SSH Tunneling
SSH tunneling can serve two purposes. One is a point-to-point secure tunnel between two machines (e.g., for Syncthing purposes), and another is to make use of a port you have available when you don’t control the firewall. Here we’ll assume 22/TCP is open from hosta
to hostb
and we want to Syncthing directories between these two hosts. There is no need for ports 22000/TCP or 22001/TCP to be open between the machines for this to work. Port 21027/UDP isn’t needed because there is no discovery, we’ll explicitly tell each member where to find the other.
SSH server config is not in scope, but we’ll also assume the server, hostb
, is configured to allow SSH connections as user syncguy
with RSA key somekey.pem
, and port forwarding is allowed. Meanwhile, hosta
is the SSH client. For Syncthing they are symmetrical peers.
Create the SSH Tunnel
First open a tunnel from hosta
to hostb
by running the SSH client on hosta
, such that localhost:22001/TCP on each machine redirects to localhost:22000/TCP on the other (for syncthing to use):
#/bin/bash
ssh -i ~/.keys/somekey.pem \
-L 127.0.0.1:22001:127.0.0.1:22000 \
-R 127.0.0.1:22001:127.0.0.1:22000 \
syncguy@hostb
127.0.0.1 is explicitly used throughout the example so the tunnels and Syncthing do NOT listen on externally exposed interfaces, for better security.
Listen on localhost
Now in Syncthing on both sides of the tunnel (hosta
and hostb
) in Settings | Connections, you can disable/uncheck all options: Enable NAT Traversal, Local Discovery, Global Discovery, and Enable Relaying. Also configure Syncthing to listen only on localhost by setting Sync Protocol Listen Addresses to:
tcp://127.0.0.1:22000
Provide Address for Remote Device
Next add the remote device and use Edit | Advanced to assign the Addresses of:
tcp://127.0.0.1:22001
Port 22001/TCP is the SSH tunnel that will redirect to localhost port 22000/TCP on the other machine. This same configuration is done on both hosta
and hostb
, and then they can find each other through the tunnel.
Troubleshooting
To ensure all is working, run netstat, on both hosta
and hostb
, with elevated privilege to confirm ssh and syncthing are listening, and that connections are established between ssh and syncthing on port 22001:
[syncguy@hosta ~]$ sudo netstat -tupna | grep 2200
A typical correct result looks like this:
tcp 0 0 127.0.0.1:22000 0.0.0.0:* LISTEN 16035/bin/syncthing
tcp 0 0 127.0.0.1:22001 0.0.0.0:* LISTEN 16112/ssh
tcp 0 0 127.0.0.1:22001 127.0.0.1:45042 ESTABLISHED 16112/ssh
tcp 0 0 127.0.0.1:45042 127.0.0.1:22001 ESTABLISHED 16035/bin/syncthing
Common mistakes when SSH tunneling include misconfiguration of the SSH client and/or server, wrong permissions on keys, forgetting about selinux policy, and being blocked by firewall, i.e. even 22/TCP is blocked. If you want the tunnel to establish after reboot and re-establish upon failure, consider autossh.