to connect to a device behind a private unreachable router you can use remote ssh port forwarding or remote ssh tunneling (notice that remote ssh tunneling is different from local ssh tunneling).
example:
ssh -i path/to/key -R '*:5000:*:22' user@remote -N -g
so say you have 3 machines, "local1"
, "local2"
and "remote1"
. when this command is run from local2
, it binds to the port 5000 on the machine remote1
and forwards the traffic to that port to port 22 of local2
. this allows you to ssh into local2
through the remote machine from local1
, now if you take local1
into any other network, not necessarily the network local2
is on, you can still connect to local2
from local1
through remote1
.
basically, this can be used as an alternative to other port forwarding methods when you want to gain access to a machine behind a private network like a home or office network.
a connection to the tunnel can be opened using the command
ssh -i path/to/key localuser@remote1 -p 5000
note that localuser
would be the user of local2
(not the remote machine) that you want ssh to use.
connection refused
by default tunnel endpoints only listen on 127.0.0.1, so they can't be accessed from other machines. to change this you may need to add this to /etc/ssh/sshd_config
on the server:
GatewayPorts clientspecified
this is also the reason we use the address *:5000:*:22
, the star is used to listen on all interfaces, like 0.0.0.0
.
using ipv6
if you're using ipv6 you need to make sure its enabled on all machines. vim /etc/sysctl.conf
and make sure you have the following:
net.ipv6.conf.default.disable_ipv6 = 0 net.ipv6.conf.all.disable_ipv6 = 0
the ipv6 equivalent for localhost
is ::1
. so, for example, the reverse tunnel ssh command becomes:
ssh -i yourkey -R '*:5000:*:22' -6 user@remote1:etc:etc::1 -N -g
systemd service
an example systemd service that i use to automatically open an ssh tunnel for a linux server:
[Unit] After=network.target network-online.target Description=ssh tunnel Wants=network-online.target [Service] ExecStart=ssh -i my/key/path -R '*:5000:*:22' -6 root@my:server:ipv6::1 -NTg -o ServerAliveInterval=60 Restart=on-failure RestartSec=5s User=mahmooz [Install] WantedBy=multi-user.target