Come funziona il tunneling SSH inverso?


350

A quanto ho capito, i firewall (presupponendo le impostazioni predefinite) negano tutto il traffico in entrata che non ha traffico in uscita corrispondente precedente.

Basato sull'inversione di una connessione ssh e sul tunneling SSH reso semplice , il tunneling SSH inverso può essere utilizzato per aggirare le fastidiose restrizioni del firewall.

Vorrei eseguire i comandi di shell su una macchina remota. La macchina remota ha il proprio firewall ed è protetta da un firewall aggiuntivo (router). Ha un indirizzo IP come 192.168.1.126 (o qualcosa di simile). Non sono protetto da un firewall e conosco l'indirizzo IP della macchina remota visto da Internet (non l'indirizzo 192.168.1.126). Inoltre, posso chiedere a qualcuno di eseguire prima ssh (something)come root sul computer remoto.

Qualcuno potrebbe spiegarmi, passo dopo passo, come funziona il tunneling SSH inverso per aggirare i firewall (i firewall delle macchine locali e remote e il firewall aggiuntivo tra di loro)?

Qual è il ruolo degli interruttori ( -R, -f, -L, -N)?


Risposte:


403

Adoro spiegare questo tipo di cose attraverso la visualizzazione. :-)

Pensa alle tue connessioni SSH come a tubi. Grandi tubi Normalmente, raggiungi questi tubi per eseguire una shell su un computer remoto. La shell funziona in un terminale virtuale (tty). Ma conosci già questa parte.

Pensa al tuo tunnel come a un tubo all'interno di un tubo. Hai ancora la grande connessione SSH, ma l'opzione -L o -R ti consente di impostare un tubo più piccolo al suo interno.

Ogni tubo ha un inizio e una fine. Il big tube, la tua connessione SSH, è iniziato con il tuo client SSH e finisce sul server SSH a cui ti sei connesso. Tutti i tubi più piccoli hanno gli stessi punti finali, tranne per il fatto che il ruolo di "inizio" o "fine" è determinato dal fatto che siano stati utilizzati -Lo -R(rispettivamente) per crearli.

(Non lo hai detto, ma suppongo che il computer "remoto" che hai citato, quello dietro il firewall, possa accedere a Internet usando Network Address Translation (NAT). Questo è un po 'importante, quindi si prega di correggere questo assunto se è falso.)

Quando si crea un tunnel, si specifica un indirizzo e una porta su cui risponderà e un indirizzo e una porta a cui verrà consegnato. L' -Lopzione indica al tunnel di rispondere sul lato locale del tunnel (l'host che esegue il client). L' -Ropzione indica al tunnel di rispondere sul lato remoto (il server SSH).

indicazioni tunnel ssh

Quindi ... Per poter SSH da Internet in una macchina dietro un firewall, è necessario che la macchina in questione apra una connessione SSH al mondo esterno e includa un -Rtunnel il cui punto "entry" è il lato "remoto" di la sua connessione.

Dei due modelli mostrati sopra, vuoi quello a destra.

Dall'host con firewall:

ssh -f -N -T -R22222:localhost:22 yourpublichost.example.com

Questo dice al tuo cliente di stabilire un tunnel con un -Rpunto di ingresso emote. Tutto ciò che si collega alla porta 22222 all'estremità del tunnel raggiungerà effettivamente la "porta localhost 22", dove "localhost" è dalla prospettiva del punto di uscita del tunnel (cioè il client ssh).

Le altre opzioni sono:

  • -f dice a ssh di mettersi in background dopo che si è autenticato, quindi non devi sederti in giro eseguendo qualcosa sul server remoto perché il tunnel rimanga attivo.
  • -Ndice che si desidera una connessione SSH, ma in realtà non si desidera eseguire alcun comando remoto. Se tutto ciò che stai creando è un tunnel, l'inclusione di questa opzione consente di risparmiare risorse.
  • -T disabilita l'allocazione pseudo-tty, il che è appropriato perché non stai cercando di creare una shell interattiva.

Ci sarà una sfida con la password a meno che tu non abbia impostato le chiavi DSA o RSA per un accesso senza password.

Si noti che si consiglia vivamente di utilizzare un account usa e getta (non il proprio accesso) che è stato impostato solo per questo tunnel / cliente / server.

Ora, dalla tua shell su yourpublichost , stabilisci una connessione all'host con firewall attraverso il tunnel:

ssh -p 22222 username@localhost

