Check connexion SSH

Check connexion SSH - Codes et scripts - Linux et OS Alternatifs

Marsh Posté le 12-02-2015 à 10:08:51    

Bonjour à tous.
 
Dans le cadre de mon taff, j'ai mis en place un montage automatique de tunnels SSH entre plusieurs machines.
 
La machine du client initie la connexion vers mon serveur public, avec un peu de RemoteForward pour les redirections 22 et 3389.  
 
De temps à autre, il doit y avoir des coupures du lien etre mes clients et moi, et la connexion se coupe.
Le processus SSH est toujours en exécution du côté client, aussi mon script de test ne le relance pas (car déjà existant).
 
J'aimerais avoir une solution pour tester si le tunnel est toujours ouvert, et l'automatiser.
 
J'avais songé à récupérer les PID des différentes connexions en LISTENING sur mon serveur, de comparer avec les PID des process ssh sur le serveur...
Mais en fait il me semble (car le problème ne s'est pas reproduit depuis un long moment et je ne peux pas le reproduire manuellement) que lors d'une coupure, le process SSH disparait également sur le serveur.
 
Sur mon client j'ai une connexion ESTABLISHED unique vers mon serveur public, associée au PID du script SSH.  
(tiens en passant, je me demande si cette connexion ne passerait pas en LISTENING ou TIME_WAIT si la coupure de connexion se reproduisait... a tester quand cela se reproduira).
 
Si vous avez quelques idées de pistes à creuser, je suis demandeur ! :)


---------------
Truez zo marv, karantez zo interet. \\ Kement-se zo evit lakaat ar sod da gomz hag ar fur da devel.
Reply

Marsh Posté le 12-02-2015 à 10:08:51   

Reply

Marsh Posté le 12-02-2015 à 10:18:27    

tu peux pas intergrer un bëte "ssh machinedistante date " pour tester la com entre tes deux machines ?  
si OK, on touche à rien, si KO , tu kill ton tunnel et tu le relances?  


---------------
L'ouverture d'esprit n'est pas une fracture du crâne ...
Reply

Marsh Posté le 12-02-2015 à 10:21:21    

Ca va pas relancer le tunnel tout simplement de faire ça ?
Ca va le relancer le temps de la commande date...
 
Les certifs ont été échangés donc le tunnel monte en deux deux.
Si je teste "ssh monserveurdistant date", il va me monter le tunnel (un nouveau tunnel donc) et ne va pas vérifier le bon établissement des premiers liens.


---------------
Truez zo marv, karantez zo interet. \\ Kement-se zo evit lakaat ar sod da gomz hag ar fur da devel.
Reply

Marsh Posté le 12-02-2015 à 10:24:38    

j'ai un peu de mal à visulaiser ton archi et ton montage de tunnel ...
Qu'appelle tu un tunnel SSH ? et comment est il monté/appellé ? il n'est pas persistant ? il monte lors de la sollicitation d'une com entre les deux serveurs ?
 
Tunnel ssh crypté ?
 
edit : pour le test :  
 lsof -i tcp | grep "^ssh" | grep ESTABLISHED


Message édité par izn0 le 12-02-2015 à 10:35:23

---------------
L'ouverture d'esprit n'est pas une fracture du crâne ...
Reply

Marsh Posté le 12-02-2015 à 11:04:45    

Merci pour la commande, je regarde ça au prochain crash de la liaison.
 
En fait mon SSH est monté via un script, tout bêtement, en cron.  
Il est persistant, et c'est bien là le souci.  
Lorsque j'ai une coupure, le process ssh reste sur la machine cliente, tout va bien pour elle. La liaison est elle, dans les choux complètement.
 
Faut que je regarde à la prochaine coupure.
 
Merci :jap:


---------------
Truez zo marv, karantez zo interet. \\ Kement-se zo evit lakaat ar sod da gomz hag ar fur da devel.
Reply

Marsh Posté le 12-02-2015 à 11:16:36    

je pense qu'effectivement, tu dois pouvoir jouer sur le ESTABLISHED pour faire ton check. il faudrait vérifier, si lors du crash de ton tunnel tu est toujours en paire "ESTABLISHED"  
si t'as un environnement de test, tu peux jetter un oeil la dessus  
http://www.harding.motd.ca/autossh/


---------------
L'ouverture d'esprit n'est pas une fracture du crâne ...
Reply

Marsh Posté le 12-02-2015 à 11:41:54    

Essaye

Code :
  1. ssh -o ServerAliveInterval=10 user@host


Citation :

ServerAliveInterval
             Sets a timeout interval in seconds after which if no data has been received from the server, ssh(1) will send a message through the encrypted channel to request a
             response from the server.  The default is 0, indicating that these messages will not be sent to the server, or 300 if the BatchMode option is set.  This option
             applies to protocol version 2 only.


Message cité 1 fois
Message édité par N-Mi le 12-02-2015 à 11:42:13

---------------
Le V-Twin, c'est la vie ! | inconditionnel du chant des patates | Bon anniversaire !
Reply

Marsh Posté le 12-02-2015 à 12:16:12    

N-Mi a écrit :

Essaye

Code :
  1. ssh -o ServerAliveInterval=10 user@host


Citation :

ServerAliveInterval
             Sets a timeout interval in seconds after which if no data has been received from the server, ssh(1) will send a message through the encrypted channel to request a
             response from the server.  The default is 0, indicating that these messages will not be sent to the server, or 300 if the BatchMode option is set.  This option
             applies to protocol version 2 only.




 
Déjà mise en place comme option, directement dans les fichiers de conf pour cette connexion :jap:


---------------
Truez zo marv, karantez zo interet. \\ Kement-se zo evit lakaat ar sod da gomz hag ar fur da devel.
Reply

Marsh Posté le 12-02-2015 à 12:21:12    

Et ça ne coupe pas la connexion automatiquement ?


---------------
Le V-Twin, c'est la vie ! | inconditionnel du chant des patates | Bon anniversaire !
Reply

Marsh Posté le 12-02-2015 à 12:22:49    

La connexion oui. Le serveur coupe bien, il n'y a plus de traces.

 

Le process SSH sur le client tourne toujours lui.

 

Mon script automatique recherche ce process et relance le tunnel si le process n'est pas existant.
En l'occurence il existe, donc le tunnel n'est pas relancé.
La connexion est coupée, mais le script n'en sait rien et ne relance rien.

 

Je testerai la méthode avec les ESTABLISHED


Message édité par Nanab le 12-02-2015 à 12:23:03

---------------
Truez zo marv, karantez zo interet. \\ Kement-se zo evit lakaat ar sod da gomz hag ar fur da devel.
Reply

Marsh Posté le 12-02-2015 à 12:22:49   

Reply

Marsh Posté le 12-02-2015 à 12:32:18    

C'est pas normal. Tu as activé l'option côté client ou côté serveur ?
 
Par défaut, si on active le ServerAliveInterval, le client attend 3 keepalives (réglable par le paramètre ServerAliveCountMax) avant de considérer la connexion comme dead et terminer le process.
 
Peux-tu donner la ligne de commande complète qui te sert à lancer le processus côté client ?


---------------
Le V-Twin, c'est la vie ! | inconditionnel du chant des patates | Bon anniversaire !
Reply

Marsh Posté le 12-02-2015 à 13:03:45    

Le process client est lancé par une commande simple :
ssh -fN monserveur.masociete.fr
 
C'est dans le ssh_config que j'ai les options ensuite :
Host *.masociete.fr
port XXXX
RemoteForward
ServerAliveInterval


---------------
Truez zo marv, karantez zo interet. \\ Kement-se zo evit lakaat ar sod da gomz hag ar fur da devel.
Reply

Marsh Posté le 12-02-2015 à 13:26:07    

Il n'y a pas de valeur définie à ton paramètre ServerAliveInterval, essaye de mettre 10
 
Je pense qu'il reste avec la valeur par défaut sinon (0, qui veut dire "jamais" ).


---------------
Le V-Twin, c'est la vie ! | inconditionnel du chant des patates | Bon anniversaire !
Reply

Marsh Posté le 12-02-2015 à 13:28:38    

D'ailleurs, tu peux vérifier qu'il envoie bien les keepalive en lançant une connexion inactive, et en faisant un tcpdump.


---------------
Le V-Twin, c'est la vie ! | inconditionnel du chant des patates | Bon anniversaire !
Reply

Marsh Posté le 12-02-2015 à 13:45:37    

Bonne idée le tcpdump. je vais faire ça.
 
Par contre, j'ai pas mis les valeurs, mais elles sont bien renseignées.  
Mon keepalive est à 15
(et btw, le remoteforward tout seul comme ça ne peut pas marcher non plus, mais je ne vous emmerde pas au point de mettre les params ;)   )


---------------
Truez zo marv, karantez zo interet. \\ Kement-se zo evit lakaat ar sod da gomz hag ar fur da devel.
Reply

Marsh Posté le 12-02-2015 à 14:39:26    

Le tcpdump remonte bien les keepAlive

 

Le délai de 15 secondes est bon (j'ai deux clients, d'où les deux WANs)

 
Citation :

[root@webpub ~]# tcpdump host 80.XX.XX.XX or 46.XX.X.XX -vv
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
14:33:59.845116 IP (tos 0x0, ttl 50, id 65177, offset 0, flags [DF], proto TCP (6), length 116)
    46.XX.XX.XX > 10.YY.YY.YY.ssh: Flags [P.], cksum 0x334c (correct), seq 4286898003:4286898067, ack 502370005, win 1002, options [nop,nop,TS val 1081120198 ecr 758174518], length 64
14:33:59.845296 IP (tos 0x0, ttl 64, id 940, offset 0, flags [DF], proto TCP (6), length 84)
    10.YY.YY.YY.ssh > 46.XX.XX.XX.46716: Flags [P.], cksum 0xa475 (incorrect -> 0x9405), seq 1:33, ack 64, win 588, options [nop,nop,TS val 758189586 ecr 1081120198], length 32
14:33:59.878791 IP (tos 0x0, ttl 50, id 65178, offset 0, flags [DF], proto TCP (6), length 52)
    46.XX.XX.XX.46716 > 10.YY.YY.YY.ssh: Flags [.], cksum 0x7a88 (correct), seq 64, ack 33, win 1002, options [nop,nop,TS val 1081120214 ecr 758189586], length 0
14:34:02.819484 IP (tos 0x0, ttl 49, id 58245, offset 0, flags [DF], proto TCP (6), length 116)
    80.XX.XX.XX.18613 > 10.YY.YY.YY.ssh: Flags [P.], cksum 0x37ee (correct), seq 4154670747:4154670811, ack 1482871572, win 4006, options [nop,nop,TS val 3928313806 ecr 758177536], length 64
14:34:02.819981 IP (tos 0x0, ttl 64, id 22835, offset 0, flags [DF], proto TCP (6), length 84)
    10.YY.YY.YY.ssh > 80.XX.XX.XX.18613: Flags [P.], cksum 0x095e (incorrect -> 0x1e12), seq 1:33, ack 64, win 501, options [nop,nop,TS val 758192560 ecr 3928313806], length 32
14:34:02.846377 IP (tos 0x0, ttl 49, id 58246, offset 0, flags [DF], proto TCP (6), length 52)
    80.XX.XX.XX.18613 > 10.YY.YY.YY.ssh: Flags [.], cksum 0x3243 (correct), seq 64, ack 33, win 4006, options [nop,nop,TS val 3928313812 ecr 758192560], length 0
14:34:14.879192 IP (tos 0x0, ttl 50, id 65179, offset 0, flags [DF], proto TCP (6), length 116)
    46.XX.XX.XX.46716 > 10.YY.YY.YY.ssh: Flags [P.], cksum 0x1d23 (correct), seq 64:128, ack 33, win 1002, options [nop,nop,TS val 1081123964 ecr 758189586], length 64
14:34:14.879450 IP (tos 0x0, ttl 64, id 941, offset 0, flags [DF], proto TCP (6), length 84)
    10.YY.YY.YY.ssh > 46.XX.XX.XX.46716: Flags [P.], cksum 0xa475 (incorrect -> 0x2dde), seq 33:65, ack 128, win 588, options [nop,nop,TS val 758204620 ecr 1081123964], length 32
14:34:14.941117 IP (tos 0x0, ttl 50, id 65180, offset 0, flags [DF], proto TCP (6), length 52)
    46.XX.XX.XX.46716 > 10.YY.YY.YY.ssh: Flags [.], cksum 0x30bf (correct), seq 128, ack 65, win 1002, options [nop,nop,TS val 1081123973 ecr 758204620], length 0
14:34:17.843808 IP (tos 0x0, ttl 49, id 58247, offset 0, flags [DF], proto TCP (6), length 116)
    80.XX.XX.XX.18613 > 10.YY.YY.YY.ssh: Flags [P.], cksum 0xffeb (correct), seq 64:128, ack 33, win 4006, options [nop,nop,TS val 3928317562 ecr 758192560], length 64
14:34:17.844000 IP (tos 0x0, ttl 64, id 22836, offset 0, flags [DF], proto TCP (6), length 84)
    10.YY.YY.YY.ssh > 80.XX.XX.XX.18613: Flags [P.], cksum 0x095e (incorrect -> 0x09cd), seq 33:65, ack 128, win 501, options [nop,nop,TS val 758207585 ecr 3928317562], length 32
14:34:17.873364 IP (tos 0x0, ttl 49, id 58248, offset 0, flags [DF], proto TCP (6), length 52)
    80.XX.XX.XX.18613 > 10.YY.YY.YY.ssh: Flags [.], cksum 0xe885 (correct), seq 128, ack 65, win 4006, options [nop,nop,TS val 3928317568 ecr 758207585], length 0
^C
12 packets captured
12 packets received by filter
0 packets dropped by kernel


Message édité par Nanab le 12-02-2015 à 14:48:56

---------------
Truez zo marv, karantez zo interet. \\ Kement-se zo evit lakaat ar sod da gomz hag ar fur da devel.
Reply

Marsh Posté le 12-02-2015 à 15:31:11    

Il y a quelque chose qui m'échappe.
 
Si je comprends bien, la liaison a une coupure, qui pète le tunnel, le process s'arrête côté serveur, mais persiste côté client.
 
Je vois bien le paramètre "ExitOnForwardFailure=yes" qui pourrait jouer un rôle, mais à priori s'applique seulement en cas d'échec à l'établissement du tunnel, ce qui ne semble pas être ton cas. Enfin ça ne coûte rien d'essayer.
 
Sinon, j'ai trouvé cet article sympa, dont tu pourrais t'inspirer si le trafic qui transite à travers ton tunnel utilise une connexion persistante :
http://www.g-loaded.eu/2006/11/24/ [...] h-tunnels/


---------------
Le V-Twin, c'est la vie ! | inconditionnel du chant des patates | Bon anniversaire !
Reply

Marsh Posté le 12-02-2015 à 15:43:43    

C'est exactement ce comportement, N-mi...
 
Je regarde ton article ce soir en rentrant.
En effet l'option (qui est d'ailleurs par défaut, il me semble) n'agit que sur l'établissement.


---------------
Truez zo marv, karantez zo interet. \\ Kement-se zo evit lakaat ar sod da gomz hag ar fur da devel.
Reply

Marsh Posté le 12-02-2015 à 16:02:35    

Moi j'utilise autossh pour maintenir ma connection ssh vers mon server/proxy automatiquement.
 
Peut être que ça résoudra ton problème ?
 
https://wiki.archlinux.fr/Autossh


---------------
Dell 17R-SE / HTPC 3770K / Domotique DIY / Volumio DAC Rpi3 / Recalbox v4 Rpi3 / Citroen 2CV6 Special E
Reply

Marsh Posté le 12-02-2015 à 16:24:47    

Bon j'avais une hypothèse, mais impossible de reproduire le problème depuis chez moi, donc j'ai un doute sur la validité de mon raisonnement.
 
Voici la réponse que j'étais sur le point d'envoyer :
 

Citation :

Ah j'ai peut-être une idée sur ce qui ce passe [:idee]  
 
En fait, la liaison foire et le tunnel est cassé :
 - côté serveur, à priori tout se passe bien : le service à l'autre bout ferme la connexion, le process ssh côté serveur se termine.
 - côté client, le process SSH détecte que le tunnel est foiré, mais ne peut pas quitter parce que la liaison TCP est toujours établie entre lui-même et le processus local qui utilise la connexion tunnélisée.
 
Dit autrement, le process ssh client a 2 connexions TCP :
 - la connexion SSH proprement dite, dans laquelle passe le tunnel
 - la connexion entre  localhost:3389 et le processus qui dialogue avec
 
Je pense que la première connexion TCP est bien coupée, mais que la seconde persiste.


 
Problème : lorsque je reproduis ton fonctionnement et que je coupe la connexion vers la machine de test (d'une manière non détectée facilement par ssh), au bout de 3 keepalive ratés le processus client reset la connexion vers le processus local (un apache dans mon cas) et se termine.
 
Il y a vraiment un comportement spécifique à ta plate-forme [:chewyy]


---------------
Le V-Twin, c'est la vie ! | inconditionnel du chant des patates | Bon anniversaire !
Reply

Marsh Posté le 12-02-2015 à 16:33:22    

Ta citation doit coller au comportement.
 
Malheureusement comme ça ne s'est pas reproduit depuis un moment, je n'ai pas pu vérifier quels process étaient encore en cours, mais je pense que tu as vu juste.
 
En effet je n'arrive pas non plus à le reproduire.
 
Zorglub : une des machines est une distro un peu limitée, donc autossh n'y est pas (oui je sais c'est nul...) et comme c'est une machine cliente, je n'ai pas le droit d'y installer de paquets ! ;) Mais merci de l'idée :)
 
Nous verrons bien à la prochaine coupure, j'essaierai de choper un max d'infos. Sauf que souvent je m'en rends compte quand il faut que j'intervienne rapidement chez le client, aussi je remonte le tunnel à toute vitesse pour le satisfaire...


---------------
Truez zo marv, karantez zo interet. \\ Kement-se zo evit lakaat ar sod da gomz hag ar fur da devel.
Reply

Marsh Posté le 12-02-2015 à 16:39:24    

J'ai trouvé des liens qui parlent de problèmes similaires (et pouvant se produite de manière non reproductible), mais pas dans un contexte de tunneling malheureusement, mais en effet mon idée pourrait être assez proche du comportement observé.

 

http://stackoverflow.com/questions [...] -sometimes
http://www.snailbook.com/faq/background-jobs.auto.html


Message édité par N-Mi le 12-02-2015 à 16:40:42

---------------
Le V-Twin, c'est la vie ! | inconditionnel du chant des patates | Bon anniversaire !
Reply

Marsh Posté le 12-02-2015 à 17:38:56    

Bingo !
 
J'ai (presque) reproduit le problème.
 
1) Dans un term sur mon PC, je lance la commande suivante pour streamer à basse vitesse un gros fichier à toute connexion entrante sur le port 10000

pv --rate-limit=1k <~/work/archives/debian-live-7.5.0-amd64-standard.iso | nc -l -p 10000 -k


 
2) Dans un autre term, je lance un reverse tunnel SSH vers un serveur du taff, qui écoute sur le port 12345 et se connect au port 10000 du PC :

ssh -R 12345:localhost:10000 server1 -Nf -o ServerAliveInterval=10 -o ExitOnForwardFailure=yes


 
3) Depuis server1, je me connecte à localhost:12345 pour accéder au port 10000 de mon PC :

