Instantly share code, notes, and snippets.

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

README

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

[Unit]
Description=Setup a secure tunnel to %I
After=network.target

[Service]
Environment="LOCAL_ADDR=localhost"
EnvironmentFile=/etc/default/secure-tunnel@%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
RestartSec=5
Restart=always

[Install]
WantedBy=multi-user.target

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:

TARGET=jupiter
LOCAL_ADDR=0.0.0.0
LOCAL_PORT=20022
REMOTE_PORT=22

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
@erikbgithub

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 network-online.target is more interesting?

@drmalex07

This comment has been minimized.

Owner

drmalex07 commented Sep 5, 2017

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

@comperem

This comment has been minimized.

comperem commented Dec 3, 2017

Super helpful.

I think this is what worked for my restart failures:
RestartSec=5

@derkosak

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.

@willjian

This comment has been minimized.

willjian commented Mar 13, 2018

Very helpful
Thanks @drmalex07 so much

@renxida

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:

https://github.com/renxida/labtunnel

It also includes install/uninstall scripts.

@sanludhi

This comment has been minimized.

sanludhi commented Mar 24, 2018

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

@sanludhi

This comment has been minimized.

sanludhi commented Aug 10, 2018

How to forward multiple ports

@htfy96

This comment has been minimized.

htfy96 commented Sep 21, 2018

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

@dhruv

This comment has been minimized.

dhruv commented Nov 7, 2018

Thank you for this!

@sunnyszy

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