SSH od A do B do C, używając klucza prywatnego na B

59

Szukam prostej drogi do SSH z mojego komputera lokalnego, A, przez proxy, B, do hosta docelowego, C. Klucz prywatny, który idzie z kluczem publicznym na C, znajduje się na B i nie mogę umieść ten klucz na moim komputerze lokalnym. Jakieś wskazówki?

Chciałbym też móc to zrobić za pomocą ~ / .ssh / config.

Dzięki!

kowboj
źródło
1
Mówisz, że chcesz ssh z A do B, a następnie SSH do C? A może proxy jest prawdziwą sytuacją typu pass-thru?
cienkie
Chcę ssh z A do C, przechodząc przez B. Moja odpowiedź poniżej działa dla przechodzenia przez część, ale nadal próbuje szukać pliku tożsamości na moim komputerze lokalnym zamiast na B, hostu tranzytowym.
wrangler,

Odpowiedzi:

74

Schematyczny:

    ssh       ssh
A ------> B ------> C
    ^          ^
 using A's   using B's
 ssh key     ssh key

Warunki wstępne:

  • A działa ssh-agent;
  • Amoże uzyskać dostęp B;
  • Bmoże uzyskać dostęp C;
  • AKlucz publiczny ssh jest obecny w B:~/.ssh/authorized_keys
  • BKlucz publiczny ssh jest obecny w C:~/.ssh/authorized_keys

W ~/.ssh/configdniu A, dodać

Host C
    ProxyCommand ssh -o 'ForwardAgent yes' B 'ssh-add && nc %h %p'

Jeśli twój prywatny klucz ssh na B znajduje się w niestandardowej lokalizacji, dodaj jego ścieżkę po ssh-add.

Teraz powinno być w stanie uzyskać dostęp Cz A:

A$ ssh C
C$
Śnieżna kula
źródło
13
Zajęło to tylko 4 lata, ale wygląda na to, że mamy odpowiedź! Awesome
wrangler
3
Począwszy od openssh v.7.3, możesz po prostu użyć ProxyJump B. źródło: wikibooks
Keith,
2
Czy można to zdefiniować w taki sposób, że: Użytkownik hosta1 @ c ProxyCommand ssh -o 'ForwardAgent tak' użytkownik2 @ B 'ssh-add && nc% h% p'
Ravindranath Akila
2
Jak zmieni się rozwiązanie, jeśli komputer B nie ma nc?
mjalajel
1
@DrewVS Ok, trzeba dodać ForwardAgent yes przed tym ProxyJumppoleceniem.
Graipher,
22

Sprawdź, czy działa następujące.

ssh -t B ssh C

Użyj następującego polecenia, jeśli chcesz użyć klucza zapisanego na B.

ssh -t B ssh -i /path/to/identity_on_B C

Podajemy tutaj polecenie ssh -i /path/to/identity_on_B Cdo wykonania na B zamiast powłoki logowania.

Sachin Divekar
źródło
To działa, ale nie odbiera IdentityFile z B. Nadal wygląda na A.
wrangler
@DrewVS Zaktualizowałem odpowiedź. Sprawdź, czy to działa dla Ciebie.
Sachin Divekar,
Sachin, bardzo sprytny. To działało idealnie. Dzięki wielkie!
wrangler,
@DrewVS cieszę się, że działało dla Ciebie. więc proszę przyjąć odpowiedź.
Sachin Divekar,
Wygląda jednak na to, że nie działa to z kluczami RSA chronionymi hasłem. Wprowadzone hasło jest ukryte, zmuszając użytkownika do dodania klucza do klucza ssh, aby to podejście zadziałało. Jakieś pomysły?
wrangler,
10

Rozpracowałem to teraz. Oto rozwiązanie, które jest dość proste. Powinienem był to zobaczyć wcześniej:

~ / .ssh / config:

Host B
  HostName 1.2.3.4
  User myuser
  IdentityFile ~/.ssh/rsa_key
  ControlMaster auto
  ControlPath ~/.ssh/socket/master-%l-%r@%h:%p

Host C.*
  User customer_username
  Port customer_port
  IdentityFile remote/path/to/ssh/key
  ForwardAgent yes
  ProxyCommand ssh accessable.server nc %h %p

Host C.server-1
  HostName 2.3.4.5

„B” to serwer proxy, przez który przeskakujesz. Powinien być skonfigurowany tak, jak zwykle konfigurowałbyś dostęp do serwera.

„C” to host docelowy. Musi być skonfigurowany do używania „B” w procesie połączenia. Plik tożsamości w „C” jest ścieżką do klucza ssh w „B”. ProxyCommand używa Netcat do otwarcia połączenia z „C” z „B”. Netcat lub nc będzie musiał zostać zainstalowany na „B”.

Mam nadzieję, że to pomaga innym.

kowboj
źródło
3
Mówiłem za wcześnie. To rozwiązanie nie działa. Klucz został załadowany do agenta ssh, więc pomyślałem, że działa. W powyższym kluczu dla C nadal musi znajdować się na A, a nie na B.
wrangler
2

Napisałem prosty skrypt, aby w zasadzie wypisać moje klucze ssh w zdalnej instancji, a następnie dodać ten, który wybrałem do mojego lokalnego agenta ssh. To nie jest bardzo czyste, ale pozwala mi przechowywać wszystkie klucze w zdalnej lokalizacji, a nie lokalnie.

Oto skrypt, jeśli ktoś jest zainteresowany:

#!/usr/bin/ruby

require "rubygems"
require "fileutils"

# Get key list
key_list = (`ssh jumpbox "cd ~/.ssh/ ; ls id_rsa*" | sed 's/id_rsa_/  /g' | sed     's/id_rsa//g'`)
puts ' '
puts 'Available customer keys:'
puts key_list

# Get customer name input
puts ' '
puts 'Enter customer name: '
customer_name = gets.chomp

# Add key to ssh-agent
key_name = "~/.ssh/id_rsa_#{customer_name}"
puts ' '
puts "Adding #{key_name} to local ssh-agent"
`ssh jumpbox "ssh-add ~/.ssh/id_rsa_#{customer_name}"`
exit 0
kowboj
źródło
Myślę, że dodanie klucza może być traktowane jako idempotentne, co eliminuje potrzebę pobierania listy kluczy.
dmourati
Należy zaakceptować serverfault.com/a/701884/127993, który robi dokładnie to, co chcesz.
sjas
1
#!/usr/bin/env bash
target_host=10.121.77.16
target_port=22
target_user=vagrant

bastion_user=yourusername
bastion_host=10.23.85.245
bastion_port=32780

scp -P $target_port -o ProxyCommand="ssh -o 'ForwardAgent yes' $bastion_user@$bastion_host -p $bastion_port 'ssh-add ~/.ssh/*.rsa && nc %h %p'" /tmp/x.txt $target_user@$target_host:/tmp/
wcc526
źródło
1

Do zrobienia:

ssh someuser@IP_D

takie, że

A -> B-> C -> D gdzie A jest gospodarzem, na którym jesteś,

edytuj lokalną ~ / .ssh / config w następujący sposób:

Host IP_D
  ProxyCommand ssh -o 'ForwardAgent yes' userX@IP_C 'ssh-add && nc %h %p'
Host IP_C
  ProxyCommand ssh -o 'ForwardAgent yes' userY@IP_B 'ssh-add && nc %h %p'

Ta odpowiedź jest oparta na wybranej odpowiedzi. Musiałem dowiedzieć się, jak różni użytkownicy pasują do całego scenariusza.

To działa dla mnie. HTH.

Ravindranath Akila
źródło
0

Odpowiedź Snowball bardzo pomogła. Wprowadziłem jednak pewne zmiany w poleceniu i chciałem wyjaśnić, jak to działa. Biorąc pod uwagę tę sytuację:

    ssh        ssh
A -------> B -------> C
     ^          ^
  using A's  using B's
  ssh key    ssh key

Zmodyfikuj ~/.ssh/configplik i dodaj hosta, Bprzez który chcesz przeskoczyć, tak jak normalnie skonfigurujesz hosta:

Host B
 User myusername
 HostName b.mycompany.com

Następnie dodajesz hosta C, na którym chcesz skończyć:

Host C
 User myusername
 HostName c.intranet.mycompany.com
 ProxyCommand ssh -T -q -o 'ForwardAgent yes' B 'ssh-add -t 1 && nc %h %p'

Uwaga ProxyCommand, gdzie:

  • ssh -T -qwskazuje, że nie powinien przydzielać pseudo-TTY ( -T) i być cichym ( -q);
  • po przejściu do hosta skoku Bdodajemy klucz do kluczy SSH Aprzez ssh-add;
  • co działa tylko dlatego, że przekazaliśmy agenta SSH za pomocą -o 'ForwardAgent yes'.
  • ssh-add -t 1 wskazuje, że chcę, aby klucz został dodany tylko na 1 sekundę potrzebną do uwierzytelnienia na ostatecznym hoście C;
  • i na koniec nc %h %pinicjuje netcatpołączenie z hostem końcowym %hna porcie %p(oba zostaną wypełnione przez SSH na podstawie informacji zawartych w ~/.ssh/configpliku).

Jeśli musisz określić niestandardowy klucz Bdo użycia, możesz to zrobić, modyfikując ssh-addczęść:

Host C
 User myusername
 HostName c.intranet.mycompany.com
 ProxyCommand ssh -T -q -o 'ForwardAgent yes' B 'ssh-add -t 1 ~/.ssh/mykey && nc %h %p'
Daniel AA Pelsmaeker
źródło