Jak skonfigurować skrót dla połączenia SSH przez tunel SSH

22

Serwery produkcyjne mojej firmy (FOO, BAR ...) znajdują się za dwoma serwerami bram (A, B). Aby połączyć się z serwerem FOO, muszę otworzyć połączenie ssh z serwerem A lub B z moją nazwą użytkownika JOHNDOE, a następnie z A (lub B) mogę uzyskać dostęp do dowolnego serwera produkcyjnego otwierającego połączenie SSH ze standardową nazwą użytkownika (nazwijmy to WEBBY).

Więc za każdym razem muszę zrobić coś takiego:

ssh johndoe@a
...
ssh webby@foo
...
# now I can work on the server

Jak możesz sobie wyobrazić, jest to kłopotliwe, gdy muszę użyć scplub szybko otworzyć wiele połączeń.

Skonfigurowałem klucz ssh, a także używam .ssh / config dla niektórych skrótów.

Zastanawiałem się, czy mogę stworzyć jakąś konfigurację ssh w celu pisania

ssh foo

i pozwól SSH otworzyć / przekazać wszystkie połączenia dla mnie. Czy to możliwe?

Edytować

Odpowiedź womble jest dokładnie tym, czego szukałam, ale wydaje się, że w tej chwili nie mogę użyć netcata, ponieważ nie jest zainstalowany na serwerze bramy.

weppos:~ weppos$ ssh foo -vv
OpenSSH_5.1p1, OpenSSL 0.9.7l 28 Sep 2006
debug1: Reading configuration data /Users/xyz/.ssh/config
debug1: Applying options for foo
debug1: Reading configuration data /etc/ssh_config
debug2: ssh_connect: needpriv 0
debug1: Executing proxy command: exec ssh a nc -w 3 foo 22
debug1: permanently_drop_suid: 501
debug1: identity file /Users/xyz/.ssh/identity type -1
debug2: key_type_from_name: unknown key type '-----BEGIN'
debug2: key_type_from_name: unknown key type 'Proc-Type:'
debug2: key_type_from_name: unknown key type 'DEK-Info:'
debug2: key_type_from_name: unknown key type '-----END'
debug1: identity file /Users/xyz/.ssh/id_rsa type 1
debug2: key_type_from_name: unknown key type '-----BEGIN'
debug2: key_type_from_name: unknown key type 'Proc-Type:'
debug2: key_type_from_name: unknown key type 'DEK-Info:'
debug2: key_type_from_name: unknown key type '-----END'
debug1: identity file /Users/xyz/.ssh/id_dsa type 2
bash: nc: command not found
ssh_exchange_identification: Connection closed by remote host
Simone Carletti
źródło

Odpowiedzi:

36

Jako bardziej konkretną wersję odpowiedzi Kyle'a, chcesz umieścić w swoim ~/.ssh/configpliku:

host foo
  User webby
  ProxyCommand ssh a nc -w 3 %h %p

host a
  User johndoe

Następnie, kiedy uruchomisz „ssh foo”, SSH spróbuje SSH do johndoe@a, run netcat( nc), a następnie wykona SSH do webby@footego tunelu. Magia!

Oczywiście, aby to zrobić, Netcat musi być zainstalowany na serwerze bramy; ten pakiet jest dostępny dla każdej dużej dystrybucji i systemu operacyjnego.

womble
źródło
Doskonały! Próbowałem to rozgryźć, nigdy wcześniej nie spotkałem się z taką sytuacją. Zachowam tam swoją odpowiedź, na wypadek, gdyby to pomogło komuś z mniej konkretną sytuacją w przyszłości.
Kyle Brandt,
Zaktualizowałem swoje pierwotne pytanie, w tym pełne dane wyjściowe mojego połączenia. Wygląda na to, że nie mogę używać NetCat. Czy powinien być domyślnie dostępny?
Simone Carletti
Nie zawsze, czy masz moc, aby go zainstalować? Możesz być w stanie to zrobić również za pomocą telnetu, nigdy tego nie próbowałem ...
Kyle Brandt
Możesz także być w stanie pobrać netcat do swojego katalogu domowego i tam go skompilować. Następnie możesz po prostu użyć pełnej ścieżki w poleceniu proxy, tj. / Home / nazwa_użytkownika / bin / nc
Kyle Brandt
Właśnie sprawdziłem ustawienia systemowe. Na Ubuntu netcat wydaje się być domyślnie dostępny, niestety serwery bram są zasilane przez OpenSUSE. Zastanowię się również nad zainstalowaniem netcata na serwerach bramy.
Simone Carletti
7

Możesz użyć dyrektywy ProxyCommand w pliku ~ / .ssh / config, na przykład aby użyć netcat jako przekaźnika:

host server2
    ProxyCommand ssh server1 nc server2 22

Po prostu użyłbyś „ssh server2”. Informacje o stronie podręcznika dla tej dyrektywy znajdują się w 'man ssh_config'

Kyle Brandt
źródło
5

Wolę inne podejście, które utrzymuje wstępnie uwierzytelniony tunel do serwera bramy. W ~/.ssh/config:

Host a
    ControlMaster auto
    ControlPath ~/.ssh/control-master/%r@%h:%p

Następnie w .bashrc:

s () {
        if ( ssh -O check a 2>&1 > /dev/null 2>&1 )
        then
                ssh -t a ssh $1
        else
                if [[ -S ~/.ssh/control-master/insyte@a:22 ]]
                then
                        echo "Deleting stale socket..."
                        rm ~/.ssh/control-master/insyte@a:22
                fi
                echo "Opening master session..."
                if ssh -Nf a
                then
                         ssh -t a ssh $1
                fi
        fi
 }

Aby połączyć się z foo:

s foo

Przy pierwszym podłączeniu uwierzytelni cię przed „a” i otworzy trwały tunel ssh w tle. Kolejne wywołania „s” otworzą się niemal natychmiast przez wstępnie autostabilny tunel.

Działa świetnie.

Insyte
źródło
2

Ten typ funkcjonalności istnieje w nowszych wersjach OpenSSH i można z niego korzystać poprzez wykonanie

ssh -W server2 server1

Gdzie server2jest zamierzonym miejscem docelowym i server1hostem proxy. Możesz to ułatwić, korzystając z ProxyCommandopcji w konfiguracji ssh, na przykład:

host = *.example.com
user = packs
port = 22
ProxyCommand ssh -W %h:%p server1
Scott Pack
źródło
Wydaje się, że aby to zadziałało, potrzebujesz OpenSSH 5.4+ we wszystkich trzech lokalizacjach: komputer, pośrednik, miejsce docelowe. (Cóż, pierwszy i ostatni, z pewnością).
Steve Bennett,
@ SteveBennett: Używam tej metody od jakiegoś czasu, działa całkiem dobrze. Musiałem wrócić do metody netcat na kilku systemach RHEL5, co było denerwujące.
Scott Pack,
2

Jeśli netcatnie jest dostępny w proxy, wypróbuj tę sztuczkę:

host foo
  User webby      
  ProxyCommand ssh a 'exec 3<>/dev/tcp/foo/22; cat <&3 & cat >&3;kill $!'

host a
  User johndoe

Więc powinieneś być w stanie ssh foo.

Ponadto, jeśli masz najnowszą wersję ssh na a (tj. Z -Wkomendą do przekazywania standardowych danych wejściowych i wyjściowych), możesz użyć:

host foo
  User webby
  ProxyCommand ssh -W foo:%p a

host a
  User johndoe

Wreszcie, tylko dlatego, że uznałem to za fajne (a nie dlatego, że będzie działać w twoim konkretnym przypadku, z powodu różnic w nazwach użytkowników), post na blogu znajomego wskazuje, jak zrobić tego rodzaju dynamikę i rekurencyjnie łączyć łańcuchy proxy SSH (wraz z niektórymi rzeczami które nie działają dobrze):

host */*
  ProxyCommand ssh ${$(dirname %h)/\%%/@} nc ${$(basename %h)#*%%} %p

A potem ssh machine1/machine2powinien dać ci pocisk na machine2tunelu machine1.

Zastanawiam się, czy używanie niestandardowych sedpoleceń zamiast dirnamei basenamemoże nie rozwiązać problemu z różnymi nazwami użytkowników?

Paul Price
źródło
2

Można to osiągnąć przez wykonanie ssh -At johndoe@a ssh webby@foo. -AKomenda do przodu agent ssh (dzięki czemu można uniknąć konieczności ponownego uwierzytelnienia na serwerze proxy), natomiast -tzapewnia zacisk istnieje na pełnomocnika. Przydatna może być następująca funkcja bash:

ssh-bounce () {
    local cmd=""
    for i in "$@"; do
        cmd+="ssh -At $i "
    done
    $cmd
}
Marcin
źródło
To zdecydowanie najprostsze rozwiązanie. Teraz potrzebuje tylko 35 pozytywnych opinii. (Przy okazji -A nic dla mnie nie robi.)
Steve Bennett,
0
weppos:~ weppos$ ssh foo -vv
[..]
bash: nc: command not found

Netcat nie jest zainstalowany a. Po uruchomieniu ssh host "command arg", commandwykonywany jest na host, a nie na komputerze lokalnym.

markdrayton
źródło
Tak, wiem. Właśnie to zgłosiłem w komentarzu do odpowiedzi womble. :)
Simone Carletti
0

Od OpenSSH 7.3 (2016-08-01) ProxyJumpdostępna jest opcja i odpowiednia -Jflaga wiersza poleceń, aby umożliwić prostszą pośrednią transmisję przez jeden lub więcej bastionów SSH lub „hostów skokowych”.

To usuwa zależność od zewnętrznego ncpolecenia, jak znaleziono w rozwiązaniu Womble .

ssh -J johndoe@a webby@foo 

ustanowi połączenie SSH ze stacji roboczej do serwera bramy ajako użytkownik johndoe i tuneluje sesję SSH, aby hostować foo dla użytkownika Webby.

Aby to uprościć, utwórz definicje hosta zarówno dla siebie, jak ~/.ssh/configi dla tego, które możesz wykonaćssh foo

Host a
    User johndoe

Host foo
    User Webby 
    ProxyJump a
HBruijn
źródło