SSH tunnels are the Swiss Army knife of network connectivity. Need to access a device behind NAT? Reverse tunnel. Want to secure traffic over an untrusted network? Local forward. Managing remote routers from a central jump host? Multiple tunnels, multiple ports.

The problem with SSH tunnels is that they die. Network blips, ISP maintenance, DHCP lease renewals -- any interruption kills the connection and the tunnel goes down. Manually SSH-ing back into a remote router to re-establish tunnels doesn't scale past a handful of devices.

Autossh solves this. It wraps SSH connections in a monitoring loop -- if the tunnel drops, autossh restarts it automatically. With new UCI configuration support on OpenWrt, setting up persistent tunnels is now a configuration task, not a monitoring chore.

How Autossh Works Link to heading

Autossh starts an SSH connection and monitors it through a pair of echo ports. Periodically, it sends test data through the tunnel and verifies the response. If the connection fails, autossh kills the SSH process and spawns a new one. From the perspective of whatever is using the tunnel, the connection just comes back.

Autossh is not a VPN -- it doesn't encrypt traffic at the network layer. It tunnels specific ports over SSH, which means:

  • Only the ports you configure are forwarded
  • The encryption is standard SSH (the same as your terminal session)
  • No kernel modules or routing table changes needed
  • Works through NAT and firewalls without configuration changes

UCI Configuration Link to heading

Instead of writing autossh command lines with long flags, UCI gives you structured configuration sections. Each section represents one persistent tunnel:

Local port forward -- forward a port from the remote server to your local machine:

uci set autossh.local_forward=autossh
uci set autossh.local_forward.ssh_host='server.example.com'
uci set autossh.local_forward.ssh_port='22'
uci set autossh.local_forward.ssh_user='admin'
uci set autossh.local_forward.ssh_identity='/root/.ssh/id_rsa'
uci set autossh.local_forward.local_forward='8080:localhost:80'
uci set autossh.local_forward.monitor_port='20000'

uci commit autossh
/etc/init.d/autossh restart

This makes the remote server's port 80 available at localhost:8080 on the OpenWrt router. Useful for accessing internal web services through a jump host.

Remote port forward (reverse tunnel) -- expose a local port through a remote server:

uci set autossh.remote_forward=autossh
uci set autossh.remote_forward.ssh_host='jump.example.com'
uci set autossh.remote_forward.ssh_port='22'
uci set autossh.remote_forward.ssh_user='tunnel'
uci set autossh.remote_forward.ssh_identity='/root/.ssh/id_rsa'
uci set autossh.remote_forward.remote_forward='2222:localhost:22'
uci set autossh.remote_forward.monitor_port='20001'

uci commit autossh
/etc/init.d/autossh restart

Now you can SSH into the router behind NAT by connecting to jump.example.com on port 2222. The remote server forwards that connection back through the tunnel to the router's SSH port.

Dynamic SOCKS proxy -- turn the remote server into a SOCKS proxy:

uci set autossh.socks_proxy=autossh
uci set autossh.socks_proxy.ssh_host='server.example.com'
uci set autossh.socks_proxy.dynamic_forward='1080'
uci set autossh.socks_proxy.monitor_port='20002'

Configure your browser or application to use localhost:1080 as a SOCKS proxy, and all traffic routes through the remote server -- encrypted over SSH.

Multiple Tunnels, One Router Link to heading

A single OpenWrt device can maintain multiple autossh tunnels simultaneously. Configure each as a separate section:

# Tunnel 1: Access internal web server
uci set autossh.web=autossh
uci set autossh.web.ssh_host='office.example.com'
uci set autossh.web.local_forward='8080:192.168.1.100:80'
uci set autossh.web.monitor_port='20000'

# Tunnel 2: Remote SSH access to this router  
uci set autossh.ssh=autossh
uci set autossh.ssh.ssh_host='jump.example.com'
uci set autossh.ssh.remote_forward='22001:localhost:22'
uci set autossh.ssh.monitor_port='20001'

# Tunnel 3: SOCKS proxy for secure browsing
uci set autossh.proxy=autossh
uci set autossh.proxy.ssh_host='server.example.com'
uci set autossh.proxy.dynamic_forward='1080'
uci set autossh.proxy.monitor_port='20002'

uci commit autossh
/etc/init.d/autossh restart

Each tunnel gets its own monitor port and operates independently. If the web tunnel dies, the SSH access tunnel keeps running unaffected.

Procd Integration Link to heading

Under the hood, each UCI section spawns a separate autossh instance managed by procd. This means:

  • Independent lifecycle -- one tunnel failing doesn't take down others
  • Automatic restart -- procd restarts crashed instances without manual intervention
  • Startup ordering -- tunnels start after the network is up, after DNS is available
  • Hotplug awareness -- tunnels restart when WAN interfaces change IP addresses

For remote routers that might lose connectivity during ISP maintenance, procd ensures your tunnels come back as soon as the network recovers -- no cron job watching for dead processes, no manual reconnect scripts.

SSH Key Management Link to heading

Autossh needs passwordless SSH access to function. Generate a dedicated key pair:

mkdir -p /root/.ssh
ssh-keygen -t ed25519 -f /root/.ssh/id_rsa_autossh -N ''

Copy the public key to the remote server:

cat /root/.ssh/id_rsa_autossh.pub | ssh admin@server.example.com \
  'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'

Test the connection manually before enabling autossh:

ssh -i /root/.ssh/id_rsa_autossh admin@server.example.com 'echo OK'

Once the key works, enable the UCI section and autossh handles the rest.

Real-World Use Cases Link to heading

Managing remote sites -- Install OpenWrt routers at customer locations behind NAT. Each router establishes a reverse SSH tunnel to your central jump host. You access any router by connecting to a different port on the jump host. When the customer's ISP resets, the tunnel comes back automatically.

IoT device access -- Deploy sensors and controllers on cellular connections with carrier-grade NAT. Reverse tunnels give you SSH access to debug, update firmware, or pull logs without needing a public IP.

Secure browsing from untrusted networks -- Set up a SOCKS proxy tunnel through your home or office connection. When you're on hotel WiFi or public hotspots, your browser traffic routes through the encrypted tunnel.

Database replication over SSH -- Forward database ports through autossh tunnels for encrypted replication between sites. More lightweight than a full IPSec VPN and easier to configure.

When to Use Autossh vs IPSec Link to heading

Autossh and IPSec solve different problems:

AutosshIPSec
SetupSSH key + UCI configCertificates or PSK + UCI config
ScopeSpecific portsEntire subnets
OverheadMinimal (userspace SSH)Kernel-level encryption
NAT traversalWorks through any NATMay need NAT-T configuration
Best forPort forwarding, remote accessSite-to-site, road warrior VPNs

For accessing a single service through a jump host, autossh is simpler. For connecting entire office networks, IPSec is the right tool. On OpenWrt, you can run both -- they share the same UCI configuration model.


Originally published July 4, 2022 on jaymspatel.blogspot.com