SSH von A über B nach C mit privatem Schlüssel auf B


59

Ich suche nach einer einfachen Möglichkeit, SSH von meinem lokalen Computer A über einen Proxy B zu einem Zielhost C. Der private Schlüssel, der mit dem öffentlichen Schlüssel auf C verbunden ist, ist auf B, und ich kann nicht Lege diesen Schlüssel auf meinen lokalen Computer. Irgendwelche Tipps?

Außerdem möchte ich in der Lage sein, dies mit ~ / .ssh / config zu tun.

Vielen Dank!


1
Wollen Sie von A nach B und dann von SSH nach C ssh? Oder ist Proxy eine echte Pass-Through-Situation?
Thinice

Ich möchte von A nach C ssh, indem ich durch B gehe. Meine Antwort unten funktioniert für den Durchgangsteil, aber es wird weiterhin versucht, auf meinem lokalen Computer nach der Identitätsdatei zu suchen, anstatt auf B, dem Durchgangshost.
Wrangler

Antworten:


74

Schema:

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

Voraussetzungen:

  • A läuft ssh-agent;
  • Azugreifen können B;
  • Bzugreifen können C;
  • Assh public key ist in vorhanden B:~/.ssh/authorized_keys
  • Bssh public key ist in vorhanden C:~/.ssh/authorized_keys

In ~/.ssh/configauf A, fügen

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

Wenn sich Ihr privater SSH-Schlüssel auf B an einem nicht standardmäßigen Speicherort befindet, fügen Sie den Pfad danach hinzu ssh-add.

Sie sollten nun in der Lage sein , den Zugriff auf Cvon A:

A$ ssh C
C$

13
Es hat nur 4 Jahre gedauert, aber anscheinend haben wir eine Antwort! Super
Wrangler

3
Ab openssh v.7.3 können Sie einfach verwenden ProxyJump B. Quelle: Wikibooks
Keith

2
Kann dies so definiert werden, dass: Host user1 @ c ProxyCommand ssh -o 'ForwardAgent yes' user2 @ B 'ssh-add &&nc% h% p'
Ravindranath Akila

2
Wie würde sich die Lösung ändern, wenn Maschine B keine hat nc?
mjalajel

1
@DrewVS Ok, man muss ForwardAgent yes vor dem ProxyJumpBefehl hinzufügen .
Graipher

22

Überprüfen Sie, ob Folgendes funktioniert.

ssh -t B ssh C

Verwenden Sie den folgenden Befehl, wenn Sie den auf B gespeicherten Schlüssel verwenden möchten.

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

Hier geben wir den Befehl ssh -i /path/to/identity_on_B Can, der auf B anstelle einer Login-Shell ausgeführt werden soll.


Dies funktioniert, holt aber nicht die IdentityFile von B ab. Es sieht immer noch nach A.
wrangler aus.

@DrewVS Ich habe die Antwort aktualisiert. Bitte überprüfen Sie, ob es für Sie funktioniert.
Sachin Divekar

Sachin, sehr schlau. Das hat einwandfrei funktioniert. Vielen Dank!
Wrangler

@DrewVS freut sich zu hören, dass es für Sie funktioniert hat. Bitte akzeptieren Sie die Antwort.
Sachin Divekar

Es sieht jedoch so aus, als würde dies mit passwortgeschützten RSA-Schlüsseln nicht funktionieren. Die Passworteingabe ist ausgeblendet, sodass der Benutzer den Schlüssel zu seinem SSH-Schlüssel hinzufügen muss, damit dieser Ansatz funktioniert. Irgendwelche Ideen?
Wrangler

10

Ich habe das jetzt ausgearbeitet. Hier ist die Lösung, die ziemlich einfach ist. Ich hätte es früher sehen sollen:

~ / .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' ist der Proxy-Server, durch den Sie springen. Es sollte so konfiguriert werden, wie Sie normalerweise den Zugriff auf einen Server konfigurieren würden.

'C' ist der Zielhost. Es muss so konfiguriert sein, dass 'B' im Verbindungsprozess verwendet wird. Die Identitätsdatei in 'C' ist der Pfad zum SSH-Schlüssel in 'B'. Der ProxyCommand verwendet Netcat, um die Verbindung zu 'C' von 'B' aus zu öffnen. Netcat oder nc muss auf 'B' installiert sein.

Hoffe das hilft anderen.


3
Ich habe zu früh gesprochen. Diese Lösung funktioniert nicht. Der Schlüssel war in den ssh-agent geladen worden, also dachte ich, dass es funktioniert. In der oben muss der Schlüssel für C noch auf A sein, nicht B.
wrangler

2

Ich habe ein einfaches Skript geschrieben, um im Grunde genommen meine SSH-Schlüssel auf der Remote-Instanz aufzulisten und dann den ausgewählten zu meinem lokalen SSH-Agenten hinzuzufügen. Das ist nicht sehr sauber, aber ich kann alle Schlüssel an einem entfernten Ort anstatt vor Ort aufbewahren.

Hier ist das Skript, wenn jemand interessiert ist:

#!/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

Ich denke, das Hinzufügen eines Schlüssels kann als idempotent behandelt werden, wodurch die Notwendigkeit beseitigt wird, eine Schlüsselliste zu erhalten.
Dmourati

Sie sollten serverfault.com/a/701884/127993 akzeptieren, das genau das tut, was Sie wollen.
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/

1

Machen:

ssh someuser@IP_D

so dass

A -> B-> C -> D wo A der Host ist, auf dem Sie sich befinden,

Bearbeiten Sie Ihre lokale ~ / .ssh / config wie folgt:

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'

Diese Antwort basiert auf der gewählten Antwort. Ich musste herausfinden, wie verschiedene Benutzer in das gesamte Szenario passen.

Das funktioniert bei mir. HTH.


0

Schneeballs Antwort hat mir sehr geholfen. Ich habe jedoch einige Änderungen am Befehl vorgenommen und wollte erklären, wie es funktioniert. In dieser Situation:

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

Ändern Sie Ihre ~/.ssh/configDatei und fügen Sie den Host hinzu, Büber den Sie springen möchten, genau wie Sie normalerweise einen Host konfigurieren würden:

Host B
 User myusername
 HostName b.mycompany.com

Dann fügen Sie den Host hinzu C, auf dem Sie landen möchten:

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

Beachten Sie ProxyCommand, wo:

  • ssh -T -qgibt an, dass kein Pseudo-TTY zugewiesen werden soll ( -T) und dass es ruhig sein soll ( -q);
  • Sobald Bwir uns auf dem Sprunghost befinden , fügen wir den Schlüssel zu den SSH-Schlüsseln von Athrough hinzu ssh-add.
  • Das funktioniert nur, weil wir den SSH-Agenten mit weitergeleitet haben -o 'ForwardAgent yes'.
  • ssh-add -t 1 gibt an, dass der Schlüssel nur für die 1 Sekunde hinzugefügt werden soll, die für die Authentifizierung beim endgültigen Host C erforderlich ist.
  • und nc %h %pinitiiert schließlich eine netcatVerbindung zum endgültigen Host %ham Port %p(beides wird von SSH basierend auf den Informationen in der ~/.ssh/configDatei ausgefüllt ).

Wenn Sie einen benutzerdefinierten Schlüssel für Bdie Verwendung angeben müssen , können Sie dies tun, indem Sie das ssh-addTeil ändern :

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'
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.