J'ai écrit un petit script bash qui nécessite un tunnel ssh pour extraire les données d'un serveur distant. Il invite donc l'utilisateur:
echo "Please open an ssh tunnel using 'ssh -L 6000:localhost:5432 example.com'"
Je voudrais vérifier si l'utilisateur a ouvert ce tunnel et quitter avec un message d'erreur si aucun tunnel n'existe. Existe-t-il un moyen d’interroger le tunnel ssh
, c’est-à-dire de vérifier si le port local 6000 est réellement tunnelé vers ce serveur?
Ceci est mon test. J'espère que c'est utile.
# $COMMAND is the command used to create the reverse ssh tunnel
COMMAND="ssh -p $SSH_PORT -q -N -R $REMOTE_Host:$REMOTE_HTTP_PORT:localhost:80 $USER_NAME@$REMOTE_Host"
# Is the tunnel up? Perform two tests:
# 1. Check for relevant process ($COMMAND)
pgrep -f -x "$COMMAND" > /dev/null 2>&1 || $COMMAND
# 2. Test tunnel by looking at "netstat" output on $REMOTE_Host
ssh -p $SSH_PORT $USER_NAME@$REMOTE_Host netstat -an | egrep "tcp.*:$REMOTE_HTTP_PORT.*LISTEN" \
> /dev/null 2>&1
if [ $? -ne 0 ] ; then
pkill -f -x "$COMMAND"
$COMMAND
fi
Netcat est votre ami:
nc -z localhost 6000 || echo 'no tunnel open'; exit 1
Autossh est la meilleure option - le processus de vérification ne fonctionne pas dans tous les cas (par exemple, processus zombie, problèmes liés au réseau)
exemple:
autossh -M 2323 -c arcfour -f -N -L 8088:localhost:80 Host2
C'est vraiment une question de type serverfault, mais vous pouvez utiliser netstat.
quelque chose comme:
# netstat -lpnt | grep 6000 | grep ssh
Cela vous indiquera si un processus ssh écoute sur le port spécifié. il vous indiquera également le PID du processus.
Si vous voulez vraiment vérifier que le processus ssh a été lancé avec les bonnes options, vous pouvez alors rechercher le processus par PID dans quelque chose comme:
# ps aux | grep PID
Utilisez autossh . C'est l'outil qui est destiné à surveiller la connexion SSH.
stunnel est un bon outil pour établir des connexions semi-permanentes entre les hôtes.
Ce sont des étapes plus détaillées pour tester ou dépanner un tunnel SSH. Vous pouvez en utiliser certaines dans un script. J'ajoute cette réponse parce que je devais résoudre le lien entre deux applications après qu'elles aient cessé de fonctionner. Il ne suffisait pas de mettre en place le processus SSH, car il était toujours là. Et je ne pouvais pas utiliser nc -z
car cette option n'était pas disponible sur mon incantation de netcat.
Commençons par le début. Supposons qu’il existe une machine appelée locale avec l’adresse IP 10.0.0.1 et une autre appelée distante à 10.0.3.12. Je vais préfixer ces noms d’hôte, aux commandes ci-dessous, il est donc évident de savoir où ils sont exécutés.
L'objectif est de créer un tunnel qui transmettra le trafic TCP de l'adresse de bouclage sur la machine distante sur le port 123 à la machine locale sur le port 456. Cela peut être fait avec la commande suivante sur la machine locale:
local:~# ssh -N -R 123:127.0.0.1:456 10.0.3.12
Pour vérifier que le processus est en cours d'exécution, nous pouvons faire:
local:~# ps aux | grep ssh
Si vous voyez la commande dans la sortie, nous pouvons continuer. Sinon, vérifiez que la clé SSH est installée dans la télécommande. Notez qu'en excluant le nom d'utilisateur avant l'adresse IP distante, ssh utilise le nom d'utilisateur actuel.
Ensuite, nous voulons vérifier que le tunnel est ouvert sur la télécommande:
remote:~# netstat | grep 10.0.0.1
Nous devrions obtenir un résultat similaire à ceci:
tcp 0 0 10.0.3.12:ssh 10.0.0.1:45988 ESTABLISHED
Serait agréable de voir certaines données passant de la télécommande à l'hôte. C'est ici que netcat entre en jeu. Sous CentOS, il peut être installé avec yum install nc
.
Tout d’abord, ouvrez un port d’écoute sur la machine locale:
local:~# nc -l 127.0.0.1:456
Ensuite, établissez une connexion sur la télécommande:
remote:~# nc 127.0.0.1 123
Si vous ouvrez un deuxième terminal sur la machine locale, vous pouvez voir la connexion. Quelque chose comme ça:
local:~# netstat | grep 456
tcp 0 0 localhost.localdom:456 localhost.localdo:33826 ESTABLISHED
tcp 0 0 localhost.localdo:33826 localhost.localdom:456 ESTABLISHED
Mieux encore, allez-y et tapez quelque chose sur la télécommande:
remote:~# nc 127.0.0.1 8888
Hallo?
anyone there?
Vous devriez voir cela reflété sur le terminal local:
local:~# nc -l 127.0.0.1:456
Hallo?
anyone there?
Le tunnel fonctionne! Mais que se passe-t-il si vous avez une application, appelée appname, qui est censée écouter sur le port 456 de la machine locale? Terminez nc des deux côtés puis exécutez votre application. Vous pouvez vérifier qu'il écoute sur le port correct avec this :
local:~# netstat -tulpn | grep LISTEN | grep appname
tcp 0 0 127.0.0.1:456 0.0.0.0:* LISTEN 2964/appname
En passant, l'exécution de la même commande sur la télécommande devrait montrer que sshd écoute sur le port 127.0.0.1:123.
Nous pouvons vérifier en utilisant la commande ps
# ps -aux | grep ssh
Affichera tous les services shh en cours et nous pourrons trouver le service de tunnel répertorié
#!/bin/bash
# Check do we have tunnel to example.com server
lsof -i tcp@localhost:6000 > /dev/null
# If exit code wasn't 0 then tunnel doesn't exist.
if [ $? -eq 1 ]
then
echo ' > You missing ssh tunnel. Creating one..'
ssh -L 6000:localhost:5432 example.com
fi
echo ' > DO YOUR STUFF < '