Accesso SSH via bastion host a reti private » Cronologia » Versione 12
Simone Piccardi, 04-10-2024 09:39
1 | 12 | Simone Piccardi | h1. Accesso con SSH tramite _bastion host_ a reti private |
---|---|---|---|
2 | 1 | Simone Piccardi | |
3 | 10 | Simone Piccardi | L'utilizzo di una connessione SSH è uno degli strumenti fondamentali per l'amministrazione remota dei server Linux. Su una macchina su una rete pubblica in genere tutto quello che serve è fornire un opportuno accesso agli utenti autorizzati sulla porta su cui è in ascolto il server (possibilmente limitando gli stessi ad una lista di macchine remote autorizzate). |
4 | 1 | Simone Piccardi | |
5 | 10 | Simone Piccardi | Esistono però diversi casi in cui può essere necessario fornire a singoli utenti esterni un accesso con SSH su specifiche macchine presenti nella propria rete interna, senza fornire un accesso generico a detta rete con una VPN. In sostanza si vuole poter consentire ad un utente esterno +solo+ un collegamento SSH, +solo+ verso una specifica macchina interna. |
6 | 1 | Simone Piccardi | |
7 | 10 | Simone Piccardi | Per ottenere questo risultato si può sfruttare una qualunque macchina che si affacci su detta rete interna (un cosiddetto _bastion host_) e che sia raggiungibile dall'esterno con SSH, appoggiandosi ad una delle funzionalità avanzate di questo servizio, il cosiddetto " _Proxy Jump_", che è stato introdotto con OpenSSH 7.3 (rilasciata nell'agosto 2016) ed è ormai disponibile su tutte le versioni del programma installate da una qualunque distribuzione recente. |
8 | |||
9 | 9 | Simone Piccardi | Questa funzionalità prevede che si possa, passando attraverso una macchina a cui si ha accesso SSH, effettuare in maniera trasparente un reinoltro della connessione SSH verso un'altra macchina da questa raggiungibile. Si tratta in sostanza di usare il server SSH presente sul _bastion host_ come proxy del protocollo. |
10 | 1 | Simone Piccardi | |
11 | 3 | Simone Piccardi | La funzionalità di proxy deve essere richiesta dal client che esegue la connessione, usando l'opzione l'opzione @-J@ del comando @ssh@ per indicare la macchina da usare come proxy. Può essere inoltre essere indicata nella propria configurazione client (quella mantenuta nel file @.ssh/config@ nella propria home directory) con la direttiva @ProxyJump@. |
12 | 1 | Simone Piccardi | |
13 | !bastion.png! |
||
14 | |||
15 | 10 | Simone Piccardi | Nel prosieguo faremo riferimento allo schema di rete illustrato nella figura precedente; per collegarsi alla macchina server sull'indirizzo interno @192.168.42.105@, passando dalla macchine @bastion.truelite.it@ raggiungibile da Internet, si dovrà utilizzare un comando come: |
16 | 1 | Simone Piccardi | |
17 | <pre> |
||
18 | ssh -J utente_a@bastion.truelite.it utente_b@192.168.42.105 |
||
19 | </pre> |
||
20 | |||
21 | 10 | Simone Piccardi | e una volta autenticatisi sul bastion host che fa da proxy con @utente_a@ e poi sul server finale con @con utente_b@, si otterrà l'accesso al server interno. |
22 | 1 | Simone Piccardi | |
23 | 10 | Simone Piccardi | Si tenga presente che per la macchina di destinazione finale si può usare anche un nome a dominio, o un qualunque altro nome che sia risolubile dal _bastion host_; la connessione verso la destinazione finale (nell'esempio @utente_b@192.168.42.105@) infatti viene sempre eseguita dal _bastion host_. |
24 | 2 | Simone Piccardi | |
25 | 9 | Simone Piccardi | Ovviamente se lo scopo è quello di fornire accesso ristretto solo ad una specifica macchina interna ad un utente esterno, fornire un accesso utente ordinario sul _bastion host_ è una scelta tutt'altro che appropriata sul piano della sicurezza. |
26 | |||
27 | 8 | Simone Piccardi | Inoltre chi si collega in questo modo deve anche autenticarsi due volte, e dare due volte una password, possibilmente anche diversa, cosa che non è particolarmente comoda. Fortunatamente l'autenticazione a chiavi di SSH, di cui abbiamo già parlato [[La_gestione_delle_chiavi_SSH|qui]] ci viene incontro, e permette di semplificare notevolmente le operazioni lato client, rendendo al contempo l'accesso molto più sicuro. |
28 | 3 | Simone Piccardi | |
29 | 1 | Simone Piccardi | Il primo passo è quello di creare sul _bastion host_ un utente dedicato al servizio di proxy, privandolo di qualunque altra capacità. Nel nostro caso sceglieremo di usare un utente @sshproxy@, che creeremo come utente di sistema, senza password e senza possibilità di accesso, con qualcosa del tipo: |
30 | 3 | Simone Piccardi | |
31 | 2 | Simone Piccardi | <pre> |
32 | useradd -r sshproxy -s /sbin/false |
||
33 | </pre> |
||
34 | |||
35 | 9 | Simone Piccardi | Per fornire ad un esterno l'accesso questo utente creeremo una coppia di chiavi senza passphrase. Questo può essere fatto su qualunque macchina, basterà poi inserire la chiave pubblica nel file @.ssh/authorized_keys@ dell'utente @sshproxy@ sul _bastion host_ e distribuire la coppia di chiavi a tutte le persone a cui si vuole fare usare il servizio. Per semplicità creeremo la coppia di chiavi direttamente nella home dell'utente @sshproxy@, predisponendo l'accesso, con i seguenti comandi: |
36 | 2 | Simone Piccardi | |
37 | <pre> |
||
38 | root@bastion:~# su - sshproxy -s /bin/bash |
||
39 | sshproxy@bastion:~$ ssh-keygen |
||
40 | Generating public/private rsa key pair. |
||
41 | Enter file in which to save the key (/home/sshproxy/.ssh/id_rsa): |
||
42 | Created directory '/home/sshproxy/.ssh'. |
||
43 | Enter passphrase (empty for no passphrase): |
||
44 | Enter same passphrase again: |
||
45 | Your identification has been saved in /home/sshproxy/.ssh/id_rsa. |
||
46 | Your public key has been saved in /home/sshproxy/.ssh/id_rsa.pub. |
||
47 | The key fingerprint is: |
||
48 | SHA256:6kwKCutHHWIP6R/TVaQgHN+uL7PuOhYdTQTvs7jCjEY sshproxy@bastion |
||
49 | The key's randomart image is: |
||
50 | +---[RSA 2048]----+ |
||
51 | | .o.oo... | |
||
52 | | .o +... | |
||
53 | | . .o+. | |
||
54 | | = . .oo | |
||
55 | 1 | Simone Piccardi | | o = + S+ | |
56 | | E * +o o | |
||
57 | 2 | Simone Piccardi | |. + = *o . | |
58 | |.o = % oo | |
||
59 | |+.o o.O=+. | |
||
60 | +----[SHA256]-----+ |
||
61 | sshproxy@bastion:~$ cp .ssh/id_rsa.pub .ssh/authorized_keys |
||
62 | sshproxy@bastion:~$ chmod 600 .ssh/authorized_keys |
||
63 | </pre> |
||
64 | |||
65 | 3 | Simone Piccardi | In questo modo chiunque abbia a disposizione la coppia di chiavi potrà usarla per autenticarsi sul bastion host, pur non potendosi collegare allo stesso. Per migliorare la sicurezza sarà comunque opportuno bloccare anche tutte le funzionalità di SSH non necessarie all'utilizzo della connessione ad uso di proxy, cosa che si può fare in due modi diversi. |
66 | 2 | Simone Piccardi | |
67 | 3 | Simone Piccardi | Il primo metodo è più radicale, e rimuove le capacità aggiuntive in maniera completa per l'utente ricorrendo all'uso della direttiva @Match@ in @/etc/ssh/sshd_config@ per bloccare le stesse. La direttiva consente di applicare configurazioni specifiche a tutte le connessioni che corrispondono al criterio indicato come parametro, questo prevede che si utilizzi una prima parola chiave per specificare cosa filtrare, come @User@, @Group@, @Address@, ecc. Nel nostro caso filtreremo per utente, restringendo al massimo le capacità di @sshproxy@, pertanto occorrerà aggiungere _in coda_ a @/etc/ssh/sshd_config@ le seguenti direttive: |
68 | 1 | Simone Piccardi | |
69 | 2 | Simone Piccardi | <pre> |
70 | Match User sshproxy |
||
71 | 1 | Simone Piccardi | AllowAgentForwarding no |
72 | AllowTcpForwarding yes |
||
73 | X11Forwarding no |
||
74 | PermitTunnel no |
||
75 | GatewayPorts no |
||
76 | 3 | Simone Piccardi | PasswordAuthentication no |
77 | 1 | Simone Piccardi | </pre> |
78 | |||
79 | 11 | Simone Piccardi | Si noti che si è detto +_in coda_+: la direttiva @Match@ infatti si applica a tutto quello che segue, e supporta l'indicazione soltanto di un sottoinsieme delle direttive di @sshd_config@, pertanto se la si inserisce in mezzo al file tutto quello che segue verrà applicato all'utente @sshproxy@, e se nel seguito si è usata una delle direttive non consentite da @Match@ si avrà anche una configurazione non valida ed il servizio non ripartirà. |
80 | |||
81 | Si può rimuovere l'applicazione specifica delle direttive all'utente @sshproxy@ facendo seguire il precedente estratto da una ulteriore direttiva @Match all@, che applica il resto delle direttive a tutti, ma questo non risolve il problema dell'uso nel resto del file di direttive non consentite dalla direttiva @Match@. Mettere l'estratto in coda evita questi problemi. In ogni caso, prima di riavviare il servizio, si verifichi sempre che la configurazione aggiuntiva è valida usando il comando @sshd -T@. |
||
82 | 1 | Simone Piccardi | |
83 | 9 | Simone Piccardi | Il secondo metodo è più flessibile e consente almeno teoricamente di variare le restrizioni a secondo di chi si collega senza modificare la configurazione del server. Di nuovo si usa una delle funzionalità avanzate del servizio SSH, che consente di restringe l'ambito di applicazione di una chiave, inserendo in testa alla riga in cui è elencata dentro @.ssh/authorized_keys@ le opportune restrizioni prima dell'indicazione del tipo di chiave. In sostanza nel caso precedente si tratterà si modificare @/home/sshproxy/.ssh/authorized_keys@ inserendo in testa alla chiave autorizzata qualcosa come: |
84 | 1 | Simone Piccardi | |
85 | 8 | Simone Piccardi | <pre> |
86 | 1 | Simone Piccardi | restrict,port-forwarding ssh-rsa AAAAB3NzaC ... 9bgOvM/DkF sshproxy@bastion |
87 | 4 | Simone Piccardi | </pre> |
88 | 3 | Simone Piccardi | |
89 | 9 | Simone Piccardi | che blocca tutte le capacità aggiuntive eccetto quella del reinoltro delle connessioni, necessaria per il " _Proxy Jump_ ". |
90 | 3 | Simone Piccardi | |
91 | 9 | Simone Piccardi | Una volta fatta questa configurazione sul _bastion host_ ci si potrà collegare ad una macchina usandolo come proxy, ma per farlo è necessario dire al client di usare la coppia di chiavi che abbiamo creato allo scopo, che assumeremo di aver copiato sul client come @proxy_rsa_id@ e @proxy_rsa_id.pub@ nella directory @.ssh@ della propria home directory. Si potrebbe pensare di farlo con un comando come: |
92 | |||
93 | 3 | Simone Piccardi | <pre> |
94 | 6 | Simone Piccardi | ssh -J sshproxy@bastion.truelite.it -i .ssh/proxy_rsa_id utente@192.168.42.105 |
95 | 3 | Simone Piccardi | </pre> |
96 | |||
97 | ma in questo caso l'opzione @-i@ si applica al collegamento verso @192.168.42.105@ e si otterrà una richiesta della password per @sshproxy@. |
||
98 | |||
99 | 9 | Simone Piccardi | Dato che non esiste una opzione a riga di comando per indicare la chiave da usare per il proxy, e che usare l'opzione @-J@ comporta comunque di scrivere di più, è opportuno inserire i parametri per la connessione dentro la propria configurazione client di SSH nel file @.ssh/config@ della propria home, così che sia valida non solo per @ssh@, ma anche per @scp@ e tutti gli altri comandi che usano il servizio. |
100 | 3 | Simone Piccardi | |
101 | In questo file si potrà sia indicare come collegarsi alla macchina @bastion.truelite.it@ con le chiavi aggiuntive, sia l'uso della stessa come proxy per le connessioni verso la macchina @192.168.42.105@, aggiungendo le righe: |
||
102 | |||
103 | <pre> |
||
104 | Host bastion.truelite.it |
||
105 | User sshproxy |
||
106 | IdentityFile ~/.ssh/proxy_rsa_id |
||
107 | |||
108 | 1 | Simone Piccardi | Host 192.168.42.105 testserver othername |
109 | 4 | Simone Piccardi | Hostname 192.168.42.105 |
110 | 3 | Simone Piccardi | ProxyJump sshproxy@bastion.truelite.it |
111 | 1 | Simone Piccardi | </pre> |
112 | 4 | Simone Piccardi | |
113 | ottenendo di potersi collegare semplicemente con: |
||
114 | |||
115 | <pre> |
||
116 | 1 | Simone Piccardi | ssh utente@192.168.42.105 |
117 | 4 | Simone Piccardi | </pre> |
118 | |||
119 | o con uno qualunque dei nomi aggiuntivi inseriti nella configurazione, come: |
||
120 | |||
121 | 1 | Simone Piccardi | <pre> |
122 | 4 | Simone Piccardi | ssh utente@testserver |
123 | 1 | Simone Piccardi | </pre> |
124 | |||
125 | 4 | Simone Piccardi | La scelta di usare una coppia di chiavi dedicate come descritto finora ha il vantaggio che non serve fare nessuna modifica alla configurazione generale di SSH sul _bastion host_ e che su deve configurare l'accesso in @/home/sshproxy/.ssh/authorized_keys@ una sola volta e poi basta distribuire i file delle chiavi a chi si vuole dare accesso, ma ha lo svantaggio che non è possibile bloccare l'uso del proxy ad uno solo degli utenti a cui si sia data la coppia di chiavi, a meno di non cambiarla per tutti. |
126 | 8 | Simone Piccardi | |
127 | 9 | Simone Piccardi | Per questo, pur comportando il tutto un maggior lavoro di configurazione sul _bastion host_, è più sicuro e flessibile farsi inviare dal singolo utente esterno la sua chiave pubblica SSH ed aggiungerla a @/home/sshproxy/.ssh/authorized_keys@, sempre con una configurazione analoga alla precedente: |
128 | 8 | Simone Piccardi | |
129 | 4 | Simone Piccardi | <pre> |
130 | 1 | Simone Piccardi | restrict,port-forwarding ssh-rsa AAAAB3NzaC ... eOze07VFk= esterno@altrove.it |
131 | 4 | Simone Piccardi | </pre> |
132 | |||
133 | 9 | Simone Piccardi | in modo che ogni utente acceda con la propria chiave. |
134 | 4 | Simone Piccardi | |
135 | 9 | Simone Piccardi | Questa configurazione permette di revocare l'accesso ad un singolo utente semplicemente eliminando la sua chiave da @/home/sshproxy/.ssh/authorized_keys@ ed in questo caso la generazione di una chiave generale per @sshproxy@ non è più necessaria. Si noti anche che in questo caso, se la chiave corrisponde all'identità di default dell'utente che accede, si potrà anche ridurre la precedente configurazione che questi dovrà eseguire sul proprio client a: |
136 | |||
137 | 4 | Simone Piccardi | <pre> |
138 | Host 192.168.42.105 testserver othername |
||
139 | Hostname 192.168.42.105 |
||
140 | ProxyJump sshproxy@bastion.truelite.it |
||
141 | </pre> |
||
142 | |||
143 | 9 | Simone Piccardi | Ed inoltre si potrà anche usare la stessa chiave sulla macchina di destinazione (@192.168.42.105@ o qualunque altra) per fornire l'accesso esterno desiderato, senza dover distribuire una password utente, rendendo così più semplice e sicuro l'accesso, dato che non servirà più fornire la password tutte le volte (una modalità di configurazione degli accessi sulla destinazione finale che è comunque consigliabile anche qualora si fosse adottato la strategia precedente di una chiave comune per @sshproxy@). |