SSH Remote Network Access
In a recent technical meeting, someone asked about some SSH ProxyJump documentation I’d posted. I promised to follow up with a full configuration for using ProxyJump with a remote network, so here goes nothing.
Let’s assume a simple setup. Here are three views of it.
- Logical: Internet <-> Bastion Host <-> Private Network
- DNS: Internet <-> login.my.com <-> *.my.com
- IPv4: 0.0.0.0/0 <-> 18.104.22.168 + 10.10.10.1 <-> 10.10.10.0/24
The bastion host can also be called a “jump host.” It has two interfaces: public (22.214.171.124) and private (10.10.10.1).
The simple way to access a *.my.com host (e.g., dev.my.com) is with a shell one-liner:
# plain ssh ssh -J login.my.com dev.my.com # scp scp -o 'ProxyJump login.my.com' myfile.txt dev.my.com:/my/dir
It’s often the case, however, that you login to several my.com hosts and that you further have some internal-only web applications you want to access there. (What follows will work more easily if you have SSH keys working with ssh-agent, but it’s not necessary.)
First, we need to setup your
~/.ssh/config file. We’re going to assign an alias to your bastion host; the purpose of the alias will only become clear later. The Host stanza for your bastion host will also enable three optional SSH features: compression, agent forwarding, and SOCKS5 proxying. The SOCKS5 proxy will allow you to reach your internal-only web apps.
# part of ~/.ssh/config Host mybastion Hostname login.my.com Compression yes ControlPath ~/.ssh/cm-%r@%h:%p ControlMaster auto ControlPersist 9H ForwardAgent yes DynamicForward 127.0.0.1:1080
The various Control directives allow you to run multiple SSH sessions over a single network connection. The ssh_config(5) man page has more information.
It’s important to note that you should use the alias (“mybastion”) rather than the fully qualified domain name (FQDN) when setting up your master connection. We’ll get to the ssh invocation in a bit.
The next customization for your ssh config file ensures any SSH session destined for *.my.com uses your control session.
# part of ~/.ssh/config Host *.my.com CheckHostIP no ProxyCommand ssh mybastion -W %h:%p
The important thing to note here is that you’ll need to use fully qualified domain names (e.g., dev.my.com) rather than short versions (dev) if you want to use the multiplex connection.
Now setup the session. We avoid the chicken-and-egg problem by using the alias for your bastion host rather than its FQDN.
ssh -f -N mybastion 2>/dev/null
The “-f -N” options will invoke ssh without a remote command and put it into the background. Even though it’s backgrounded, ssh will allow you to check its status:
ssh -O check mybastion
It will return something like “Master running” if successful.
Now you can do
ssh dev.my.com in a terminal window and you will be able to directly into your dev machine. (I say “directly,” but if you run “who” while logged it, your session will show up as coming from the bastion host.) As a side benefit, you will also be able to use
scp directly to my.com hosts. Remember, you need to use the FQDN. If that’s a hassle for you, try a shell alias to simplify things.
Finally, if you want to be able to access your internal-only web apps using the SOCKS5 proxy, you’ll probably want to dedicate a browser to that sort of work. I use Firefox for that:
- Launch Firefox
- Enter “about:config” into the URL box.
- Ignore the “this might void your warranty” warning.
- Change some settings:
network.proxy.socks: localhost network.proxy.socks_port: 1080 network.proxy.socks_remote_dns: true network.proxy.type: 1
The port number, 1080 in my example, is arbitrary, but it must match the only you specified in your DynamicForward directive (above).
I’ve found it necessary to start my proxied browser within a couple minutes of setting up the control/multiplex session. Something times out otherwise, but I haven’t really sought to understand that. At that point, Firefox ought to be able to browser your internal web sites.
It’s worth noting that, with those configuration changes in place, Firefox will fail to work properly if your ssh session isn’t running. Personally, I only use Firefox for proxied communications, but if you want more flexibility you can setup a Firefox profile just for proxied sessions.
Finally, when you’re ready to close your multiplex session, just ask ssh nicely:
ssh -O exit mybastion