How do I SSH to machine A via B in one command?
Solution 1
Using ProxyCommand
in your SSH config.
Create an SSH configuration file in your home directory (unless you want to make this system-wide), ~/.ssh/config
:
Host unibroker # Machine B definition (the broker)
Hostname 12.34.45.56 # Change this IP address to the address of the broker
User myusername # Change this default user accordingly
# (`user@unibroker` can overwrite it)
Host internalmachine # Machine A definition (the target host)
ProxyCommand ssh -q unibroker nc hostname.or.IP.address.internal.machine 22
Now you can reach Machine A directly using
ssh user@internalmachine
Also note that now you have a single SSH host target name for it, you can use this in other applications as well. E.g.:
-
SCP to copy files.
scp somefile user@internalmachine:~/
-
In your GUI applications:
use
sftp://user@internalmachine/
as the location to browse on the machine.KDE-based (Dolphin): use
fish://user@internalmachine/
Notes
Change hostname.or.IP.address.internal.machine
and the port (22
) to the machine you like to reach as if you would from the unibroker
machine.
Depending on netcat versions on the unibroker host, the -q0
option must be omitted. Regarding authentication; you're basically setting up two SSH connections from your workstation. This means both the unibroker host and the internalmachine host are verified/authenticated against one after another (for both keypair/password and host key verification).
Explanation
This approach of the use of ProxyCommand
and 'netcat' is just one way to do it. I like this, because my SSH client talks directly to the target machine so that I can verify the host key from my client and I can use my public key authentication without using another key on the broker.
Each Host
defines the start of a new host section. Hostname
is the target hostname or IP address of that host. User
is what you would provide as the user part in ssh user@hostname
.
ProxyCommand
will be used as the pipe to the target machine. By using SSH to the first machine and directly setting up a simple 'netcat' (nc
) to the target from there, this is basically just a plaintext forward to the internal machine from the broker between those. The -q
options are to silence any output (just a personal preference).
Make sure you have netcat installed on the broker (usually available by default on Ubuntu) - either netcat-openbsd or netcat-traditional .
Note that you're still using SSH with encryption twice here. While the netcat channel is plaintext, your SSH client on your PC will set up another encrypted channel with the final target machine.
Solution 2
You could use the -J
command line option:
ssh -J user@machineB user@machineA
From man ssh
:
-J [user@]host[:port]
Connect to the target host by first making a ssh connection to
the jump host and then establishing a TCP forwarding to the
ultimate destination from there. Multiple jump hops may be
specified separated by comma characters. This is a shortcut to
specify a ProxyJump configuration directive.
It was introduced in OpenSSH version 7.3 (released in August 2016). It is available in Ubuntu 16.10 and later.
Solution 3
Hop in one go
An obvious alternative to the ProxyCommand approach I provided in my other answer would be 'hopping' directly to the target machine:
ssh -t user@machineB ssh user@machineA
Note the -t
on the first ssh
command. Without it, it will fail:
Pseudo-terminal will not be allocated because stdin is not a terminal.
ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory
Permission denied, please try again.
[...]
It will force a real TTY to be allocated
Downside of this is that now all configuration, verification and authentication takes place at Machine B, which I really don't like in my situation for security reasons. I like my keypair on my own PC and authenticate and verify the final target machine from my own PC. Additionally, you can only use the interactive shell for SSH, so this won't deal with other tools like SCP or using your GUI file manager.
For all the aforementioned reasons I strongly recommend the ProxyCommand approach, but for a quick connect this works fine.
Solution 4
Try using
Host <visible hostname alias>
Controlmaster auto
User <user>
hostname <visible hostname>
port <port>
IdentityFile ~/.ssh/<id file>
Host <private LAN hostname alias>
ProxyCommand ssh -q -W <private LAN hostname>:<private LAN port> <visible hostname alias>
in your ~/.ssh/config and do it all in one shot with keys only residing on your computer.
Solution 5
machineA
is the final target.
machineB
is the broker.
We want to do home -- machineB -- machineA
easily via ssh.
In OpenSSH version 7.3 (released in August 2016) or later, you can do one of the following:
.ssh/config
approach:
Add the following lines to your .ssh/config
:
Host machineB
Hostname 12.12.12.12 # IP of machineB (w.r.t. home)
User usernameB # username on machineB
Host machineA
Hostname 34.34.34.34 # IP of machineA (w.r.t. machineB)
ProxyJump usernameB@machineB # PROXY MAGIC!
User usernameA # username on machineA
Then type ssh machineA
. Also compatible with scp
.
You can augment the above config to also force specific key usage via https://unix.stackexchange.com/a/494485.
-J
flag option:
Just type ssh -J usernameB@machineB usernameA@machineA
.
Final notes
This answer combines gertvdijk and Erik Sjölund answers with the guide at https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Proxies_and_Jump_Hosts#cite_note-ProxyJump-1.
Related videos on Youtube
nikosdi
Updated on September 18, 2022Comments
-
nikosdi over 1 year
I want to access a computer, say machine A which is based in my university's network. However, this computer is only accessible via the internal network of the university, so I can not use SSH to this computer from home directly.
Here's what I do now:
Log in to a different university machine, say machine B
(This machine B is accessible via SSH from my home computer.)
Use SSH on B to connect to A.
Is there a way to do that faster? Using only one ssh command.
-
Trevor Boyd Smith about 5 yearsrelated: ssh via multiple hosts
-
demure almost 11 yearsWhy not have one answer with both the 'One Off' and Permanent solutions?
-
gertvdijk almost 11 years@demure That's how StackExchange sites work... See: What is the official etiquette on answering a question twice? says "It's better to post two different answers, than to put them into one answer.". And I don't consider this to be the same solution. Permanent/temporarily is not what makes this approach differently, in my opinion.
-
Gerry over 10 yearsI had to remove the -q0 option as it wasn't supported by the machine I was using. Other than that, it all worked. This is a FANTASTIC tip. Thank you so much. :)
-
Felipe Alvarez about 9 yearsIf you set up and configure public key authentication, then you don't need to worry about entering in your passwords. But
-t
is still required. -
Vikash Balasubramanian over 8 yearsI ran into a problem, your answer works fine for me from the terminal, but i am unable to do it using the gui sftp, it says : unhandled error message, timed out while logging in.
-
gertvdijk over 8 years@VikashB Well, it really should work. Consider creating a NEW question to handle your specific situation.
-
Vikash Balasubramanian over 8 yearsI did here is the question: askubuntu.com/questions/688567/…
-
danemacmillan almost 8 yearsThis is more clean than introducing netcat into the mix. Also, the private SSH key does not need to exist on the
B
machine, either. -
gertvdijk almost 8 yearsVery interesting approach. However, the main downsides of this are: 1) Use is limited to standard SSH usage (no SFTP/SCP support). 2) A user can't select another target host other than the single one (because hardcoded in login shell) 3) Host key validation can't be done from workstation to the final target host (since the use of the broker SSH binary). 4) Private keys for users to access the final target host are residing on the broker rather than with the user. This allows for impersonation of the user by an admin (which isn't possible normally).
-
Michael about 7 years@FelipeAlvarez You still have to worry about entering the second password if you don't trust machine B to have passwordless login to A!
-
Travis Clarke over 6 yearsTo complement the wise word of @gertvdijk, there is a great wikibook on the topic of ssh proxies and jump hosts that can serve as an invaluable reference.
-
Grief about 6 years+1 because this works even if you need to specify key file for machineA
-
Diagon over 5 yearsOther guides say to use, in addition, the -A switch, but indicate that this has security implications. Do you know what it means to forward, or not, the authentication agent connection?
-
Trevor Boyd Smith over 5 years@gertvdijk super ninja here! you have the top TWO solutions. i've never seen that before. super cool. way better than creating one mega long solution with N solutions (which is what i usually see).
-
gertvdijk about 5 years+1, this is the better version compared to my ProxyCommand answer if all your hosts are running an OpenSSH version recent enough.
-
Nikhil Sahu about 5 yearsThis is much more convenient than setting up a config which will hamper other ssh's as well.
-
Mikhail about 5 yearsOpenSSH server should be installed on both A and B machines in this case? Am I right understood?
-
Mikhail about 5 yearsOpenSSH server should be installed on both A and B machines in this case? Am I right understood?
-
gertvdijk about 5 years@Mikhail Moreover, Machine B should have both have an SSH server and client. Machine A a server.
-
Michael over 4 yearsI had to include
User
underHost <private LAN hostname alias>
for this to work. -
Amiratak88 about 4 yearsThe config file equivalent is "ProxyJump"
-
geronime over 3 yearsThanks for this fantastic tip. In case you have many hosts behind the jumphost and you have an entry like
Host *.some.domain.tld
you almost surely want to use%h
in the ProxyCommand not to have an entry for each specific host, e.g.ProxyCommand ssh -q unibroker nc %h 22
-
rambi almost 3 yearsHow do you specify key files in that case ? Do the private for machineA key need to be in machineB ? How can you specify 2 ssh keys ?
-
Erik Sjölund almost 3 years@rambi Your question Do the private for machineA key need to be in machineB? No, you just need to store the private key(s) on your local computer. If any of the private keys is located under a non-standard path you could configure their usage by editing ~/.ssh/config (Look up
IdentityFile
in man7.org/linux/man-pages/man5/ssh_config.5.html) -
Abdull about 2 yearsFor anyone having backslashes in their usernames (e.g. Linux users managed by Kerberos/GSSAPI/Active Directory, therefore Unix username being e.g.
Realm\mytargetuser
) and already being accustomed to escape the backslash on the shell prompt (ssh Realm\\[email protected]
): For some reason, the jump proxy username now requires double escaping:ssh -J Realm\\\\[email protected] Realm\\[email protected]
orssh -J 'Realm\\[email protected]' Realm\\[email protected]
.