Multi-hops are methods to reach hosts behind firewalls or to reach the outside world from inside a bastion host. With multi-hops, TRAMP can negotiate these hops with the appropriate user/host authentication at each hop. All methods until now have been the single hop kind, where the start and end points of the connection did not have intermediate check points.
tramp-default-proxies-alist specifies proxy hosts to pass
through. This user option is list of triples consisting of
(host user proxy).
The first match is the proxy host through which passes the file name
and the target host matching user@host. host and
user are regular expressions or
nil, interpreted as a
regular expression which always matches.
proxy is a literal TRAMP file name whose local name part is ignored, and the method and user name parts are optional.
The method must be an inline method (see Inline methods). If
nil, no additional hop is required reaching
For example, to pass through the host ‘bastion.your.domain’ as user ‘bird’ to reach remote hosts outside the local domain:
(add-to-list 'tramp-default-proxies-alist '("\\." nil "/ssh:firstname.lastname@example.org:")) (add-to-list 'tramp-default-proxies-alist '("\\.your\\.domain\\'" nil nil))
add-to-list adds elements at the beginning of a
list. Therefore, most relevant rules must come last in the list.
Proxy hosts can be cascaded in the alist. If there is another host called ‘jump.your.domain’, which is the only host allowed to connect to ‘bastion.your.domain’, then:
(add-to-list 'tramp-default-proxies-alist '("\\`bastion\\.your\\.domain\\'" "\\`bird\\'" "/ssh:jump.your.domain:"))
proxy can take patterns
%u for host or
user respectively. Ports or domains, if they are part of
a hop file name, are not expanded by those patterns.
To login as ‘root’ on remote hosts in the domain ‘your.domain’, but login as ‘root’ is disabled for non-local access, then use this alist entry:
(add-to-list 'tramp-default-proxies-alist '("\\.your\\.domain\\'" "\\`root\\'" "/ssh:%h:"))
Opening /sudo:randomhost.your.domain: first connects
to ‘randomhost.your.domain’ via
ssh under your account
name, and then performs
sudo -u root on that host.
It is key for the sudo method in the above example to be applied on the host after reaching it and not on the local host. TRAMP checks therefore, that the host name for such hops matches the host name of the previous hop.
host, user and proxy can also take Lisp forms. These
forms when evaluated must return either a string or
To generalize (from the previous example): For all hosts, except my
local one, first connect via
ssh, and then apply
sudo -u root:
(add-to-list 'tramp-default-proxies-alist '(nil "\\`root\\'" "/ssh:%h:")) (add-to-list 'tramp-default-proxies-alist '((regexp-quote (system-name)) nil nil))
Passing through hops involves dealing with restricted shells, such as
rbash. If TRAMP is made aware, then it would use
them for proxies only.
An alist of regular expressions of hosts running restricted shells,
rbash. TRAMP will then use them only as
To specify the bastion host from the example above as running a restricted shell:
(add-to-list 'tramp-restricted-shell-hosts-alist "\\`bastion\\.your\\.domain\\'")