Using trap to automatically close a SSH tunnel
In my article on SSH port forwarding, we used SSH local forwarding to connect to a port on a local machine to a port on a remote machine to access services that would normally be restricted to localhost. But what if we wanted to automatically close the SSH process when we are done using a service like VNC? If we use ssh -N -L 5900:localhost:5900 remote; vncviewer localhost
, the SSH process blocks us from running the vncviewer
command. If we use ssh -N -L 5900:localhost:5900 remote &; vncviewer localhost
, our VNC viewer will run, but if we close it, the SSH process will still be in the background. One way to automatically close the SSH process when the VNC viewer exits is by using the trap
shell builtin command. Place the following into a script:
#!/usr/bin/env bash
trap 'kill $(jobs -p)' EXIT
ssh -N -L 5900:localhost:5900 remote &
# Tune the value based on how fast the ssh connection gets establishes
sleep 1.5
vncviewer localhost
First, we run the SSH local forwarding command as a background process. However, it may take some time for the connection to be established (e.g. if you use a slow key type like rsa4096), so we add a sleep command before running the vncviewer
command. When we exit the vncviewer
comamnd, and hence exit the script, the trap
command will run kill $(jobs -p)
, which will send a SIGTERM
signal to the SSH process and stop it.
Extra
If you want to log to the systemd journal when you open and close the SSH local forwarding, you could try using systemd-cat
like the following:
trap 'systemd-cat -t name-of-script echo "Ending SSH port forward"; kill $(jobs -p)' EXIT
systemd-cat -t name-of-script echo "Starting SSH port forward"
ssh -N -L 5900:localhost:5900 remote &
sleep 1.5
vncviewer localhost
Or you can try using notify-send
to send notifications to your desktop.