Skip to main content

SSH tunnel

Overview

SSH (Secure Shell Protocol) enables secure login and command execution on servers.

An SSH tunnel creates a secure channel between client and server for transferring traffic. This mechanism connects to applications and services inside your internal network.

Two types of tunneling exist:

  • Local port forwarding - forwards traffic from a local port to a remote port
  • Remote port forwarding - forwards traffic from a remote port to a local port

Prerequisites

Establish the tunnel by connecting an SSH client to a server that accepts SSH connections.

Local port forwarding

Local port forwarding creates a tunnel to forward traffic from the local port to the remote port.

Syntax:

ssh -L [bind_ip:]local_port:destination_server_ip:remote_port user@server_hostname

Example - forward local port 8000 to remote port 4000:

ssh -L 8000:127.0.0.1:4000 user@remote_server_ip

Notes:

  • Anyone can connect on port 8000. Authentication depends on the destination service at port 4000.
  • Restrict listening 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 localhost, allowing only local apps to access remote port 4000.
  • 127.0.0.1 refers to the remote server context. This can be any IP address the remote server can connect to, making the remote server an intermediary.
  • Chain multiple -L flags to forward multiple local ports.

Ssh Local Forwarding

Picture credit - user erik from StackOverflow

Remote port forwarding

Remote port forwarding creates a tunnel to forward traffic from the remote port to the local port.

Syntax:

ssh -R [bind_ip:]remote_port:local_server_ip:local_port user@server_hostname

Example - forward remote port 4000 to local port 8000:

ssh -R 4000:127.0.0.1:8000 user@remote_server_ip

Notes:

  • 127.0.0.1 refers to the local server context. The connection forwards to localhost port 8000.
  • Forward to any server the local server can reach. For example, 4000:5.6.7.8:8000 forwards to port 8000 on server 5.6.7.8.
  • Chain multiple -R flags to forward multiple remote ports.

Ssh Remote Forwarding

Picture credit - user erik from StackOverflow

Persistent tunnel

Create a persistent tunnel by adding a systemd service file at /etc/systemd/system/ssh-tunnel.service.

The following example exposes a MySQL server on remote server 5.75.134.144 to the Cloudron network (172.18.0.1) on port 6612. Apps connect to 172.18.0.1:6612 to reach 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

Enable and start the service:

systemctl daemon-reload
systemctl enable ssh-tunnel.service
systemctl start ssh-tunnel.service

Cloudron network

IP

All apps and services run in an internal network (not reachable from outside the server). The network address is 172.18.0.0/16.

To expose a port to apps, use the internal Docker bridge IP 172.18.0.1. Apps connect to this internal IP address.

Databases

To set up connections, see the internal IP of the databases.