web-dev-qa-db-fra.com

ssh: vérifie si un tunnel est en vie

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?

30
Adam Matan

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
27
Tommy

Netcat est votre ami:

nc -z localhost 6000 || echo 'no tunnel open'; exit 1
40
rwilhelm

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
17
Jeff

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
9
Igor Serebryany

Utilisez autossh . C'est l'outil qui est destiné à surveiller la connexion SSH.

6
plaes

stunnel est un bon outil pour établir des connexions semi-permanentes entre les hôtes.

http://www.stunnel.org/

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.

1
Nagev

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é 

0
Javeed Shakeel
#!/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 < '
0
sobi3ch