SSH: Tips and Tricks Reprise

2

opensshlinux

Come avevo promesso ecco la seconda dose di Tips and Tricks per SSH!

Invito a leggere la prima parte QUI.

SSH Tunneling

Siccome oggi mi sento pigro, farò il copiaincolla di un commento (più precisamente questo, grazie Michelangelog 😉 )

Mi permetto di fare una piccola aggiunta ai tuoi ottimi suggerimenti.
Spesso farebbe comodo accedere alla macchina HOST_C dalla nostra macchina HOST_A
ma magari la macchina HOST_C non permette l’accesso alla nostra macchina oppure
non permette l’accesso ad una determinata porta, capita invece di avere accesso
alla macchina HOST_B e magari questa ha un accesso ad HOST_C.
Si può sfruttare l’ssh per creare un “tunnel” che in pratica ci permette tramite
la macchina HOST_B di avere un accesso alla porta desiderata su HOST_C.
Supponiamo di avere un istanza di oracle sulla porta 1523 di HOST_C a cui si
vuole accedere magari tramite un tool grafico come oracle sql developer,
la sintassi per il tunnel ssh è la seguente:
ssh -L PORTA_LOCALE:HOST_C:PORTA(host e porta a cui non possiamo accedere)
utente@HOST_B(host su cui abbiamo l’accesso)
ad esempio suppinendo che vogliamo sulla porta locale 9999 il forward della
porta 1523 di HOST_C
ssh -L 9999:HOST_C:1523 user@HOST_B
ora una semplice connessione localhost:9999 viene inoltrata su 1523 di HOST_C.

Direi che è tutto abbastanza chiaro no? 🙂

Reverse Tunnelling

Cosa succede se la macchina che vogliamo controllare è dietro un NAT ? È una situazione comune per tutti gli utenti di FastWeb, che fornisce sicuramente una connessione veloce, ma a patto di stare dietro un fastidioso NAT, che permette liberamente le connessioni in uscita ma non le connessioni in ingresso.

Se vi trovate in questa situazione e avete la fortuna di essere possessori di un VPS o abbiate un gentile amico in grado di fornirvi un accesso SSH potrete usufruire della fantastica capacità di reverse tunneling di SSH.

Il reverse tunneling consiste nel far aprire la prima connessione alla macchina dietro NAT ed incapsulando tutte le connessioni successive (sia in ingresso che in uscita) su quella prima connessione.

Supponiamo di avere tre macchine:

  • remotehost: la macchina dietro NAT
  • middlehost: la macchina ponte
  • otherhost: la macchina “esterna”

Per poter controllare remotehost dal mondo esterno è necessario che il demone SSH su middle host abbia l’opzione “GatewayPorts yes” nel suo file di configurazione, una volta accertato questo è necessario istanziare la prima connessione da remotehost a middlehost in questo modo:

fpedrini@remotehost:~$ ssh -R 10022:localhost:22 fpedrini@middlehost

In questo modo la porta 10022 di “middlehost” rimarrà in ascolto per eventuali connessioni e le reindirizzerà sulla porta 22 di “remotehost”, è appunto il nostro reverse tunnel.

È anche possibile evitare di lasciare una shell di middlehost aperta sulla macchina remota, passando le opzioni -Nf ad ssh:

fpedrini@remotehost:~$ ssh -R -Nf 10022:localhost:22 fpedrini@middlehost

In questo modo il client ssh si metterà automaticamente in background.

Una volta aperto il reverse tunnel è possibile connettersi da “otherhost” a “remotehost” usando il seguente comando:

fpedrini@otherhost:~$ ssh remotehost@middlehost -p 10022

La connessione verrà effettuata alla porta 10022 di middlehost, che provvedrà a fare il forwarding verso la porta 22 di remotehost sfruttando il tunnel.

Nel caso non fosse possibile abilitare l’opzione “GatewayPorts yes” sul demone ssh di middle host avete un’ulteriore possibilità:

fpedrini@otherhost:~$ ssh user@middlehost
Password:
user@middlehost:~ ssh remoteuser@locahost -p 10022

In questo modo vi appoggerete direttamente a middlehost, e non dovrete modificare la sua configurazione.

Autenticazione con chiavi: ssh-copy-id e ssh-agent

SSH permette di autenticarsi su host remoti in diverse maniere, le più famose sono quella con password (che è il default) e quella con chiave.

Una coppia di chiavi (una pubblica e una privata) è composta da due file che identificano in maniera univoca (e fino ad ora in maniera non replicabile a meno di bug) un utente su un determinato host.
Per autenticarsi con chiave su una macchina remota è necessario copiare su quella macchina la propria chiave pubblica, al tentativo di login, verrà controllata la corrispondenza chiave pubblica/chiave privata e nel caso il login verrà permesso.

Per generare la propria coppia di chiavi è sufficiente dare il comando ssh-keygen:

fpedrini@host:~$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/fpedrini/.ssh/id_rsa): [invio]
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_rsa.
Your public key has been saved in id_rsa.pub.
The key fingerprint is:
83:67:5b:bd:76:ae:76:ad:45:49:67:39:9a:2c:71:82 fpedrini@host
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|          .     .|
|         E o . +o|
|       .   .= +.+|
|      . S ...+ ..|
|       o +  .. . |
|        .   o ...|
|           ..o...|
|           ..oo. |
+-----------------+

In questo modo all’interno di ~/.ssh ci saranno due file: id_rsa e id_rsa.pub, il primo contiene la chiave privata, il secondo quella pubblica.

Per effettuare un login con chiave è necessario copiare il contenuto del file id_rsa.pub all’interno del file “~/.ssh/authorized_keys” della macchina remota.

Copiare la chiave pubblica su una macchina remota è un’operazione che, se eseguita male, può portare alla rimozione delle chiavi precedentemente installate.
Fortunatamente ssh-copy-id ci viene in aiuto, occupandosi da solo di copiare la chiave specificata sull’host remoto:

fpedrini@host:~$ ssh-copy-id -i id_rsa remotehost
fpedrini@remotehost's password:
Now try logging into the machine, with "ssh 'remotehost'", and check in:

  .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

D’ora in poi avremo la possibilità di entrare su remotehost usando solo la passphrase della chiave ssh.

Tuttavia non risolviamo il problema di dover inserire ad ogni login una password, che sia quella del sistema remoto o quella che sblocca la propria chiave, siamo sempre costretti ad rispondere alla tediosa (quando si tratta di connettersi a molti host) domanda “Password?”

Anche in questo caso ci viene in aiuto un tool chiamato ssh-agent, che permette di fare il caching della propria passphrase (rigorosamente in RAM) per la sessione corrente, in modo da dover inserire la propria passphrase una e una sola volta, indipendentemente dal numero di login che si faranno.

La maggior parte delle distribuzioni fa partire ssh-agent assieme alla sessione del X server, per verificare che ssh-agent sia vivo è sufficiente lanciare il comando ssh-add -L:

fpedrini@host:~$ ssh-add -L
Could not open a connection to your authentication agent.
fpedrini@host:~$ #l'agent non è attivo, lanciamolo!
fpedrini@host:~$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-sojRj30014/agent.30014; export SSH_AUTH_SOCK;
SSH_AGENT_PID=30015; export SSH_AGENT_PID;
echo Agent pid 30015;
fpedrini@host:~$ ssh-add -L
The agent has no identities.

Per aggiungere l’identità all’agent ssh è sufficiente lanciare

fpedrini@host:~$ ssh-add ~/.ssh/id_rsa
Enter passphrase for /home/fpedrini/.ssh/id_rsa:
Identity added: /home/fpedrini/.ssh/id_rsa (/home/fpedrini/.ssh/id_rsa)
fpedrini@host:~$ ssh-add -L
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwCN3/itjoIjM1yt3R78PiWm6xXpo8vn1/CCmg09o0P+KEr3QE429AfXern3IIP2l+3kpsTSyCOkBA0FoCJU2D9euhIoXyKVrB/sy4sE75rlnz0ab/YqUJWyGzXC6KFoaipgh+6rbN2FCoVF9m0mlBi4aNz4flHwsJskQ5vlMqpLO1YoB9yF7jSgLcjNT11+vbppi3AwMUVUWOx89aKuEHjL+qKNCIY1igEmSRpJ9K2OfW6otFRKp/sBcSo8U7HJjPn74I+NwAGFuf0dJXIs/3dTgcenhLCMurVrq8OWenKvHTpxkWmHGnkruhe3tvT/Jf76DcKOFxm7+a3K0uhLJ/w== /home/fpedrini/.ssh/id_rsa

Da questo momento la chiave è aggiunta ad ssh-agent.

Remote commands

Con SSH è possibile lanciare singoli comandi senza aprire una shell sulla macchina e digitare il comando voluto, permettendo così di automatizzare alcuni processi e annoiarsi un po’ di meno nell’esecuzione dei compiti tediosi di tutti i giorni.

Ad esempio se volessi lanciare il comando ‘w’ su remotehost, è sufficiente il seguente comando:

fpedrini@host:~$ ssh remotehost w
Password:
 16:05:17 up 347 days, 23:40,  0 users,  load average: 0,00, 0,02, 0,00
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT

Fino a che si tratta di un comando singolo su una macchina singola, la differenza tra lanciare il comando tramite ssh e connettersi direttamente è decisamente esugua, ma nel caso si voglia lanciare lo stesso comando su una serie di macchine si può usare il seguente mini-script:

cat host_list.txt |
while read host;
do
    ssh $host w 
done

Ovviamente tutto questo funziona MOLTO meglio dopo aver installato la propria chiave sulle macchine contenute in host_list.txt.

Conclusione
Con questo secondo articolo abbiamo coperto la maggior parte delle “hidden features” (per modo di dire) di SSH, che sono spesso molto utili per alleviare la fatica della gestione di diverse macchine.