Skip to content

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 IP 5.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.