ssh tunnel via userspace systemd service


[image above is a screenshot of 0pointer.de – in place of a systemd logo]

This is short how-to on setting up a systemd service that is run from a user account.

In the /etc/systemd/system directory:

a) create a service file that implements the service. In my case, I wanted to set up a service that would be started at boot and run under my userid. This service is to set up a ssh tunnel to a system that is on another, external network.

$ cat /etc/systemd/system/ssh-tunnel.service
[Unit]
Description=ssh tunnel
After=network.target

[Service]
User=harish
Group=harish
Type=simple
WorkingDirectory=/home/harish
ExecStart=/home/harish/sshpipe.sh
Restart=on-failure

[Install]
WantedBy=multi-user.target

$

b) This is a service that is to be started after the network.target is reached – obviously, no network, nothing happens. Then the section [Service] has details as to who’s UID it is to be invoked. Included are the User, Group, and WorkingDirectory details. The file that is to be run when this service is started is called sshpipe.sh and that is also indicated.

# ps -ef|grep ssh
root       898   812  0 Jul17 ?        00:00:00 /usr/libexec/sssd/sssd_ssh --uid 0 --gid 0 --logger=files
root      1333     1  0 Jul17 ?        00:00:00 /usr/sbin/sshd -D
harish   30062     1  0 16:30 ?        00:00:00 /bin/sh /home/harish/sshpipe.sh
harish   30063 30062  0 16:30 ?        00:00:00 /usr/bin/ssh -N -R 2048:localhost:22 harish@10.10.10.10

c) As can be seen above, the sshpipe.sh is invoked under my UID and in this case, because I am have set it up as passwordless ssh connection (which you have set up earlier), the command will work seamlessly.

d) The file sshpipe.sh is as follows:

$ cat sshpipe.sh 
#!/bin/sh
/usr/bin/ssh -N -R 2048:localhost:22 harish@10.10.10.10
$

Essentially, the command says that is run (in my case a Red Hat Enterprise Linux 7.5 system running in an Intel NUC RYBDWi35) is connecting to port 2048 on the remote host 10.10.10.10 under my UID and linking back up port 22 on this NUC. So, when I log into 10.10.10.10, I can run:

$ ssh -p 2048 localhost

and I am back into the NUC.

e) So, once the systemd service file, in this case, ssh-tunnel.service is created, you will have to enable it and start it.

# systemctl enable ssh-tunnel.service
Created symlink from /etc/systemd/system/multi-user.target.wants/ssh-tunnel.service to /etc/systemd/system/ssh-tunnel.service.
# systemctl start ssh-tunnel.service
# systemctl status ssh-tunnel.service -l
● ssh-tunnel.service - ssh tunnel back
   Loaded: loaded (/etc/systemd/system/ssh-tunnel.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2018-07-19 19:13:50 +08; 9s ago
 Main PID: 421 (sshpipe.sh)
    Tasks: 2
   CGroup: /system.slice/ssh-tunnel.service
           ├─421 /bin/sh /home/harish/sshpipe.sh
           └─436 /usr/bin/ssh -N -R 2048:localhost:22 harish@10.10.10.10

Jul 19 19:13:50 r7 systemd[1]: Started ssh tunnel.
Jul 19 19:13:50 r7 systemd[1]: Starting ssh tunnel...

That’s about it.

I really do like systemd for the elegance provided.

[Update based on comments on g+: https://plus.google.com/u/0/+HarishPillay/posts/527ieimh6Tv%5D

In this instance, since the shell script has exactly one line, it can be placed in the unit file where it refers to the script. The updated file is as follows:

# cat ssh-tunnel.service 
[Unit]
Description=ssh tunnel
After=network.target

[Service]
User=harish
Group=harish
Type=simple
WorkingDirectory=/home/harish
ExecStart=/usr/bin/ssh -N -R 2048:localhost:22 harish@10.10.10.10
Restart=on-failure

[Install]
WantedBy=multi-user.target

[root@r7 system]#

The reason I had the script was because it was something I have been using for a long time – predates systemd and since I wanted to make sure that I could work this tunnel with systemd, I just kept the script.

Thanks to +Christoph Wickert!

Advertisements

5 Comments

  1. This may be a dumb question, Harish, but is there an advantage to having the systemd unit be a system unit (in /etc/systemd/system), as opposed to a user unit (in ~/.config/systemd/user)?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.