2009-09-10 10 views
46

Jestem w trakcie tworzenia skryptu bash, który będzie logował się do komputerów zdalnych i tworzy klucze prywatne i publiczne.Jak utworzyć skrypt bash, aby sprawdzić połączenie SSH?

Mój problem polega na tym, że zdalne maszyny nie są niezawodne i nie zawsze są w górze. Potrzebuję skryptu bash, który sprawdzi, czy połączenie SSH jest włączone. Przed faktycznym utworzeniem kluczy do przyszłego użytku.

+2

Zazwyczaj uruchamia się 'ssh-keygen', aby wygenerować parę kluczy na komputerze lokalnym, a następnie' ssh-copy-id', aby skopiować klucz publiczny do komputerów zdalnych. Wygląda na to, że robisz coś inaczej. Dlaczego, jaki jest twój cel? – ephemient

+1

Ponieważ w oczywisty sposób zmieniasz sposób, w jaki odległe komputery nawiązują połączenia, rozważ wdrażanie * mosh *. http://mosh.mit.edu/ Jest przeznaczony do uzupełniania SSH na niestabilnych połączeniach. Mam z tym bardzo dobre doświadczenia. – Aeyoun

Odpowiedz

92

Można to sprawdzić za zwrot wartości ssh daje:

$ ssh -q [email protected] exit 
$ echo $? 
255 

$ ssh -q [email protected] exit 
$ echo $? 
0 

EDIT: Inne podejście byłoby użyć nmap (nie trzeba mieć klucze lub login-rzeczy):

$ a=`nmap uphost -PN -p ssh | grep open` 
$ b=`nmap downhost -PN -p ssh | grep open` 

$ echo $a 
22/tcp open ssh 
$ echo $b 
(empty string) 

Ale musisz wysłać wiadomość (nmap nie używa wartości zwracanej, aby pokazać, czy port został przefiltrowany, zamknięty czy otwarty).

EDIT2:

Jeśli jesteś zainteresowany rzeczywistego stanu ssh-portu, można zastąpić grep open z egrep 'open|closed|filtered':

$ nmap host -PN -p ssh | egrep 'open|closed|filtered' 

Wystarczy być kompletne.

+0

Aby być kompletnym, czy możesz wskazać, który kod powrotu oznacza sukces, a co oznacza brak SSH? –

+0

Zastanawiasz się, co jeśli próba SSH po prostu się zawiesi? –

+1

Świetna odpowiedź! Nie wspominasz jednak, że próba wprowadzenia 'ssh' na hoście down kończy się niepowodzeniem dopiero po przekroczeniu limitu czasu np.60 sekund - co może być zaporowe dla niektórych zastosowań. Ponadto, jeśli nazwa hosta jest zdefiniowana w '~/.ssh/config', pierwsze podejście' ssh' działa podczas gdy druga metoda 'nmap' nie powiedzie się z' Nie udało się rozwiązać "". – ssc

-2

Czuję, że próbujesz rozwiązać niewłaściwy problem. Czy nie powinieneś próbować uczynić demonów ssh bardziej stabilnymi? Spróbuj uruchomić coś w rodzaju monit, które sprawdzi, czy demon jest uruchomiony, i zrestartuj go, jeśli tak nie jest (dając ci czas na odnalezienie głównego problemu za zamknięciem sshd). A może usługa sieciowa jest kłopotliwa? Spróbuj spojrzeć na man ifup. Czy The Whole Damn Thing po prostu chce cię zamknąć? Cóż, to większy problem ... spróbuj spojrzeć na swoje logi (zacznij od syslog), aby znaleźć awarie sprzętu lub usługi, które zamykają twój boxen (może monitor temperatury?).

Uczynienie skryptów odpornymi na błędy jest świetne, ale możesz również chcieć, aby twoja odporność na błędy była tolerancyjna.

+2

Sam: istnieją ważne przypadki użycia, aby skrypt mógł to sprawdzić. E.g (podobnie jak ja): Mam zadanie cron uruchomione na moim komputerze, aby wykonać kopię moich danych przez rsync do mojego domu nas. Teraz jestem często na zewnątrz lub nawet rozłączony i muszę zmienić harmonogram, jeśli połączenie nie było dostępne. Mój boxen działa całkiem nieźle, ale jak to się mówi: to zawsze jest kabel (aka network) – stwissel

2

Spróbuj:

echo quit | telnet IP 22 2>/dev/null | grep Connected 
+1

Problemem tego podejścia jest to, że nie rozpoznaje hostów zdefiniowanych w ssh_config (tj./Etc/ssh/config lub ~/.ssh/config) –

16
ssh -q -o "BatchMode=yes" -i /home/sicmapp/.ssh/id_rsa <ID>@<Servername>.<domain> "echo 2>&1" && echo $host SSH_OK || echo $host SSH_NOK 
+1

Jedno wyjście liniowe: (ssh -q -o "BatchMode = yes" -o "ConnectTimeout = 3" [email protected] "echo 2> & 1" && echo SSH_OK || echo SSH_NOK) | ogon -n1 – Xdg

11

Można użyć coś takiego

$(ssh -o BatchMode=yes -o ConnectTimeout=5 [email protected] echo ok 2>&1) 

Wyjście wola "ok", jeśli połączenie ssh jest ok

4

Uzupełniając odpowiedź @Adrià Cidre ty może zrobić:

status=$(ssh -o BatchMode=yes -o ConnectTimeout=5 [email protected] echo ok 2>&1) 

if [[ $status == ok ]] ; then 
    echo auth ok, do something 
elif [[ $status == "Permission denied"* ]] ; then 
    echo no_auth 
else 
    echo other_error 
fi 
Powiązane problemy