2012-09-26 40 views
6

Tengo un script de perl que, cuando destilada un poco, se ve así:Verificando un túnel SSH está funcionando

my $randport = int(10000 + rand(1000));   # Random port as other scripts like this run at the same time 
my $localip = '192.168.100.' . ($port - 4000); # Don't ask... backwards compatibility 
system("ssh -NL $randport:$localip:23 root\@$ip -o ConnectTimeout=60 -i somekey &"); # create the tunnel in the background 

sleep 10;  # Give the tunnel some time to come up 

# Create the telnet object 
my $telnet = new Net::Telnet(
     Timeout =>  10, 
     Host =>  'localhost', 
     Port =>  $randport, 
     Telnetmode => 0, 
     Errmode =>  \&fail, 
); 

# SNIPPED... a bunch of parsing data from $telnet 

La cosa es que el objetivo $ ip está en un enlace con muy impredecible ancho de banda, por lo que el túnel podría aparecer de inmediato, podría tomar un tiempo, podría no aparecer en absoluto. Por lo tanto, es necesario dormir para que el túnel pueda comenzar a funcionar.

Entonces la pregunta es: ¿cómo puedo probar si el túnel está funcionando? 10 segundos es una demora realmente indeseable si el túnel aparece de inmediato. Idealmente, me gustaría verificar si está activo y continuar creando el objeto telnet una vez que esté, hasta un máximo de, digamos, 30 segundos.

Editar: Ping no me ayuda a Mouch, como el extremo remoto del túnel es generalmente hacia arriba, pero con una cantidad muy alta de pérdida de paquetes

resuelto: Extrapolando a partir de la punta sugerido por mikebabcock , sleep 10 se ha sustituido con este bloque, que funciona como un encanto:

my $starttime = time(); 
while (1) 
{ 
    # Check for success 
    if (system("nc -dzw10 localhost $randport > /dev/null") == 0) { last } 

    # Check for timeout 
    if (time() > $starttime + 30) { &fail() } 

    # 250ms delay before recheck 
    select (undef, undef, undef, 0.25); 
} 
+0

Como está utilizando el módulo 'Net :: Telnet', ¿ha intentado utilizar la llamada' open' y probar si tiene éxito? No soy un experto en Telnet, pero eso es lo que probablemente probaría si fuera yo ... –

+0

Podría hacer eso si no hay una manera simple de probar: vuelva a intentar hasta el éxito si time_spend_trying <30 seconds – Jarmund

Respuesta

6

Uso netcat - nc menudo en sistemas Linux:

nc -dvzw10 ${HOSTNAME} 23 

funciona para mí, con una respuesta como:

Connection to ${HOSTNAME} 23 port [tcp/telnet] succeeded! 

También devuelve 0 en caso de éxito, y es feliz con un simple conexión después de lo cual desaparece.

  • -d significa no leer nada desde el lado del teclado
  • -v significa ser prolijo (desactivar esta opción en un script)
  • -z significa desconectar después de hacer la conexión
  • - w10 significa esperar hasta 10 segundos; de lo contrario, renunciar a
0

puede integrar un ping al servidor ssh y si funciona bien el túnel SSH es de hasta

# only a ping sample :-D 
if ! ping -c 1 192.168.101.9 
then 
     echo ":-(" 
else 
     echo ":-)" 
fi 
+0

quizás también sea una buena idea poner el ping en un bucle – OkieOth

+0

ping no me ayuda mucho, ya que generalmente tiene ~ 50% packetloss (esto se prueba de antemano, y créalo o no, es aceptable hasta el 50%) – Jarmund

+0

pero sale con éxito si el túnel está arriba. La calidad forma parte de otros niveles de comunicación – OkieOth

0

Creo que el fping podría ser mejor que el ping habitual, más compatible con las secuencias de comandos.

fping -t 60000 [servidor]

debe tratar de conectarse a los servidores de 60 segundos antes de renunciar a Algo así como

if(fping -t 60000 [your server]) { 
execute desired code; 
} else { 
execute this script again to rerun;; 
} 

creo que usted consigue la idea, incluso si la codificación no es real.