Reverse tunnel SSH: come bypassare un NAT

Pubblicato il 21/05/2017 in System Administration, Technology • 3 min read

Ci sono situazioni in cui si ha l'esigenza di accedere ad un computer in una rete filtrata, dove cioè non c'è la possibilità di effettuare modifiche alle regole del firewall per potervi accedere direttamente.

Per queste situazioni ci viene in aiuto SSH che è in grado di effettuare un reverse tunnel.

Vediamo come!

Scenario

Un'immagine vale più di mille parole:

SSH Reverse Tunnel

Da questo diagramma di rete possiamo osservare:

  • un client connesso a internet
  • un server pubblico che espone il servizio SSH
  • un server privato il cui accesso è bloccato da un firewall

Il nostro scopo è quello di poter accedere al server privato attraverso il server pubblico.

Come? Con un reverse tunnel SSH!

In principio era il tunnel SSH

Un tunnel SSH è un sistema di incapsulamento di protocolli che permette, attraverso l'inoltro di porte locali o remote, di accedere a servizi non esposti su internet.
Faccio un esempio: ipotizziamo di dover raggiungere un server PostrgreSQL non esposto su internet e che il suo indirizzo IP sia 192.168.1.12; ipotizziamo che questo server PostgreSQL sia raggiungibile da un altro server (che chiameremo public) che ha il server SSH esposto su internet. Per raggiungere il server PostgreSQL, dobbiamo effettuare un tunnel SSH, inoltrando una porta locale:

user@client: ~ $ ssh -L \*:9999:192.168.1.12:5432 alice@public

Con questo comando abbiamo inoltrato la porta 5432 dell'IP 192.168.1.12 sulla porta 9999 di public; quindi per accedere al database PostgreSQL useremo il comando:

psql -h public -p 9999 -U postgres

Come è possibile notare, ci siamo connessi alla porta 9999 del server public, raggiungendo il database PostgreSQL che non è esposto su internet, ma raggiungibile esclusivamente dalla rete interna.

Ok, ma allora il reverse tunnel SSH quando si usa?

Quando il computer da raggiungere è all'interno di una rete dove non possiamo modificare le regole del firewall per esporre l'accesso SSH, oppure il provider non ci fornisce un indirizzo IP pubblico e si è dietro un NAT, il reverse tunnel SSH ci è d'aiuto.
Infatti, con il reverse tunnel SSH, è la macchina da raggiungere che si preoccupa di effettuare la connessione verso un server pubblico, creando una connessione verso l'esterno.

Seguendo l'immagine in alto, abbiamo tre computer:

  • client, che è il nostro laptop
  • public, il server con SSH raggiungibile direttamente
  • private, il server da raggiungere

Avendo accesso dalla rete interna al server private, bisogna instaurare la connessione verso public:

bob@private: ~ $ ssh -R public:12345:localhost:22 alice@public

Una volta effettuato l'accesso su public, avremo girato la porta 22 di private sulla porta 12345 di public.
Quindi connettendoci in SSH verso public verso la porta 12345 usando le credenziali di private:

user@client: ~ $ ssh bob@public -p 12345

Ci troveremo finalmente sul computer private, che non ha un indirizzo IP pubblico e non è direttamente accessibile dall'esterno.

Affinché si possa accedere direttamente a [private]{style="text-decoration: underline;"}, è necessario il server SSH di [public]{style="text-decoration: underline;"} abbia la seguente direttiva:

GatewayPorts yes

Al termine della modifica, è necessario riavviare il demone SSH.

E se la connessione si interrompe?

Se per qualche motivo dovesse cadere la connessione, chiaramente, non avremmo modo di accedere nuovamente al server private in quanto il tunnel sarebbe interrotto.
Per questo motivo ci viene in aiuto un altro tool, autossh, che - con l'aiuto delle chiavi SSH per non dover inserire ogni volta la password - permette di riconnettere automaticamente le connessioni SSH che si interrompono.

Al prossimo post!