Table des matières

autossh

autossh permet de garder des tunnels ssh ouvert et de les remonter en cas de déconnexion.

Installer autossh

apt install autossh

Comme le dit le man autossh il est préférable d’utiliser les options ServerAliveInternal et ServerAliveCountMax plutôt que d’utiliser le echo port pour le monitoring, je vais donc écrire les commandes dans ce contexte.

Exemple: J’ai besoin d’un accès à une base de données distante en local

La commande ssh serait

ssh -L 3307:localhost:3306 username@toto-public.com

La commande autossh serait

autossh -M 0 -q -f -N -oServerAliveInterval=60 -oServerAliveCountMax=3 -L 3307:localhost:3306 username@toto-public.com

Lancement automatique

Pour que cette connexion se lance au démarrage de la machine, utiliser systemd

Pour un tunnel

Créez un fichier de configuration pour votre tunnel (remplacez mon-tunnel par le nom de votre choix) :

vi /etc/systemd/system/autossh-tunnel.service

Copiez et adaptez le contenu suivant :

[Unit]
Description=AutoSSH Tunnel Service
After=network-online.target
StartLimitIntervalSec=300
StartLimitBurst=5
 
[Service]
Environment="AUTOSSH_GATETIME=0"
User=votre_utilisateur
# -M 0 désactive le monitoring d'autossh pour laisser SSH gérer ses propres timeouts
ExecStart=/usr/bin/autossh -M 0 -N -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -L 8080:localhost:80 user@remote-server -i /home/votre_utilisateur/.ssh/id_rsa
 
[Install]
WantedBy=multi-user.target

Exécutez ces commandes pour prendre en compte le nouveau service et l’activer au démarrage :

systemctl daemon-reload
systemctl enable autossh-tunnel.service
systemctl start autossh-tunnel.service

Points clés à vérifier :

Pour plusieurs tunnels

Pour gérer plusieurs tunnels proprement sans multiplier les fichiers manuellement, la meilleure pratique est d’utiliser les fichiers de service instanciés (templates) de systemd.

Créer un template de service

Créez un fichier générique avec un @ dans le nom :

vi /etc/systemd/system/autossh@.service

Configurer le template

Utilisez la variable %i qui sera remplacée par le nom du fichier de configuration que nous allons créer plus loin :

[Unit]
Description=AutoSSH tunnel pour %i
After=network-online.target
StartLimitIntervalSec=300
StartLimitBurst=5

[Service]
EnvironmentFile=/etc/default/autossh-%i
ExecStart=/usr/bin/autossh -M 0 -N $SSH_OPTIONS $TUNNEL_CONFIG $REMOTE_HOST
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Créer les fichiers de configuration

Pour chaque tunnel, créez un fichier d’environnement spécifique. Par exemple, pour un tunnel “Web” et un tunnel “DB” :

Fichier /etc/default/autossh-web :

SSH_OPTIONS="-o 'ServerAliveInterval 30' -o 'ServerAliveCountMax 3'"
TUNNEL_CONFIG="-L 8080:localhost:80"
REMOTE_HOST="user@serveur-web.com"

Fichier /etc/default/autossh-db :

SSH_OPTIONS="-o 'ServerAliveInterval 30' -o 'ServerAliveCountMax 3'"
TUNNEL_CONFIG="-L 5432:localhost:5432"
REMOTE_HOST="user@serveur-db.com"

Activer chaque tunnel individuellement

Il suffit maintenant d’appeler le service en ajoutant le nom défini après l’arobase :

systemctl daemon-reload

Activer le tunnel Web

systemctl enable --now autossh@web

Activer le tunnel DB

systemctl enable --now autossh@db

Avantages :

Maintenance simplifiée : Un seul fichier service pour tous vos tunnels.

Isolation : Vous pouvez redémarrer autossh@web sans couper autossh@db.

Clarté : La commande systemctl status “autossh*” vous donnera l’état de chaque tunnel distinctement.

Le cas avec Docker

Pour que votre container docker puisse accéder au port de son hôte, il faut modifier les options pour le tunnel

Changer ça

-L 33060:localhost:3306

par ça

-L 172.17.0.1:33060:localhost:3306

L’ip 172.17.0.1 est l’ip de l’hôte vu par les containers docker

Vérifier

# ss -ln4t
State                       Recv-Q                      Send-Q                                             Local Address:Port                                              Peer Address:Port                      
LISTEN                      0                           128                                                   172.17.0.1:33060                                                  0.0.0.0:*                         

# docker exec -ti myapp sh
/app # ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1): 56 data bytes
64 bytes from 172.17.0.1: seq=0 ttl=64 time=0.073 ms
64 bytes from 172.17.0.1: seq=1 ttl=64 time=0.069 ms
^C
--- 172.17.0.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.069/0.071/0.073 ms
                     mysql_waitpid              mysqlcheck                 mysqlimport
/app # mysql -h 172.17.0.1 -P 33060 -u user -p