Instantly share code, notes, and snippets.

What would you like to do?
Setup a secure (SSH) tunnel as a systemd service. #systemd #ssh #ssh-tunnel #ssh-forward


Create a template service file at /etc/systemd/system/secure-tunnel@.service. The template parameter will correspond to the name of target host:

Description=Setup a secure tunnel to %I

ExecStart=/usr/bin/ssh -NT -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -L ${LOCAL_ADDR}:${LOCAL_PORT}:localhost:${REMOTE_PORT} ${TARGET}

# Restart every >2 seconds to avoid StartLimitInterval failure


We need a configuration file (inside /etc/default) for each target host we will be creating tunnels for. For example, let's assume we want to tunnel to a host named jupiter (probably aliased in /etc/hosts). Create the file at /etc/default/secure-tunnel@jupiter:


Note that for the above to work we need to have allready setup a password-less SSH login to target (e.g. by giving access to a non-protected private key).

Now we can start the service instance:

systemctl start secure-tunnel@jupiter.service
systemctl status secure-tunnel@jupiter.service

Or enable it, so it get's started at boot time:

systemctl enable secure-tunnel@jupiter.service

This comment has been minimized.

erikbgithub commented May 8, 2017

Thanks man, you just saved me like 4 hours of reading systemd docs!

Edit: If this blogpost is your source, maybe a reference is also polite. (not my blog, just reading what others say about the same topic)

Also, maybe the is more interesting?


This comment has been minimized.


drmalex07 commented Sep 5, 2017

Thanks @erikbgithub. No, the article you mention was not my source (just the official docs of systemd).


This comment has been minimized.

comperem commented Dec 3, 2017

Super helpful.

I think this is what worked for my restart failures:


This comment has been minimized.

derkosak commented Mar 1, 2018

+1, really useful.
As the blogpost mentioned by @erikbgithub, for flexibility you might want to allow configuration of the SSH key file and for the remote user. I added -l ${REMOTE_USER} -i ${KEY_FILE} to the command in ExecStart and the defaults file.


This comment has been minimized.

willjian commented Mar 13, 2018

Very helpful
Thanks @drmalex07 so much


This comment has been minimized.

renxida commented Mar 22, 2018

I've been using this to connect to lab computers for a while. Awesome config file. Thank you so much.

I just tried using it on a public computer but it didn't work, so I made a root-free version:

It also includes install/uninstall scripts.


This comment has been minimized.

sanludhi commented Mar 24, 2018

I was struggling... thanks for saving so much of time ... it worked perfectly fine


This comment has been minimized.

sanludhi commented Aug 10, 2018

How to forward multiple ports


This comment has been minimized.

htfy96 commented Sep 21, 2018

Maybe it's better to set it as a user service


This comment has been minimized.

dhruv commented Nov 7, 2018

Thank you for this!


This comment has been minimized.

sunnyszy commented Nov 12, 2018

I also think it's better to exec in user mode. But my machine systemctl has bug when running --user, so I add user permission in service file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment