We have two machines: master and agent. The goal is for agent to ssh into master, allocating a local port on master which forwards to a port on agent.
In this example, we'll use ssh - but that's arbitrary. The "master" is lightning
and the "agent" is fabulinus
.
First: open the ssh connection:
sauer@fabulinus:~$ ssh -Nf -R 10022:localhost:22 lightning
This will fork ssh into the background (-f
) and not run a program (-N
). Thus, it's just forwarding the port and nothing else.
sauer@fabulinus:~$ ps -C ssh -o pid,cmd
PID CMD
3808164 ssh -Nf -R 10022:localhost:22 lightning
Now, on lightning, verify that the connection is listening:
sauer@lightning:~$ sudo lsof -P -c ssh | grep -i 10022
sshd 7554 sauer 11u IPv6 1534266 0t0 TCP localhost:10022 (LISTEN)
sshd 7554 sauer 12u IPv4 1534267 0t0 TCP localhost:10022 (LISTEN)
There are two open ports - one ipv4 and one ipv6, both on the loopback interface. I also put an entry at the end of /etc/hosts to allow connectiions by name:
sauer@lightning:~$ grep fake /etc/hosts
127.0.0.1 fake_fabulinus
I put the entry at the end, because reverse-resolution works top-don in /etc/hosts, so the exiting localhost entry in there will still reverse resolve 127.0.0.1 to localhost, as expected. But the hostname will resolve to the IP. You can have multiple hosts on a line, but just adding this to the end f not present is marginally easier to script than editing the line.
So, I should be able to ssh now.
sauer@lightning:~$ ssh fake_fabulinus -p 10022 hostname
The authenticity of host '[fake_fabulinus]:10022 ([127.0.0.1]:10022)' can't be established.
ECDSA key fingerprint is SHA256:I1Z9Y2biEz7EkEHztIU2ioJiZ5y8xsK/IeCaizl7CMk.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[fake_fabulinus]:10022' (ECDSA) to the list of known hosts.
sauer@fake_fabulinus's password:
fabulinus
This could be repeated with multiple ports for multiple hosts. The ssh port forward command can also have multiple -R options added to forward multiple ports.