nc localhost 12345 >/tmp/pouet


 
4) Je coupe mon VPN qui me permet d'accéder à server1, et interrompt donc tout possibilité de communiquer à travers le tunnel SSH
 
5) Un quart d'heure après avoir coupé le VPN, le processus client est toujours présent, parce que netcat est encore en train d'essayer de balancer du trafic :

$ ps fux | grep ssh | grep 12345
nicolas  20831  0.0  0.1  49448  4664 ?        SNs  16:58   0:00 ssh -R 12345:localhost:10000 adm1 -Nf -o ServerAliveInterval=10 -o ExitOnForwardFailure=yes


 
6) Je me connecte par un autre chemin sur server1. Je constate que le processus serveur SSH est toujours là, ainsi que le netcat. C'est là que le comportement diverge (verge :o ) à cause sûrement de réglages différents pour les timeout TCP. Je kille le process serveur SSH, ce qui entraîne le netcat de server1 dans la foulée.
 
7) Je relance le VPN. Mais je constate que même après plusieurs minutes, le client SSH est toujours là et pense toujours être connecté (note: 192.168.2.1 est l'adresse du VPN (ppp0) ) :

sudo lsof -np 20831 | grep TCP
ssh     20831 nicolas    3u  IPv4 312649401      0t0     TCP 192.168.2.1:47969->X.X.X.X:ssh (ESTABLISHED)
ssh     20831 nicolas    5u  IPv4 312649684      0t0     TCP 127.0.0.1:58005->127.0.0.1:webmin (ESTABLISHED)


 
Le pire dans tout ça, c'est que la connexion est bien dans l'état ESTABLISHED pour les 2 sockets du client SSH.
 


---------------
Le V-Twin, c'est la vie ! | inconditionnel du chant des patates | Bon anniversaire !
Reply

Marsh Posté le 12-02-2015 à 17:44:39    

Eh bah bravo ! C'est exactement ce que j'ai chez moi :)
 
Sauf pour le process coté serveur encore présent.
 
Bon tu me résouds ça pour demain ? :o
 
Merci beaucoup pour tes investigations N-Mi :jap:


---------------
Truez zo marv, karantez zo interet. \\ Kement-se zo evit lakaat ar sod da gomz hag ar fur da devel.
Reply

Marsh Posté le 12-02-2015 à 17:48:46    

Ah ben le temps de finir de taper le message, le processus client SSH s'est terminé avec un message "Write failed: Broken pipe".
 
Après, c'est peut-être dû à un timeout de netcat ou a des différences de config. Ou alors pv a trop bufferisé de données dans le pipe vers netcat. Bref, difficile de savoir.
 
En tout cas, ça ressemble furieusement à ton problème.
 
L'idéal serait donc de trouver un moyen de tester périodiquement (via une tâche cron) que le tunnel fonctionne bien, et de le tuer/redémarrer si ce n'est pas le cas.


---------------
Le V-Twin, c'est la vie ! | inconditionnel du chant des patates | Bon anniversaire !
Reply

Marsh Posté le 12-02-2015 à 18:02:45    

That's the point.
 
Mon autre soluce est de kill le process tous les matins et de le relancer. Mais c'est sale, j'aime pas :o


---------------
Truez zo marv, karantez zo interet. \\ Kement-se zo evit lakaat ar sod da gomz hag ar fur da devel.
Reply

Marsh Posté le 12-02-2015 à 18:37:46    

Solution à la con :
 
Sur le client, lancer périodiquement un script qui se connecte vers le port du serveur en écoute localement. Exemple :

ssh monserveur.masociete.fr "nmap -Pn -p12345 localhost | grep closed"


 
Si le port est fermé, c'est que le process ssh s'est terminé côté serveur. Donc tu tues ton client SSH bloqué et tu relances le tunnel.


---------------
Le V-Twin, c'est la vie ! | inconditionnel du chant des patates | Bon anniversaire !
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed