Dynamicznie generuj wpisy hosta SSH w ~ / .ssh / config

9

Muszę zarządzać całym stosem hostów przez ssh. Jednak mogę uzyskać do nich dostęp tylko przez określony serwer ssh bramy.

Mam w swoim ~/.ssh/config:

Host mygateway-www
Hostname www
IdentityFile ~/.ssh/id_rsa
ProxyCommand ssh mygateway nc %h 22

Jednak muszę połączyć się z wieloma z tych maszyn. Czy zamiast wstawiać do mnie dziesiątki wpisów ~/.ssh/config, mogę mieć coś takiego:

Host mygateway-*
Hostname ???WHAT GOES HERE????
IdentityFile ~/.ssh/id_rsa
ProxyCommand ssh mygateway nc %h 22

Wiem, że można używać %hw Hostnameargumencie, ale to byłaby nazwa hosta. To, czego naprawdę potrzebuję, to pewnego rodzaju podstawienie łańcucha, takie jak bash ${VAR%thingie}. czy to możliwe?

Rory
źródło

Odpowiedzi:

24

Można to zrobić za pomocą następującego pliku konfiguracyjnego SSH:

Host *
  ServerAliveInterval 120

Host gateway.somewhere.com
  User jdoe

Host gateway+*
  User jdoe
  ProxyCommand ssh -T -a $(echo %h |cut -d+ -f1).somewhere.com nc $(echo %h |cut -d+ -f2) %p 2>/dev/null
  ControlMaster auto
  ControlPath ~/.ssh/ssh-control_%r@%h:%p

Następnie uzyskujesz dostęp do swoich wewnętrznych hostów w następujący sposób:

ssh gateway+internalhost01.somewhere.com
ssh gateway+internalhost02.somewhere.com

Nazwa wybrana dla prawej połowy powinna być rozpoznawalna przez gospodarza skoku.

Parametr Użytkownik jest określany na wypadek konieczności ręcznego mapowania różnych użytkowników na różnych klasach hostów. Określono ControlMaster i ControlPath, aby umożliwić ponowne użycie połączenia SSH.

Copperlight
źródło
6

Nie trzeba ręcznie określać nazwy hosta, ponieważ będzie ona pochodzić z wiersza polecenia.

Po prostu spróbuj:

Host *.domain  
  IdentityFile ~/.ssh/id_rsa  
  ProxyCommand ssh mygateway /usr/bin/nc %h 22
Dan Carley
źródło
Problem z tym podejściem polega na tym, że nazwa hosta jest dość ogólna (np. Db1, www, mail2), podczas gdy ja chcę, aby były one również poprzedzone projektem, ponieważ może być konieczne ssh na innym komputerze o nazwie „db2”. Stąd prefiks w hoście
Rory
2
Tak naprawdę chcesz ponownie skonfigurować DNS. Najprostszym (ale najbardziej kłopotliwym rozwiązaniem) jest zmodyfikowanie pliku hosts. Z drugiej strony możesz zawsze dodać lokalny serwer DNS do swojej stacji roboczej z domeną .invalid i użyć preferowanych nazw hostów.
Martin M.
+1 poprzedni. Utwórz poddomenę dla każdego projektu. DNS ma ułatwić ci życie;)
Dan Carley
1

Wygląda na to, że nie ma na to sposobu.

Rory
źródło
1

Miałem podobny problem i ostatecznie napisałem skrypt, który wygenerował dla mnie cały szablon. Nie zmieniam już ~ / ssh / config, zmieniam ~ / ssh / config.in i ponownie uruchamiam skrypt.

Michael Hoffman
źródło
1
Chcesz udostępnić swój skrypt? Myślałem o zrobieniu tego, ale wydaje się, że solidne i ogólne rozwiązanie może zająć dużo pracy. Nawet jeśli twoje rozwiązanie nie jest jeszcze takie, dobrze byłoby wiedzieć, co według ciebie jest właściwe i co zrobiłbyś inaczej, gdybyś to zrobił.
iconoclast
Miałem na myśli .ssh/config.dplik z każdym szablonem, w którym każdy szablon wygenerowałby jeden lub więcej wpisów w końcowej wersji ~/.ssh/config. Byłby też plik ze zmiennymi uniwersalnymi, ale każdy szablon mógłby mieć swoje własne zmienne, które miałyby pierwszeństwo przed globalnymi, wymienione na górze. ~/.ssh/configPlik może zostać wygenerowany na żądanie lub według harmonogramu, to nie kwestia, jak długo nigdy dokonane zmiany bezpośrednie do niej, że chce zachować.
iconoclast
Mój skrypt jest całkowicie nieudokumentowany i nie sądzę, że byłby zrozumiały bez dokumentacji lub przykładów, których nie mam czasu stworzyć.
Michael Hoffman
Zrozumiale. Wszelkie informacje zwrotne na temat podejścia, które przedstawiłem, byłyby mile widziane, zwłaszcza jeśli pomijam jakieś ważne potrzeby lub przypadki użycia lub też duże (lub małe) przeszkody.
iconoclast
1
Myślę, że to dobre podejście, prawdopodobnie trochę mniej mylące niż podejście, które zastosowałem. Wczytałem do pamięci szereg deklaracji hosta, a następnie kilka deklaracji innych niż host. Deklaracje inne niż host są stosowane do każdego hosta w bieżącej grupie, dopóki nie pojawi się inny host. Zezwalam również na wielokrotne deklarowanie hostów w pliku, w tym za pomocą globowania. Na koniec spisuję wszystko, co budowałem w pamięci.
Michael Hoffman,
1

Zignoruj ​​określenie Hostnamezastąpienia nazwy hosta bezpośrednio za pomocą deklaracji i zamiast tego określ ją w czasie wykonywania. Zrób to, oceniając go jako część ProxyCommand, używając %hdo odwołania go w poleceniu (użyj również %pzamiast portu na stałe jako 22), tj.

Host mygateway-*
   #Hostname ???WHAT GOES HERE????
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh mygateway nc $(echo %h|sed 's/^mygateway-//') %p

Można nawet zastosować bardziej ogólną zwrotkę, w której można określić dowolny host bez -konieczności traktowania go takim, jaki jest, lub zgodnie z inną pasującą zwrotką, ale zastosować ogólne -podejście do określenia dowolnej <gateway>-<target>:

Host *-*
   # Assume LHS of "-" is GW and RHS of "-" is target host
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh $(echo %h|cut -d - -f1) nc $(echo %h|cut -d - -f2-) %p

Ponadto nowsze wersje klienta SSH obsługują [-W host:port]opcję bezpośredniego wykonywania tej samej funkcji co nc(netcat). W związku z tym możemy użyć zmodyfikowanego:

Host *-*
   # Assume LHS of "-" is GW and RHS of "-" is target host
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh -W $(echo %h|cut -d - -f2-):%p $(echo %h|cut -d - -f1)

Oczywiście, jeśli masz skończoną listę hostów, zawsze możesz:

Host host1 host2 host3 hostN
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh mygateway nc %h %p

Mam nadzieję że to pomoże!

Taz
źródło
0

Miałem klienta z tą samą konfiguracją i użyłem DSSH do rozwiązania mojego problemu.
DSSH pozwala między innymi na przezroczyste logowanie do hostów zdalnych za pośrednictwem hosta bramy.

Przypadków użycia

  • Zbierz parametry konfiguracyjne z routerów Cisco, które wymagają logowania „ena”
  • Zaloguj się do serwerów, na których PermitRootLogin jest wyłączony bezpośrednio jako root (wpisując su - i hasło automatycznie), zachowując status wyjścia
  • Dodaj niestandardową logikę, taką jak zaawansowane rejestrowanie
  • tuneluj przez kilka połączeń, aby dostać się do serwera docelowego
aussielunix
źródło
5
Wolę nie zaczynać używać losowego klienta ssh innej firmy, który używa java, do rzeczy, które mogę zrobić w ~ / .ssh / config.
Rory
link nie działa
iconoclast
Źródło oprogramowania można znaleźć na Github: github.com/digmia/dssh
Gość