Riceverai una sfida chiave dell'host, poiché probabilmente non hai mai colpito questo host prima. Quindi riceverai una richiesta di password per l' usernameaccount (a meno che tu non abbia impostato le chiavi per l'accesso senza password).

Se accederai regolarmente a questo host, puoi anche semplificare l'accesso aggiungendo alcune righe al tuo ~/.ssh/configfile:

host remotehostname
    User remoteusername
    Hostname localhost
    Port 22222

Regolare remotehostnamee remoteusernameadattarsi. Il remoteusernamecampo deve corrispondere al tuo nome utente sul server remoto, ma remotehostnamepuò essere qualsiasi nome host adatto a te, non deve corrispondere a nulla di risolvibile.

(Per esporre l'endpoint inverso su un IP non localhost , consulta questo post )


2
che dire di ssh MrGreen. Spiega usando lo stesso metodo.
BigSack,

6
I proxy SOCKS non sono gli stessi dei tunnel. Se hai una domanda su come usarli, ti preghiamo di chiederlo .
ghoti,

12
Sto attraversando un momento molto difficile seguendo questa spiegazione a causa dell'uso lento di termini: server, client, macchina locale, macchina remota, host, yourpublichost, localhost, nomehost remoto. Con tutti questi termini vaghi e indefiniti, si potrebbe presumere che qualcuno avrebbe bisogno di ben 8 computer per configurarlo. Lo dico perché in tutti gli altri aspetti sembra un'ottima spiegazione. Riduci e definisci i termini.
Rucent88,

4
@ Rucent88, non sono sicuro di quale riduzione sarebbe possibile. Un client stabilisce una connessione a un server. Questa è una terminologia comune in tutto il mondo del networking. Le macchine locali e remote sembrano abbastanza evidenti. Se sei confuso su SSH o sulla terminologia generale di Unix dopo aver letto la documentazione, sono sicuro che non avrai problemi a trovare persone molto disponibili a rispondere a qualsiasi domanda tu possa avere.
ghoti,

9
@ghoti È davvero confuso, perché le macchine locali e remote sono relative. Quando mi siedo sul posto di lavoro, il computer di casa è il telecomando, quando mi siedo a casa, il computer sul posto di lavoro è remoto. Server e client sono anche fonte di confusione quando si parla di tunneling. Ad esempio, se mi connetto a casa dal lavoro con ssh -R. Mi collego al mio lavoro dal computer di casa collegando localhost. Quindi, dal punto di vista dei socket, il server è lo stesso computer di casa. Ma logicamente mi sono collegato al mio computer di lavoro. È confuso.
Calmarius,

357

Ho disegnato alcuni schizzi

La macchina, in cui viene digitato il comando ssh tunnel, è chiamata "host" .

tunnel ssh a partire da locale


tunnel ssh a partire da remoto

introduzione

  1. Locale: -L Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side.

    ssh -L sourcePort:forwardToHost:onPort connectToHostsignifica: connettersi con ssh a connectToHost, e inoltrare tutti i tentativi di connessione alla porta locale sulla macchina chiamata , che può essere raggiunta dalla macchina.sourcePortonPortforwardToHostconnectToHost

  2. a distanza: -R Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side.

    ssh -R sourcePort:forwardToHost:onPort connectToHostsignifica: connettiti con ssh a connectToHoste inoltra tutti i tentativi di connessione al telecomando sourcePort per port onPortsulla macchina chiamata forwardToHost, che può essere raggiunta dalla tua macchina locale.

Opzioni aggiuntive

  • -f dice a ssh di mettersi in background dopo che si è autenticato, quindi non devi sederti in giro eseguendo qualcosa sul server remoto perché il tunnel rimanga attivo.
  • -Ndice che si desidera una connessione SSH, ma in realtà non si desidera eseguire alcun comando remoto. Se tutto ciò che stai creando è un tunnel, l'inclusione di questa opzione consente di risparmiare risorse.
  • -T disabilita l'allocazione pseudo-tty, il che è appropriato perché non stai cercando di creare una shell interattiva.

Il tuo esempio

La terza immagine rappresenta questo tunnel. Ma il computer blu chiamato "host" rappresenta il computer in cui qualcuno avvia il tunnel SSH, in questo caso la macchina con firewall.

Quindi, chiedi a qualcuno di avviare una connessione tunnel ssh alla tua macchina. Il comando dovrebbe sostanzialmente apparire come

ssh -R 12345:localhost:22 YOURIP

Ora il tunnel è aperto. Ora puoi connetterti via ssh alla macchina firewall attraverso il tunnel con il comando

ssh -p 12345 localhost

che si collegherà alla propria localhost(macchina) sulla porta 12345, ma la porta 12345viene inoltrata attraverso il tunnel alla porta 22 dell'host locale del computer con firewall (ovvero il computer con firewall stesso).


9
Bella risposta! Lo useremo in una presentazione.
Isaiah Turner

4
Grazie. Prego. Se vuoi le immagini vettoriali (svg o pdf) scrivimi un messaggio.
Erik,

1
@erik, come hai disegnato queste immagini?
Pacerier,

31
oh amico, vorrei che le pagine man potessero avere spiegazioni come questa! Grazie!
Lucas Pottersky,

30
Sai cosa ? Non ho nemmeno dovuto leggere la spiegazione del testo. Ottimo lavoro !
Deppfx,

21

tunneling ssh funziona utilizzando la connessione ssh già stabilita per l'invio di traffico aggiuntivo.

Quando ti connetti a un server remoto, di solito hai solo 1 canale per la normale interazione dell'utente (o 3 canali se consideri STDIN / STDOUT / STDERR separati). In qualsiasi momento, il processo ssh locale o remoto può aprire canali aggiuntivi sulla connessione esistente. Questi canali quindi inviano / ricevono il traffico del tunnel. Quando si invia o si riceve traffico, il processo ssh dice semplicemente "questo traffico è per foobar di canale".

Funziona essenzialmente così:

  1. Dite a ssh di iniziare l'ascolto sulla porta XXXX e che tutto il traffico ricevuto dovrebbe essere incanalato, quindi impostare su AAAA sulla porta ZZZZ.
  2. L'ssh locale inizia l'ascolto sulla porta XXXX (generalmente attiva 127.0.0.1, ma può essere modificata).
  3. Alcune applicazioni aprono una connessione alla porta XXXX sul computer locale.
  4. L'ssh locale apre un canale sull'ssh remoto e dice "qualsiasi traffico su questo canale va a AAAA: ZZZZ
  5. L'ssh remoto si collega a AAAA: ZZZZ e restituisce "OK, il canale è aperto"
  6. Ora tutto il traffico inviato lungo la connessione alla porta XXXX sul computer locale viene inoltrato da ssh a YYYY: ZZZZ.

Questo processo è identico sia per il tunneling in avanti che per quello invertito (basta scambiare le parole "locale" e "remoto" nella procedura sopra descritta). Entrambe le parti possono avviare il tunnel. Non è nemmeno necessario quando si avvia ssh per la prima volta. Puoi aprire i tunnel mentre ssh è già in esecuzione (vedi ESCAPE CHARACTERS, in particolare ~C).

Per il ruolo di -R, -f, -L, e -N, si dovrebbe davvero basta consultare la pagina man, ti dà la migliore spiegazione possibile. Ma citerò -Re -L.
-Rdice a ssh remoto di ascoltare le connessioni e che ssh locale dovrebbe connettersi alla destinazione reale. -Ldice a ssh locale di ascoltare le connessioni e che ssh remoto dovrebbe connettersi alla destinazione reale.

Nota, questa è una descrizione molto rozza, ma dovrebbe darti abbastanza informazioni per sapere cosa sta succedendo


16

Questo è spiegato nel manuale di SSH, in particolare le differenze tra -L(locale) e -R(remoto).


-L

-L [bind_address:]port:host:hostport

Specifica che la porta specificata sull'host locale (client) deve essere inoltrata all'host e alla porta dati sul lato remoto .

Funziona assegnando un socket per ascoltare la porta sul lato locale, eventualmente associato al bind_address specificato.

Ogni volta che viene stabilita una connessione a questa porta, la connessione viene inoltrata sul canale protetto e viene stabilita una connessione alla hostporta hostportdalla macchina remota .

L'esempio seguente esegue il tunneling di una sessione IRC dal computer client 127.0.0.1( localhost) utilizzando la porta 1234 al server remoto server.example.com:

$ ssh -f -L 1234:localhost:6667 server.example.com sleep 10

Nota: l' -fopzione sfondi ssh e il comando remoto sleep 10sono specificati per consentire un periodo di tempo per avviare il servizio da sintonizzare.

Esempio:

ssh `-N` -L 22000:localhost:11000 remote.server.com
  • -N Dopo esserti connesso, resta lì (non riceverai un prompt della shell)

    Non eseguire un comando remoto.

  • -L 22000La connessione avrà origine sulla porta 22000 della tua macchina L ocal personale

  • localhost:11000- remote.server.comfarà in modo che l'altra estremità del tunnel sia la localhostporta11000

ssh -N -L 22000: 192.168.1.2: 11000 remote.server.com

Fonte: una guida illustrata, tutorial, come fare, sul tunneling ssh .


-R

-R [bind_address:]port:host:hostport

Specifica che la porta specificata sull'host remoto (server) deve essere inoltrata all'host e alla porta dati sul lato locale .

Funziona assegnando un socket da ascoltare portsul lato remoto e ogni volta che viene stabilita una connessione a questa porta, la connessione viene inoltrata sul canale protetto e viene stabilita una connessione alla hostporta hostportdal computer locale .

Esempio:

ssh -N -R 22000:localhost:11000 remote.server.com
  • -N Dopo esserti connesso, resta lì (non riceverai un prompt della shell)

    Non eseguire un comando remoto.

  • -R22000 La connessione avrà origine sulla porta 22000 del computer R emote (in questo caso, remote.server.com)

  • localhost:11000il tuo computer personale locale assicurerà che l'altra estremità del tunnel sia la localhostporta11000

ssh -N -R 22000: localhost: 11000 remote.server.com

Fonte: una guida illustrata, tutorial, come fare, sul tunneling ssh .


6
l'orecchio e la bocca chiariscono chi sta parlando e chi sta ascoltando!
Giovedì

1
Adoro le tue illustrazioni!
mcantsin,
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.