Come posso SSH per lavorare A tramite B in un comando?


103

Voglio accedere a un computer, ad esempio la macchina A che si trova nella rete della mia università. Tuttavia, questo computer è accessibile solo tramite la rete interna dell'università, quindi non posso utilizzare SSH per questo computer direttamente da casa.

Ecco cosa faccio ora:

  1. Accedi a un'altra macchina universitaria, ad esempio macchina B

    (Questa macchina B è accessibile tramite SSH dal mio computer di casa.)

  2. Usa SSH su B per connetterti ad A.

C'è un modo per farlo più velocemente? Utilizzando solo un comando ssh.


Risposte:


97

Sì, usando ProxyCommandnella tua configurazione SSH.

Crea un file di configurazione SSH nella tua home directory (a meno che tu non voglia fare questo a livello di sistema) ~/.ssh/config,:

Host unibroker          # Machine B definition (the broker)
Hostname 12.34.45.56    # Change this IP address to the address of the broker
User myusername         # Change this default user accordingly 
                        # (`user@unibroker` can overwrite it)

Host internalmachine    # Machine A definition (the target host)
ProxyCommand ssh -q unibroker nc -q0 hostname.or.IP.address.internal.machine 22

Ora puoi raggiungere direttamente la Macchina A usando

ssh user@internalmachine

Nota anche che ora hai un solo nome target host SSH per questo, puoi usarlo anche in altre applicazioni. Per esempio:

  • SCP per copiare i file.

    scp somefile user@internalmachine:~/
    
  • Nelle tue applicazioni GUI:

    utilizzare sftp://user@internalmachine/come posizione per navigare sulla macchina.

    Basato su KDE (Dolphin): usare fish://user@internalmachine/

Appunti

Cambia hostname.or.IP.address.internal.machinee la porta ( 22) sulla macchina che desideri raggiungere come se dalla unibrokermacchina.

A seconda delle versioni di netcat sull'host unibroker, l' -q0opzione deve essere omessa. Per quanto riguarda l'autenticazione; stai fondamentalmente configurando due connessioni SSH dalla tua workstation. Ciò significa che sia l'host unibroker che l'host interno della macchina sono verificati / autenticati uno dopo l'altro (sia per la verifica della coppia di chiavi / password che per la chiave host).

Spiegazione

Questo approccio all'uso di ProxyCommand'netcat' è solo un modo per farlo. Mi piace questo, perché il mio client SSH parla direttamente con la macchina di destinazione in modo che io possa verificare la chiave host dal mio client e posso usare la mia autenticazione della chiave pubblica senza usare un'altra chiave sul broker.

Ciascuno Hostdefinisce l'inizio di una nuova sezione host. Hostnameè il nome host o l'indirizzo IP di destinazione di tale host. Userè ciò che forniresti come parte dell'utente ssh user@hostname.

ProxyCommandverrà utilizzato come pipe per la macchina target. Usando SSH per la prima macchina e impostando direttamente un semplice 'netcat' ( nc) sulla destinazione da lì, questo è fondamentalmente solo un semplice inoltro alla macchina interna dal broker tra quelli. Le -qopzioni sono di silenziare qualsiasi output (solo una preferenza personale).

Assicurati di avere netcat installato sul broker (generalmente disponibile di default su Ubuntu) - netcat-openbsdInstalla netcat-openbsd o netcat-tradizionaleInstalla netcat-tradizionale .

Nota che stai ancora usando SSH con crittografia due volte qui. Mentre il canale netcat è in chiaro, il tuo client SSH sul tuo PC imposterà un altro canale crittografato con il computer di destinazione finale.


4
Ho dovuto rimuovere l'opzione -q0 poiché non era supportata dalla macchina che stavo usando. A parte questo, ha funzionato tutto. Questo è un consiglio FANTASTICO. Grazie mille. :)
Gerry,

Ho riscontrato un problema, la tua risposta funziona bene per me dal terminale, ma non riesco a farlo usando la gui sftp, dice: messaggio di errore non gestito, scaduto durante il login.
Vikash B

@VikashB Beh, dovrebbe davvero funzionare. Valuta la possibilità di creare una NUOVA domanda per gestire la tua situazione specifica.
gertvdijk,

Ho fatto qui la domanda: askubuntu.com/questions/688567/…
Vikash B,

1
A complemento della saggia parola di @gertvdijk, c'è un fantastico wikibook sull'argomento dei proxy ssh e dei jump host che può servire come riferimento inestimabile.
Travis Clarke,

