2012-09-26 14 views
6

Ho uno script perl che, quando distillata un po ', si presenta così:Verificando un tunnel SSH è installato e funzionante

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 

Il fatto è che l'obiettivo $ ip è su un link con molto imprevedibile larghezza di banda, quindi il tunnel potrebbe venire subito, potrebbe volerci un po ', potrebbe non arrivare affatto. Quindi un sonno è necessario per dare al tunnel un po 'di tempo per alzarsi e correre.

Quindi la domanda è: come posso verificare se il tunnel è attivo e funzionante? 10 secondi è un ritardo davvero indesiderato se il tunnel si alza subito. Idealmente, vorrei verificare se è attivo e continuare a creare l'oggetto telnet una volta, per un massimo di, ad esempio, 30 secondi.

Edit: Ping non mi aiuta Mouch, come la fine remota del tunnel è generalmente alto, ma con una quantità molto elevata di packetloss

risolto: Estrapolando dalla punta suggerito da mikebabcock , sleep 10 è stato sostituito con questo blocco, che funziona come un fascino:

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

Dato che stai usando il modulo 'Net :: Telnet', hai provato a usare la chiamata' open' e testare per il successo? Non sono un esperto di Telnet, ma è quello che probabilmente proverò se fossi io ... –

+0

Potrei farlo se non c'è un modo semplice di test: riprova fino al successo se time_spend_trying <30 secondi – Jarmund

risposta

6

Usa netcat - spesso nc su sistemi Linux:

nc -dvzw10 ${HOSTNAME} 23 

funziona per me, con una risposta del tipo:

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

Inoltre restituisce 0 in caso di successo, ed è felice con un semplice connessione dopo la quale va via.

  • -d significa non leggere nulla dal lato della tastiera
  • -v significa essere verbose (disattivare questo in uno script)
  • -z significa staccare dopo aver effettuato il collegamento
  • - w10 significa attendere fino a 10 secondi, altrimenti rinunciare a
0

è possibile integrare un ping al server SSH e se funziona bene il tunnel ssh è fino

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

forse è anche una buona idea mettere il ping in un ciclo – OkieOth

+0

ping non mi aiuta molto, come generalmente ha ~ 50% packetloss (questo è testato in anticipo, e ci crediate o no, è accettabile fino al 50%) – Jarmund

+0

ma esce con successo se il tunnel è attivo. La qualità fa parte di altri livelli di comunicazione – OkieOth

0

Penso che fping potrebbe essere migliore del solito ping, più script friendly.

fping -t 60000 [il server]

dovrebbe cercare di connettersi ai server di 60 secondi prima di rinunciare Qualcosa di simile

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

Penso che si ottiene l'idea, anche se la codifica non è vero.

Problemi correlati