Progetto

Generale

Profilo

AutosshTunnel » Cronologia » Versione 12

Simone Piccardi, 03-05-2023 13:45

1 1 Simone Piccardi
h1. Creare tunnel permanenti con autossh
2
3 6 Chiara Barbucci
Ci sono molte occasioni in cui occorre creare delle connessioni verso macchine e servizi protetti da firewall che è opportuno cifrare e proteggere adeguatamente ma per le quali la creazione di una VPN diventa un onere eccessivo.
4 1 Simone Piccardi
5 9 Simone Piccardi
Per delle operazioni temporanee la capacità di _port forwarding_ di SSH è molto utile per creare un tunnel cifrato da una macchina ad un'altra, consentendo anche di condividere accessi locali in maniera sicura (come ad esempio l'accesso ad un database MySQL che ascolta solo localmente). Il problema sorge quando si vuole fornire una connessione di questo tipo in maniera permanente. In tal caso infatti lasciare attivo il programma può non bastare, perché la connessione SSH (ed il relativo tunnel) potrebbero cadere in caso di problemi sulla rete.
6 1 Simone Piccardi
7 9 Simone Piccardi
Per ovviare a questa eventualità e creare tunnel permanenti ci viene in aiuto @autossh@, un semplice programma che consente di eseguire un'istanza di @ssh@ mantenendola sotto controllo, riavviandola qualora la connessione dovesse cadere, il tutto fino ad un numero massimo di volte controllato dalla variabile di ambiente @AUTOSSH_MAXSTART@, o indefinitamente se il valore di questa è negativo (che è il comportamento di default).
8 1 Simone Piccardi
9 9 Simone Piccardi
Il programma infatti rileva se l'istanza di @ssh@ che ha lanciato termina con un segnale o un errore di connessione e nel caso la riesegue. Se invece si ferma @ssh@ con un segnale di SIGKILL, @autossh@ interpreta la cosa come una terminazione esplicita e si ferma anche lui. Allo stesso modo viene interpretato un segnale di terminazione inviato ad @autossh@ stesso che nel caso esce chiudendo anche l'istanza di @ssh@.
10 1 Simone Piccardi
11 10 Chiara Barbucci
Il comando prevede un'opzione principale, @-M@, che consente di indicare una porta che verrà usata per il monitoraggio della connessione. Per verificare che l'istanza di @ssh@ sia attiva e funzionante @autossh@ utilizza la porta indicata e la successiva per mandare dei messaggi che gli devono tornare indietro. Ma con la versione 2 del protocollo @ssh@ stesso supporta un controllo interno della connessione che è più affidabile. Si suggerisce pertanto di usare le opzioni di @ssh@ che abilitano questo controllo interno, che vedremo più avanti, e dare sempre ad @autossh@ un valore nullo per l'opzione (cioè @-M 0@) che disabiliti questo monitoraggio.
12 2 Simone Piccardi
13 11 Chiara Barbucci
L'altra opzione principale di @autossh@ è @-f@ che imposta l'esecuzione in background. Il resto del comportamento del programma è controllato da una serie di variabili di ambiente che ne controllano le funzionalità e per il significato di queste si rimanda alla lettura della pagina di manuale. I valori di default delle stesse, infatti, sono già adatti all'uso ordinario ed ha senso modificarli solo in caso di problemi o per attivare diagnostiche.
14 4 Simone Piccardi
15 12 Simone Piccardi
L'uso di @autossh@ consente di creare un numero arbitrario di tunnel in maniera molto sicura. Se infatti non è necessario mettersi in ascolto su porte riservate si può far eseguire il programma per conto di un utente non privilegiato, che nel nostro caso sarà appunto @autossh@. Si provvederà allora a creare detto utente sulla macchina da cui si vuole creare il tunnel con il comando:
16 2 Simone Piccardi
17
<pre>
18
useradd -m -s /bin/false autossh
19
</pre>
20
21 12 Simone Piccardi
da notare come per l'utente si sia disabilitata la shell e non si sia impostata la password, cosa che renderà impossibile usare l'utente per un accesso al sistema, che serve, essendo esso utilizzato solo allo scopo di creare il tunnel.
22 1 Simone Piccardi
23 12 Simone Piccardi
Allo stesso tempo occorrerà creare un analogo utente dedicato alla ricezione delle connessioni per creare il tunnel sulla macchina di destinazione a cui ci si collegherà con @autossh@, ed anche in questo caso dovrà essere disabilitata la shell e non impostata la password, dato che anche questa utenza non deve essere usata per un accesso al sistema, ma solo per consentire un accesso ad uso della sola creazione del tunnel. Si esegua pertanto sull'altro capo un utente con:
24
25
<pre>
26
useradd -m -s /bin/false sshtunnels
27
</pre>
28
29 9 Simone Piccardi
La scelta di non impostare la password richiede l'uso della autenticazione a chiavi, cosa che è comunque il caso di usare sempre, e se possibile in maniera esclusiva. Per questo sul capo della connessione che deve creare il tunnel si dovrà creare una chiave per l'utente che, se si vuole che il tunnel possa partire automaticamente all'avvio, dovrà essere senza password. Si dovranno pertanto eseguire i seguenti comandi:
30 2 Simone Piccardi
31
<pre>
32 5 Simone Piccardi
# su -s /bin/bash autossh
33
$ ssh-keygen
34 2 Simone Piccardi
Generating public/private rsa key pair.
35
Enter file in which to save the key (/home/autossh/.ssh/id_rsa): 
36
Enter passphrase (empty for no passphrase): 
37
Enter same passphrase again: 
38
Your identification has been saved in /home/autossh/.ssh/id_rsa.
39
Your public key has been saved in /home/autossh/.ssh/id_rsa.pub.
40
The key fingerprint is:
41
b6:b7:d5:1e:fd:b0:62:57:b5:77:4c:33:82:78:f7:06 autossh@dodds
42
The key's randomart image is:
43
+--[ RSA 2048]----+
44
|                 |
45
|                 |
46
|          . .    |
47
|         . o E oo|
48
|        S . . +o=|
49
|       . .   . ==|
50
|        . . . =.+|
51
|         . oo..+.|
52
|          .. oo .|
53 3 Simone Piccardi
+-----------------+
54
</pre>
55 1 Simone Piccardi
56
(è necessario usare @su@ con il primo comando per impersonare l'utente @autossh@ dato che questo non ha una shell né una password valida).
57
58 12 Simone Piccardi
Una volta fatto questo si dovrà aver cura di copiare la chiave pubblica sulla/e macchina/e di destinazione ed installarla nelle home dell'utente @sshtunnels@ ivi creato sotto @.ssh/authorized_keys@. Si verifichi che detto file appartenga ad @sshtunnels@, inoltre sarebbe opportuno, per evitare a priori l'uso della suddetta chiave per altri scopi, configurarla aggiungendo in testa alla riga in cui compare in @.ssh/authorized_keys@ le direttive @restrict,port-forwarding@ che ne limitano l'uso al reinoltro delle connessioni, cioè dovrà comparire come:
59 1 Simone Piccardi
60 12 Simone Piccardi
<pre>
61
...
62
restrict,port-forwarding ssh-rsa AAAAB3NzaC ... eOze07VFk= autossh@client
63
...
64
</pre>
65 1 Simone Piccardi
66 12 Simone Piccardi
Infine occorrerà completare le operazioni di preparazione ed almeno la prima volta occorrerà confermare la validità della fingerprint della chiave del server SSH dell'altro capo della connessione eseguendo come utente @autossh@ sul client una connessione alla macchina remota, in sostanza si dovrà eseguire:
67
68 1 Simone Piccardi
<pre>
69 12 Simone Piccardi
# su -s /bin/bash autossh
70
$ ssh sshtunnels@macchinaremota
71
</pre>
72
73
ed accettare la fingerprint della chiave del server remoto.
74
75
A questo punto si potrà creare un tunnel semplicemente lanciando @ssh@ con le opzioni necessarie tramite @autossh@. Dato che si vuole solo creare un tunnel occorrerà usare l'opzione @-N@ per dire a @ssh@ di non lanciare nessun comando (non sarebbe comunque possibile, avendo impostato @/bin/false@ come shell). Sono importanti inoltre le opzioni:
76
77
<pre>
78 1 Simone Piccardi
-o "ServerAliveInterval 60" 
79
-o "ServerAliveCountMax 3"
80 8 Chiara Barbucci
</pre>
81 1 Simone Piccardi
82
che consentono di attivare il controllo interno della sussistenza della connessione di @ssh@ cui abbiamo accennato. Il tunnel potrà poi essere attivato con le solite opzioni @-L@ o @-R@ a seconda della direzione.
83
84 12 Simone Piccardi
Se allora ad esempio si vuole creare un tunnel per la connessione ad un database MySQL remoto di una macchina che è raggiungibile in SSH, una volta creati gli utenti come descritti, sarà sufficiente eseguire il comando:
85 1 Simone Piccardi
86
<pre>
87 12 Simone Piccardi
su -s /bin/sh autossh -c 'autossh -M 0 -q -f -N -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -L 3306:localhost:3306 sshtunnels@macchinaremota'
88 1 Simone Piccardi
</pre>
89 9 Simone Piccardi
90 5 Simone Piccardi
91
Allo stesso modo, se si vuole creare un tunnel per consentire un accesso di amministrazione remota ad una macchina posta dietro un firewall per la quale non è possibile un accesso diretto, si potrà usare un comando del tipo:
92 1 Simone Piccardi
93 5 Simone Piccardi
<pre>
94 12 Simone Piccardi
su -s /bin/sh autossh -c 'autossh -M 0 -q -f -N -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -R 20001:localhost:22 sshtunnels@macchinaremota'
95 5 Simone Piccardi
</pre>
96 9 Simone Piccardi
97 5 Simone Piccardi
e in questo modo usando sull'altro capo del tunnel il comando @ssh -p 20001 root@localhost@ ci si potrà ricollegare all'indietro. 
98 9 Simone Piccardi
99 5 Simone Piccardi
Con i comandi indicati, che portano @autossh@ in background, il tunnel resta attivo fintanto che non lo si interrompe esplicitamente o si riavvia la macchina. Per abilitare il tunnel in maniera permanente all'avvio di una macchina la cosa più semplice è inserire il comando in @/etc/rc.local@ o file analogo per il proprio sistema di avvio. 
100 1 Simone Piccardi
101 12 Simone Piccardi
Qualora si utilizzi @systemd@ si può utilizzare la _unit file_ illustrata di seguito (ma ci si ricordi che si deve comunque aver cura di aver eseguire almeno una volta il comando manualmente per accettare la fingerprint del server a cui ci si connette, come descritto in precedenza):
102 5 Simone Piccardi
103
<pre>
104
[Unit]
105
Description=AutoSSH tunnel service for SSH remote access
106
After=network.target
107
108
[Service]
109
Environment="AUTOSSH_GATETIME=0"
110 12 Simone Piccardi
ExecStart=/usr/bin/autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -NR 20001:localhost:22 sshtunnels@macchinaremota
111 5 Simone Piccardi
User=autossh
112
113
[Install]
114
WantedBy=multi-user.target
115
</pre>
116
117 9 Simone Piccardi
Si noti come in questo caso non è possibile lanciare @autossh@ con l'opzione @-f@, perché l'avvio in background non è supportato da @systemd@ (è cura di @systemd@ eseguire il tutto in background). In questo caso occorre inoltre indicare ad @autossh@ di ripetere la connessione anche se questa fallisce inizialmente, impostando la variabile di ambiente @AUTOSSH_GATETIME@ ad un valore nullo (questo è il default se si usa @-f@, ma non nell'uso normale).
118 5 Simone Piccardi
119
Installando la _unit file_ precedente sotto @/etc/systemd/system@ (ad esempio come @autossh-tunnel.service@) sarà possibile attivare il tunnel con:
120
121
<pre>
122
systemctl start autossh-tunnel
123
</pre>
124
125
verificarne lo stato con:
126
127
<pre>
128
systemctl status autossh-tunnel
129
</pre>
130
131
e predisporne l'attivazione all'avvio con: 
132
133
<pre>
134
systemctl enable autossh-tunnel
135
</pre>