51

Salta in una volta sola

Un'ovvia alternativa all'approccio ProxyCommand che ho fornito nell'altra mia risposta sarebbe "saltare" direttamente alla macchina target:

ssh -t user@machineB ssh user@machineA

Nota -tsul primo sshcomando. Senza di essa, fallirà:

Pseudo-terminal will not be allocated because stdin is not a terminal.
ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory
Permission denied, please try again.
[...]

Costringerà un vero TTY da allocare

L'aspetto negativo di questo è che ora tutta la configurazione, la verifica e l'autenticazione avvengono presso la Macchina B, cosa che non mi piace davvero nella mia situazione per motivi di sicurezza. Mi piace la mia coppia di chiavi sul mio PC e autenticare e verificare la macchina di destinazione finale dal mio PC. Inoltre, puoi usare solo la shell interattiva per SSH, quindi questo non si occuperà di altri strumenti come SCP o usando il tuo file manager della GUI.

Per tutti i motivi sopra citati, consiglio vivamente l'approccio ProxyCommand , ma per una connessione rapida funziona perfettamente.


Perché non avere una risposta con entrambe le soluzioni "One Off" e permanenti?
esca il

5
@demure Ecco come funzionano i siti StackExchange ... Vedi: Qual è l'etichetta ufficiale nel rispondere a una domanda due volte? dice "È meglio pubblicare due risposte diverse, piuttosto che metterle in una risposta". . E non considero questa la stessa soluzione. Permanente / temporaneo non è ciò che rende questo approccio in modo diverso, secondo me.
gertvdijk,

Altre guide affermano di utilizzare, inoltre, l'opzione -A, ma indicano che ciò ha implicazioni per la sicurezza. Sai cosa significa inoltrare o meno la connessione dell'agente di autenticazione?
Diagon,

@gertvdijk super ninja qui! hai le DUE soluzioni migliori. non l'ho mai visto prima. super cool. molto meglio della creazione di una mega soluzione lunga con soluzioni N (che è quello che di solito vedo).
Trevor Boyd Smith,

Questo è molto più conveniente che impostare una configurazione che ostacolerà anche altri ssh.
Nikhil Sahu

37

È possibile utilizzare l' -Jopzione della riga di comando:

ssh -J user@machineB user@machineA

Da man ssh:

-J [user@]host[:port]
     Connect to the target host by first making a ssh connection to
     the jump host and then establishing a TCP forwarding to the
     ultimate destination from there.  Multiple jump hops may be
     specified separated by comma characters.  This is a shortcut to
     specify a ProxyJump configuration directive.

