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
Pour que cette connexion se lance au démarrage de la machine, utiliser systemd
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 :
journalctl -u autossh-tunnel.service pour diagnostiquer.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éez un fichier générique avec un @ dans le nom :
vi /etc/systemd/system/autossh@.service
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
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"
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.
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