SSH Tunnel
Overview
Secure Shell Protocol or SSH is a protocol to login to servers securely and execute commands.
SSH Tunnel is a secure tunnel created between the client and the server to transfer any kind of traffic. The mechanism allows a way to connect to applications and services inside your internal network.
There are two types of tunneling:
- Local port forwarding
- Remote port forwarding
The distinction is the location of the port being forwarded - the local port or the remote port.
Prerequisites
It's essential to have a server which accepts SSH connections. The SSH client connects to the SSH server to establish the tunnel.
Local Port Forwarding
With local port forwarding, a tunnel is set up to forward traffic from the local port to the remote port.
The general syntax to set up this forwarding is:
ssh -L [bind_ip:]local_port:destination_server_ip:remote_port user@server_hostname
For example, to forward local port 8000 of local server to remote port 4000:
ssh -L 8000:127.0.0.1:4000 user@remote_server_ip
More explanation:
- In the above example, anyone can connect on port 8000. The authentication depends on the destination service at port 4000.
- You can restrict the listening of port 8000 by providing a specific bind address. For example,
127.0.0.1:8000:127.0.0.1:4000
makes SSH listen on port 8000 only on the localhost. This way only local apps can access the remote port 4000. 127.0.0.1
above is in the context of the remote server. This can be any IP address that the remote server can connect to. In such set ups, the remote server is just an intermediary server.- Multiple local ports can be forwarded by chaining multiple
-L
.
Picture credit - user erik from StackOverflow
Remote Port Forwarding
With remote port forwarding, a tunnel is set up to forward traffic from the remote port to the local port.
The general syntax to set up this forwarding is:
ssh -R [bind_ip:]remote_port:local_server_ip:local_port user@server_hostname
For example, to forward remote port 4000 of remote server to local port 8000:
ssh -R 4000:127.0.0.1:8000 user@remote_server_ip
More explanation:
127.0.0.1
above is in the context of the local server. Connection is forwarded to local host and port 8000.- Connection can also be forwarded to any server that the local server can connect to. For example,
4000:5.6.7.8:8000
will forward to port 8000 of server with IP5.6.7.8
. - Multiple remote ports can be forwarded by chaining multiple
-R
.
Picture credit - user erik from StackOverflow
Persistent tunnel
To create a persistent tunnel, create a systemd service (on Cloudron) with a file named /etc/systemd/system/ssh-tunnel.service
.
In the example below, a MySQL server running on remote server 5.75.134.144
is exposed to the Cloudron network (172.18.0.1) on port 6612. Apps can connect to 172.18.0.1:6612 to connect to the remote MySQL server.
[Unit]
Description=Make database available to Cloudron apps
After=network.target
[Service]
Restart=on-failure
RestartSec=5
ExecStart=/usr/bin/ssh -NTC -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -L 172.18.0.1:6612:127.0.0.1:3306 root@5.75.134.144
[Install]
WantedBy=multi-user.target
To enable and restart the server:
systemctl daemon-reload
systemctl enable ssh-tunnel.service
systemctl start ssh-tunnel.service
Cloudron Network
IP
Cloudron runs all apps and services in an internal network (not reachable from outside the server). This network address is hardcoded to 172.18.0.0/16
.
To expose a port to apps, use the internal docker bridge IP 172.18.0.1
. Apps can connect to this internal IP address.
Databases
To set up connections, see the internal IP of the databases.