È stato introdotto in OpenSSH versione 7.3 (rilasciato nell'agosto 2016). È disponibile in Ubuntu 16.10 e versioni successive.


3
+1 perché funziona anche se è necessario specificare il file chiave per machineA
Grief

1
+1, questa è la versione migliore rispetto alla mia risposta ProxyCommand se tutti i tuoi host eseguono una versione OpenSSH abbastanza recente.
gertvdijk,

In questo caso il server OpenSSH dovrebbe essere installato su entrambe le macchine A e B? Ho capito bene?
Mikhail

17

Prova a usare

Host <visible hostname alias>
        Controlmaster auto
        User <user>
        hostname <visible hostname>
        port <port>
        IdentityFile ~/.ssh/<id file>

Host <private LAN hostname alias>
     ProxyCommand ssh -q -W <private LAN hostname>:<private LAN port> <visible hostname alias>

nella tua ~ / .ssh / config e fai tutto in una volta sola con i tasti che risiedono solo sul tuo computer.


1
Questo è più pulito dell'introduzione di netcat nel mix. Inoltre, la chiave SSH privata non deve necessariamente esistere sulla Bmacchina.
danemacmillan,

1

Questo è un suggerimento molto utile. Dopo aver fatto casino per ore, ho trovato questa nota e ho confermato che funziona esattamente come documentato. Per connettere tramite MachineA a MachineB, dalla macchina remota C:

es: [xuser @ machineC ~] ssh -t MachineA ssh MachineB

"-T" è critico, ssh fallisce se non è presente. Ti verrà richiesto due volte, prima per la password su MachineA, quindi per la seconda volta per MachineB. Si noti inoltre che ciò presuppone che l'utente "xuser" sia definito su tutte e tre le macchine. In caso contrario, basta usare la sintassi ssh: "yuser @ MachineA ...". Si noti inoltre che è possibile utilizzare IP # quad grezzi punteggiati, se lo si desidera. Ciò è utile se si collega tramite una rete locale privata che utilizza IP non esposti al mondo, ad es. non nel file host locale o alcun DNS. Per ottenere un file da MachineB, alla macchina remota C, è possibile passare da MachineB a MachineA, quindi da MachineA a macchinaC remota. (Ad es. La macchina remota C può eseguire il ping su MachineA, ma non su Machine B.) Avvertenza: ho testato con Fedora e WindowsXP, MachineA è una scatola XP con ICS (Condivisione connessione Internet), mentre MachineB e remote machineC sono scatole Fedora-Linux. Questo suggerimento ha risolto un problema chiave per me, vale a dire. accesso remoto limitato e monitorato al mio sito remoto lan. Nota anche che quando ti disconnetti da MachineB, dovresti vedere due "Connessione a xxx.xxx.xxx.xxx chiusa". messaggi.


Se si imposta e configura l'autenticazione con chiave pubblica, non è necessario preoccuparsi di immettere le password. Ma -tè ancora richiesto.
Felipe Alvarez,

@FelipeAlvarez Devi ancora preoccuparti di inserire la seconda password se non ti fidi della macchina B per accedere senza password ad A!
Michael,

1

ProxyCommand è una soluzione pulita per un caso in cui si consente l'accesso alla shell in entrambi i sistemi. Volevamo fornire agli utenti remoti l'accesso a una macchina interna (A) tramite un broker (B), ma senza consentire all'utente un accesso shell a B per una maggiore sicurezza. Questo ha funzionato:

Sostituisci la shell di accesso

Sostituisci la shell di accesso (usa chsh) per extusersul broker con il seguente script (memorizzato in un file):

#!/bin/sh   # this is essential to avoid Exec format error
ssh internaluser@A

A condizione che non sia stato impostato alcun accesso con password in extuser @ B per l'utente remoto e in internaluser @ A per extuser @ B, quindi l'esecuzione del comando seguente porterà l'utente remoto direttamente ad A

ssh extuser@B

Suggerimento : prima di passare alla shell di accesso personalizzata, creare la configurazione di password_utente abilitata per l'accesso senza password in extuser @ B. Dopo la modifica, poiché questo account è inaccessibile a chiunque tramite una shell, solo un sudoer @ B può apportare modifiche al file authorized_keys modificandolo direttamente.

sudo vi ~extuser/.ssh/authorized_keys
sudo touch ~extuser/.hushlogin

L'ultima riga consiste nel sopprimere la visualizzazione del banner di accesso da B, in modo che l'utente remoto abbia un accesso trasparente ad A.


Approccio molto interessante. Tuttavia, i principali svantaggi di questo sono: 1) L' uso è limitato all'utilizzo SSH standard (nessun supporto SFTP / SCP). 2) Un utente non può selezionare un altro host di destinazione diverso da quello singolo (perché codificato nella shell di login) 3) La convalida della chiave dell'host non può essere eseguita dalla workstation all'host di destinazione finale (poiché l'uso del binario SSH del broker) . 4) Le chiavi private per gli utenti per accedere all'host di destinazione finale risiedono sul broker anziché con l'utente. Ciò consente la rappresentazione dell'utente da parte di un amministratore (che non è possibile normalmente).
gertvdijk,

Tutto vero, grazie per l'elaborazione. Tuttavia, lo scopo principale è fornire a un utente attendibile l'accesso ssh ad A senza effettuare l'accesso a B. Poiché solo l'amministratore può aggiungere la chiave pubblica dell'utente attendibile su B (tramite sudo, senza accesso), ciò implica già che l'utente ha ( admin) accesso alla chiave privata di extuser @ B (non dell'utente fidato al di fuori), e l'ha impostata in primo luogo!
Sunthar,

1

Vuoi dire che hai bisogno di diversi jumper :)

Di recente, ho riscontrato questo problema con jumper1 jumper2 e la mia macchina finale, come per il mio sol

sceneggiatura locale:

#!/bin/bash
sshpass -p jumper1Passwd ssh -t jumper1@jumper1IP ./Y00.sh

poi sul primo jumper (che è il mio router), ho inserito uno script chiamato Y00.sh:

ssh -tt jumper2@jumper2 -i ~/.ssh/id_rsa sshpass -p finalPassWord ssh -tt final@final

Puoi sostituirli con il tuo IP e password, buona fortuna!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.