Poczekaj, aż SSH zdoła utworzyć przekierowanie portów

7

Dzwonię do ssh (OpenSSH) z OSX / Linux-C ++ - aplikacji przez fork / exec, aby utworzyć dynamiczne przekierowanie portów. Robi się to za pomocą trybu wsadowego (-o BatchMode = yes) i klucza prywatnego, który jest dostarczany do ssh (-i Option). Samo wywołanie SSH nie otwiera powłoki (opcja -N).

To jest mój pełny SSH-Call:

ssh -N -D 9000 -o BatchMode=yes -i /path/to/private-key user@host

Chciałbym kontynuować moją aplikację tak szybko, jak to możliwe, i muszę się dowiedzieć, czy ssh udało się utworzyć kanał. Sam SSH powraca tylko wtedy, gdy ma problem.

Czy istnieje możliwość wykrycia udanego przekierowania portów?

Oczywiście mogę poczekać, aż port zostanie otwarty przez SSH, ale szukam bardziej eleganckiego rozwiązania. Innym rozwiązaniem jest sprawdzenie Logu SSH (-v) czekającego na „Wprowadzanie interaktywnej sesji”, ale brzmi to dla mnie mało przenośnie.

nob
źródło

Odpowiedzi:

4

Użyj -f opcja i ssh przejdzie do tła (tj. fork i wyjdź w procesie macierzystym), więc możesz po prostu waitpid dla oryginału ssh aby zakończyć, a następnie wiesz (na podstawie statusu wyjścia), że połączenie nie powiodło się lub przekierowanie portu jest już skonfigurowane.

R..
źródło
1
To brzmi dobrze. Ale teraz miałbym problem z tym, że nie mogę znaleźć PID rozwidlonego procesu SSH i dlatego nie mogę go łatwo oczyścić po zakończeniu programu. Jest dyskusja na temat Bugzilli Debiana: bugzilla.mindrot.org/show_bug.cgi?id=1473 Jedyną szansą, jaką widzę, aby użyć go w połączeniu z -f, jest użycie ControlMaster / Slave-Communication.
1
@nob możesz sygnalizować wnukowi za pomocą grup procesów. Zasadniczo, gdy aplikacja przesyła do exec ssh, proces potomny powinien stać się liderem grupy procesów przed wywołaniem exec. Tutaj jest przykładem w perlu robienia tego.
Kenster
Grupy procesowe brzmią jak najlepsze rozwiązanie, ale możliwe jest również, aby proces ssh umarł, gdy dana rura lub gniazdo zostaną zamknięte przez proces.
R..
@ Kenster Dzięki Spróbuję tego.
nob
1

Myślę, że znalazłem inne (także hackish) rozwiązanie. Podczas uruchamiania SSH z

ssh -S /some/domain/socket -M ...args... host

stworzy gniazdo domeny kontrolnej tylko wtedy, gdy pomyślnie ustanowi połączenie. Musiałbym więc poczekać, aż gniazdo domeny pojawi się w systemie plików. Nadal nie jest piękny, ale brzmi to bardziej solidnie niż oczekiwanie na pojawienie się gniazda sieciowego.

Co ciekawe, można to również wykorzystać do znalezienia PID Mistrza (patrz Odpowiedź R). Za pomocą

$ ssh -S /some/domain/socket -O check host
Master running (pid=25503)
nob
źródło