-
-
Save polyrand/6f9987a7cfb09244a8e18f61b814c2d7 to your computer and use it in GitHub Desktop.
Revisions
-
olbat revised this gist
Sep 15, 2017 . 1 changed file with 99 additions and 18 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,11 +1,24 @@ # Create SSH tunnels using systemd units ## Table of contents * [Overview](#overview) * [Setup the SSH agent systemd unit](#setup-the-ssh-agent-systemd-unit) * [Setup the SSH-tunnel systemd unit](#setup-the-ssh-tunnel-systemd-unit) * [Create tunnels using systemd services](#create-tunnels-using-systemd-services) * [Examples](#examples) * [Create a tunnel to a web server on a machine that's only accessible by SSH](#create-a-tunnel-to-a-web-server-on-a-machine-thats-only-accessible-by-ssh) * [Create a tunnel to a MySQL service only accessible through an SSH bastion (directly)](#create-a-tunnel-to-a-mysql-service-only-accessible-through-an-ssh-bastion-directly) * [Create a tunnel to a MySQL service only accessible through an SSH bastion (using SSH)](#create-a-tunnel-to-a-mysql-service-only-accessible-through-an-ssh-bastion-using-ssh) * [Further reading](#further-reading) ## Overview This systemd service scripts will allow you to create SSH tunnels in background using systemd in user mode and a configuration file. ## Setup the SSH agent systemd unit To be able to run SSH tunnels in background while using a password protected SSH key to connect to the targeted host, we'll first have to setup an _ssh-agent_ (see [ssh-agent(1)](https://linux.die.net/man/1/ssh-agent)). @@ -57,11 +70,11 @@ using ssh-add (see [ssh-add(1)](https://linux.die.net/man/1/ssh-add)). ```bash ssh-add ``` _Note:_ __it has to be done at every boot in order for the tunnels to work !__ ## Setup the SSH-tunnel systemd unit As for the [SSH authentication agent](#setup-the-ssh-agent-systemd-unit) service, we'll run our SSH tunnels ([ssh(1)](https://linux.die.net/man/1/ssh)) using a _systemd service unit_ but this unit will be instanciable (see [systemd.unit(5)](https://www.freedesktop.org/software/systemd/man/systemd.unit.html), [Lennart Poettering's blog](http://0pointer.de/blog/projects/instances.html), [Arch Linux wiki page](https://wiki.archlinux.org/index.php/Systemd#Using_units), [Fedoramagazine article](https://fedoramagazine.org/systemd-template-unit-files/)). ```bash # (create the systemd config directory if it does not exists) @@ -92,7 +105,8 @@ WantedBy=multi-user.target EOF ``` ## Create tunnels using systemd services We'll now create _systemd service instances_ to run our tunnels. Our _ssh-tunnel_ service is going to look for it's configuration file into @@ -146,35 +160,102 @@ We can check the tunnel's status using: systemctl --user status -l ssh-tunnel@testtun ``` Or list the _systemd services_ of current user: ```bash systemctl --user list-units --type=service ``` ## Examples ### Create a tunnel to a web server on a machine that's only accessible by SSH Let's create a configuration file to access to the web server (_80_ port) of the _www.privatecloud.domain.tld_ machine and make the tunnel accessible to other machines over the network: ```bash cat <<'EOF' > ~/.ssh/tunnels/privatecloud-www TARGET=user@www.privatecloud.domain.tld LOCAL_ADDR=0.0.0.0 LOCAL_PORT=8080 REMOTE_PORT=80 EOF ``` Then start the tunnel and make it load at session loading: ```bash systemctl --user start ssh-tunnel@privatecloud-www systemctl --user enable ssh-tunnel@privatecloud-www ``` We can now connect to the web server using: ```bash curl http://127.0.0.1:8080/ ``` or (from another machine that's in the same network): ```bash curl http://mymachine.domain.lan:8080/ ``` ### Create a tunnel to a MySQL service only accessible through an SSH bastion (directly) Let's create a configuration file to access to the MySQL server (_3306_ port) of the _mysql.privatecloud.domain.tld_ machine that's only through the _access.privatecloud.domain.tld_ bastion: ```bash cat <<'EOF' > ~/.ssh/tunnels/privatecloud-mysql TARGET=user@access.privatecloud.domain.tld LOCAL_PORT=3306 REMOTE_PORT=3306 REMOTE_HOST=mysql.privatecloud.domain.tld EOF ``` Then start the tunnel: ```bash systemctl --user start ssh-tunnel@privatecloud-mysql ``` We can now connect to the mysql.privatecloud's MySQL service using: ```bash mysql -h 127.0.0.1 ``` ### Create a tunnel to a MySQL service only accessible through an SSH bastion (using SSH) In this example, we want to create the same tunnel than the one in the [previous example](#create-an-ssh-tunnel-to-a-mysql-service-only-accessible-through-an-ssh-bastion-directly) but this time the MySQL service is not accessible directly from the bastion (on port _3306_). Fortunately, the _mysql.privatecloud_ machine is accessible from the bastion using SSH so we can create a tunnel using an ssh jump (see [ssh(1)](https://linux.die.net/man/1/ssh), [wikibooks article](https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Proxies_and_Jump_Hosts)): ```bash cat <<'EOF' > ~/.ssh/tunnels/privatecloud-mysql TARGET=mysql.privatecloud.domain.tld LOCAL_PORT=3306 REMOTE_PORT=3306 REMOTE_HOST=127.0.0.1 SSH_OPTS="-J access.privatecloud.domain.tld:22" EOF ``` Then start the tunnel: ```bash systemctl --user start ssh-tunnel@privatecloud-mysql ``` We can now connect to the _mysql.privatecloud.domain.tld_'s MySQL service using: ```bash mysql -h 127.0.0.1 ``` ## Further reading - systemd's [unit](https://www.freedesktop.org/software/systemd/man/systemd.unit.html) and [service](https://www.freedesktop.org/software/systemd/man/systemd.service.html) and manpages - Arch Linux wiki's [Systemd](https://wiki.archlinux.org/index.php/Systemd), [Systemd/User](https://wiki.archlinux.org/index.php/Systemd/User) and [SSH_keys](https://wiki.archlinux.org/index.php/SSH_keys) pages -
olbat revised this gist
Oct 28, 2016 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -78,11 +78,11 @@ After=network.target ssh-agent.service [Service] Type=simple Environment="LOCAL_ADDR=127.0.0.1" Environment="REMOTE_HOST=127.0.0.1" EnvironmentFile=%h/.ssh/tunnels/%i ExecStart=/usr/bin/ssh -NT ${TARGET} \ -o ExitOnForwardFailure=yes -o ServerAliveInterval=60 \ -L ${LOCAL_ADDR}:${LOCAL_PORT}:${REMOTE_HOST}:${REMOTE_PORT} ${SSH_OPTS} RestartSec=10 Restart=on-success RestartForceExitStatus=255 -
olbat revised this gist
Oct 28, 2016 . 1 changed file with 6 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -14,10 +14,10 @@ The agent will be run in background using a user _systemd service unit_ (see [sy ```bash # (create the systemd config directory if it does not exists) mkdir -p ~/.config/systemd/user/ # create the ssh-agent.service unit cat <<'EOF' > ~/.config/systemd/user/ssh-agent.service [Unit] Description=SSH key agent Documentation=man:ssh-agent(1) @@ -65,10 +65,10 @@ As for the [SSH authentication agent](#setup-the-ssh-authentication-agent-system ```bash # (create the systemd config directory if it does not exists) mkdir -p ~/.config/systemd/user/ # create the ssh-tunnel@.service unit cat <<'EOF' > ~/.config/systemd/user/ssh-tunnel@.service [Unit] Description=SSH tunnel to %i Documentation=man:ssh(1) @@ -103,7 +103,7 @@ mkdir -p ~/.ssh/tunnels/ We'll then have to create a configuration file for our tunnel: ```bash cat <<'EOF' > ~/.ssh/tunnels/testtun # This parameters will be used to run: # ssh ${TARGET} ${SSH_OPTS} \ # -L ${LOCAL_ADDR}:${LOCAL_PORT}:${REMOTE_ADDR}:${REMOTE_PORT} @@ -155,7 +155,7 @@ _access.domain.tld_ bastion and make the tunnel accessible to other machines over the network: ```bash cat <<'EOF' > ~/.ssh/tunnels/machine001-mysql TARGET=user@access.domain.tld LOCAL_ADDR=0.0.0.0 LOCAL_PORT=3307 -
olbat revised this gist
Oct 28, 2016 . 1 changed file with 24 additions and 25 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ # Create SSH tunnels using systemd units ## Overview This systemd service scripts will allow you to create SSH tunnels in background @@ -10,7 +10,7 @@ To be able to run SSH tunnels in background while using a password protected SSH key to connect to the targeted host, we'll first have to setup an _ssh-agent_ (see [ssh-agent(1)](https://linux.die.net/man/1/ssh-agent)). The agent will be run in background using a user _systemd service unit_ (see [systemd.service(5)](https://www.freedesktop.org/software/systemd/man/systemd.service.html), [systemd.unit(5)](https://www.freedesktop.org/software/systemd/man/systemd.unit.html), [Arch Linux wiki page](https://wiki.archlinux.org/index.php/Systemd/User)). ```bash # (create the systemd config directory if it does not exists) @@ -38,29 +38,30 @@ EOF Once it's done we can start the authentication agent: ```bash systemctl --user start ssh-agent ``` Or even make it load at session opening: ```bash systemctl --user enable ssh-agent ``` After that, we make the `$SSH_AUTH_SOCK` env variable be loaded at our shell initialization (here [bash](https://www.gnu.org/software/bash/)): ```bash echo 'export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"' >> ~/.bashrc source ~/.bashrc ``` Finally we add our (default) private key identity to the authentication agent using ssh-add (see [ssh-add(1)](https://linux.die.net/man/1/ssh-add)). ```bash ssh-add ``` _Note:_ __it have to be done at every boot in order for the tunnels to work !__ ## Setup the SSH-tunnel systemd unit As for the [SSH authentication agent](#setup-the-ssh-authentication-agent-systemd-unit) service, we'll run our SSH tunnels ([ssh(1)](https://linux.die.net/man/1/ssh)) using a _systemd service unit_ but this unit will be instanciable (see [systemd.unit(5)](https://www.freedesktop.org/software/systemd/man/systemd.unit.html), [Lennart Poettering's blog](http://0pointer.de/blog/projects/instances.html), [Arch Linux wiki page](https://wiki.archlinux.org/index.php/Systemd#Using_units), [Fedoramagazine article](https://fedoramagazine.org/systemd-template-unit-files/)). ```bash # (create the systemd config directory if it does not exists) @@ -91,12 +92,14 @@ WantedBy=multi-user.target EOF ``` ## Create tunnels ! We'll now create _systemd service instances_ to run our tunnels. Our _ssh-tunnel_ service is going to look for it's configuration file into the `~/.ssh/tunnels/` directory so we start with creating the directory: ```bash mkdir -p ~/.ssh/tunnels/ ``` We'll then have to create a configuration file for our tunnel: ```bash @@ -125,31 +128,22 @@ REMOTE_PORT=80 EOF ``` Finally we can run our _systemd service unit_ that will create the tunnel: ```bash systemctl --user start ssh-tunnel@testtun ``` Or make it load a session loading: ```bash systemctl --user enable ssh-tunnel@testtun ``` _Note:_ make sure your SSH authentication agent has been loaded properly using `ssh-add`, the tunnel will not work without it We can check the tunnel's status using: ```bash systemctl --user status -l ssh-tunnel@testtun ``` @@ -172,11 +166,16 @@ EOF Then start the tunnel and make it load at session loading: ```bash systemctl --user start ssh-tunnel@machine001-mysql systemctl --user enable ssh-tunnel@machine001-mysql ``` We can now connect to the machine001's MySQL service using: ```bash mysql -h 127.0.0.1 -P 3307 ``` ## Further reading - systemd's [unit](https://www.freedesktop.org/software/systemd/man/systemd.unit.html) and [service](https://www.freedesktop.org/software/systemd/man/systemd.service.html) and manpages - Arch Linux wiki's [Systemd](https://wiki.archlinux.org/index.php/Systemd), [Systemd/User](https://wiki.archlinux.org/index.php/Systemd/User) and [SSH_keys](https://wiki.archlinux.org/index.php/SSH_keys) pages - DigitalOcean's [introduction to systemd units](https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files) -
olbat revised this gist
Oct 28, 2016 . 1 changed file with 177 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,12 +1,182 @@ # Create SSH tunnels using systemd services ## Overview This systemd service scripts will allow you to create SSH tunnels in background using systemd in user mode and a configuration file. ## Setup the SSH authentication agent systemd unit To be able to run SSH tunnels in background while using a password protected SSH key to connect to the targeted host, we'll first have to setup an _ssh-agent_ (see [ssh-agent(1)](https://linux.die.net/man/1/ssh-agent)). The agent will be run in background using a user _systemd service unit_ (see [systemd.service(5)](https://www.freedesktop.org/software/systemd/man/systemd.service.html), [systemd.unit(5)](https://www.freedesktop.org/software/systemd/man/systemd.unit.html), [ArchLinux wiki page](https://wiki.archlinux.org/index.php/Systemd/User)). ```bash # (create the systemd config directory if it does not exists) $ mkdir -p ~/.config/systemd/user/ # create the ssh-agent.service unit $ cat <<'EOF' > ~/.config/systemd/user/ssh-agent.service [Unit] Description=SSH key agent Documentation=man:ssh-agent(1) Wants=environment.target Before=environment.target [Service] Type=forking Environment="SSH_AUTH_SOCK=%t/ssh-agent.socket" ExecStart=/usr/bin/ssh-agent -a $SSH_AUTH_SOCK ExecStartPost=/bin/systemctl --user set-environment \ SSH_AUTH_SOCK=${SSH_AUTH_SOCK} [Install] WantedBy=multi-user.target EOF ``` Once it's done we can start the authentication agent: ```bash systemctl --user start ssh-agent ``` Or even make it load at session opening: ```bash systemctl --user enable ssh-agent ``` After that, we make the `$SSH_AUTH_SOCK` env variable be loaded at our shell initialization (here [bash](https://www.gnu.org/software/bash/)): ```bash echo 'export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"' >> ~/.bashrc source ~/.bashrc ``` Finally we add our (default) private key identity to the authentication agent ```bash ssh-add ``` _Note:_ __it have to be done at every boot in order for the tunnels to work !__ ## Setup the SSH-tunnel systemd unit As for the [SSH authentication agent](#setup_the_ssh_authentication_agent_systemd_unit) service, we'll run our SSH tunnels ([ssh(1)](https://linux.die.net/man/1/ssh)) using a _systemd service unit_ but this unit will be instanciable (see [systemd.unit(5)](https://www.freedesktop.org/software/systemd/man/systemd.unit.html), [Lennart Poettering's blog](http://0pointer.de/blog/projects/instances.html), [Archlinux wiki](https://wiki.archlinux.org/index.php/Systemd#Using_units), [Fedoramagazine article](https://fedoramagazine.org/systemd-template-unit-files/)). ```bash # (create the systemd config directory if it does not exists) $ mkdir -p ~/.config/systemd/user/ # create the ssh-tunnel@.service unit $ cat <<'EOF' > ~/.config/systemd/user/ssh-tunnel@.service [Unit] Description=SSH tunnel to %i Documentation=man:ssh(1) Wants=ssh-agent.service After=network.target ssh-agent.service [Service] Type=simple Environment="LOCAL_ADDR=127.0.0.1" Environment="REMOTE_ADDR=127.0.0.1" EnvironmentFile=%h/.ssh/tunnels/%i ExecStart=/usr/bin/ssh -NT ${TARGET} ${SSH_OPTS} \ -o ExitOnForwardFailure=yes -o ServerAliveInterval=60 \ -L ${LOCAL_ADDR}:${LOCAL_PORT}:${REMOTE_HOST}:${REMOTE_PORT} RestartSec=10 Restart=on-success RestartForceExitStatus=255 [Install] WantedBy=multi-user.target EOF ``` ## Creating tunnels ! We'll now create _systemd service instances_ to run our tunnels. Our _ssh-tunnel_ service is going to look for it's configuration file into the `~/.ssh/tunnels/` directory so we start with creating the directory: mkdir -p ~/.ssh/tunnels/ We'll then have to create a configuration file for our tunnel: ```bash $ cat <<'EOF' > ~/.ssh/tunnels/testtun # This parameters will be used to run: # ssh ${TARGET} ${SSH_OPTS} \ # -L ${LOCAL_ADDR}:${LOCAL_PORT}:${REMOTE_ADDR}:${REMOTE_PORT} # The target of the SSH command TARGET=user@hostname # The local port to listen to LOCAL_PORT=8080 # The remote port to forward REMOTE_PORT=80 # The local address to listen to (default: _127.0.0.1_) #LOCAL_ADDR=0.0.0.0 # The remote host to forward to (default: _127.0.0.1_) #REMOTE_HOST=domain.tld # Additional -custom- SSH options #SSH_OPTS=-v EOF ``` We'll then have to create a configuration file for our tunnel, the allowed parameters are the following: - `TARGET`: the target of the SSH command (ie. _user@hostname_) - `LOCAL_ADDR`: the local address to listen to (default: _127.0.0.1_) - `LOCAL_PORT`: the local port to listen to (ie. _8080_) - `REMOTE_HOST`: the remote host to forward to (default: _127.0.0.1_) - `REMOTE_PORT`: the remote port to forward (ie. _80_) - `SSH_OPTS`: additional -custom- SSH options Finally we can run our _systemd service unit_ that will create the tunnel: ```bash systemctl --user start ssh-tunnel@testtun ``` Or make it load a session loading: ```bash systemctl --user enable ssh-tunnel@testtun ``` _Note:_ make sure your SSH authentication agent has been loaded properly using `ssh-add`, the tunnel will not work without it We can check the tunnel's status using: ```bash systemctl --user status -l ssh-tunnel@localhost-test ``` ## Example: create an SSH tunnel to a MySQL service only accessible through an SSH bastion Let's create a configuration file to access to the MySQL service (_3306_ port) of the _machine001.domain.tld_ machine that's only through the _access.domain.tld_ bastion and make the tunnel accessible to other machines over the network: ```bash $ cat <<'EOF' > ~/.ssh/tunnels/machine001-mysql TARGET=user@access.domain.tld LOCAL_ADDR=0.0.0.0 LOCAL_PORT=3307 REMOTE_PORT=3306 REMOTE_HOST=machine001.domain.tld EOF ``` Then start the tunnel and make it load at session loading: ```bash systemctl --user start ssh-tunnel@machine001-mysql systemctl --user enable ssh-tunnel@machine001-mysql ``` We can now connect to the machine001's MySQL service using: ```bash mysql -h 127.0.0.1 -P 3307 ``` -
olbat created this gist
Oct 28, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,12 @@ # ~/.config/systemd/user/ssh-agent.service systemctl --user enable ssh-agent systemctl --user start ssh-agent echo 'export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"' >> ~/.bashrc source ~/.bashrc ssh-add # ~/.config/systemd/user/ssh-tunnel@.service # ~/.ssh/tunnels/localhost-test systemctl --user start ssh-tunnel@localhost-test systemctl --user enable ssh-tunnel@localhost-test systemctl --user status -l ssh-tunnel@localhost-test