SSH tunnel as systemd service

Iván Moreno
2 min readOct 17, 2019
Photo by Serge Kutuzov on Unsplash

SSH tunneling is a method of transporting arbitrary networking data over an encrypted SSH connection. It can be used to add encryption to legacy applications. It can also be used to implement VPNs (Virtual Private Networks) and access intranet services across firewalls.

SSH has 3 types of tunneling: local, remote and dynamic. Each of than can be use for different purpose.

Local port forwarding

With local port forwarding we can forward remote port to local environment:

ssh -nNT -L 8000:remotehost:80 user@remotehost

In above example we forward remotehost:80 to local environment through 8000 port, then we can access to remotehost:80 typing localhost:8000 in our local environment

Remote port forwarding

With remote port forwarding we can expose local environment to remote host

ssh -nNT -R 8080:localhost:80 user@remotehost

In above example we expose localhost:80 to remote environment through port 8080, assuming that remotehost is a server with public ip address, we can access to that service with [public_ip]:8080, but we need to enable some options in /etc/ssh/sshd_config

AllowTcpForwarding yes 
GatewayPorts yes

Dynamic port forwarding

With dynamic port forwarding you can implement a system proxy

ssh -nNT -D 9090 user@remotehost

In above example we implement a system proxy via ssh tunnel, it can be configured in the system as socket proxy through 9090 port

SSH tunnel with systemd

SSH tunnels is an incredible feature, but what happens if we want to implement at startup of the system, we can do that with systemd service

First we need to setup a ssh keys on the remote server and create a template for each type of tunnel local, remote and dynamic and save in:


And environment variables, save in


Example of dynamic, local and remote tunnel respectively

And finally for activate this services, type the next command for dynamic, local and remote tunnel respectively

systemctl enable --now dynamic-tunnel@sysproxysystemctl enable --now local-tunnel@databasesystemctl enable --now remote-tunnel@testserver