IPsec dentro IPsec: quali indirizzi deve trasportare il tunnel esterno
Date al tunnel esterno gli indirizzi dei gateway interni, non le sottoreti delle applicazioni. Poi dimostrate inoltro, traduzione e MTU a ogni livello prima di chiamarlo annidato.
L'IPsec annidato è più facile da ragionare quando i due livelli terminano su macchine diverse. Quattro gateway, due tunnel e una sola domanda che decide se il progetto funziona: cosa vede davvero il tunnel esterno quando quello interno ha finito con il pacchetto? Rispondete a questo e i selettori, le rotte e l'ordine di risoluzione dei problemi seguono. Sbagliate e passerete una giornata a eseguire il debug di un tunnel che tecnicamente è attivo.
Il modello a quattro gateway
I gateway esterni A e B costruiscono il primo tunnel tra i due siti. Dietro A c'è il gateway interno C con indirizzo di transito 10.60.0.2; dietro B c'è il gateway interno D con indirizzo di transito 10.70.0.2. Le reti delle applicazioni vivono dietro C e D, e ogni indirizzo dell'esempio è deliberatamente non sovrapposto.
application net -> C -> A == outer IPsec == B -> D -> application net
\---------- inner IPsec ----------/
C transit: 10.60.0.2 D transit: 10.70.0.2
A and B: underlay addresses only
Dividere i livelli su quattro host significa che ogni macchina applica un confine. Un singolo host che esegue entrambi i livelli deve conciliare due insiemi di policy, due tabelle di routing e due modalità di guasto su una macchina, cosa possibile e molto più difficile da osservare.
Ogni livello rimuove solo la propria protezione
C cifra un pacchetto applicativo per D. Il risultato è indirizzato da C a D, ed è ciò che raggiunge A. Tutto ciò che sta a valle dipende da quella riscrittura.
A lo cifra di nuovo per B. B decifra il livello esterno, vede un pacchetto da C a D e lo inoltra ancora cifrato. D rimuove la protezione interna e consegna il pacchetto applicativo.
Quindi A e B vedono gli endpoint interni e i loro metadati, ma non sono le parti che decifrano il payload applicativo. È una proprietà reale del progetto e non l'affermazione che C, D o gli host applicativi siano affidabili.
I selettori esterni nominano i gateway interni
È qui che la maggior parte di queste costruzioni fallisce. Per un tunnel esterno basato su policy, i selettori che negoziate devono contenere gli indirizzi che A e B gestiscono realmente: 10.60.0.2/32 e 10.70.0.2/32, nell'ordine locale e remoto corretto.
Mettere le sottoreti applicative finali nei selettori esterni non funziona, perché quando un pacchetto raggiunge A, l'incapsulamento interno ha già riscritto ciò che A deve proteggere. La policy esterna allora non corrisponderebbe a nulla, e il tunnel salirebbe senza trasportare dati.
Non restringete l'autorizzazione esterna a UDP 500. La connessione interna ha il proprio percorso dati, che usa ESP o incapsulamento UDP a seconda di quanto negoziato, e la policy esterna deve consentire quel protocollo.
Verificate il risultato con swanctl --list-sas su ogni gateway e confermate che le associazioni di sicurezza figlie riportino gli indirizzi che intendevate, non quelli che avete supposto. Se l'elenco mostra le sottoreti applicative, la policy esterna è stata scritta per il livello sbagliato. Correggete i selettori prima di eseguire il debug del routing, perché il routing sembrerà a posto e i contatori non si muoveranno.
L'inoltro e la trappola della ricorsione
I selettori non sostituiscono il routing. A e B devono inoltrare il traffico tra C e D in entrambe le direzioni, il che significa inoltro IP abilitato, rotte che puntano al tunnel e un percorso di ritorno che esista dall'altra parte.
Se il tunnel esterno usa interfacce XFRM, le rotte selezionano l'interfaccia mentre le policy negoziate limitano ancora ciò che trasporta. Un'interfaccia non amplia ciò che è protetto; cambia solo come il kernel preleva il pacchetto.
La trappola è la ricorsione. La rotta di A verso l'endpoint esterno di B deve seguire l'underlay, non il tunnel che A sta stabilendo, altrimenti l'incapsulamento tenta di viaggiare dentro se stesso e la connessione non si completa mai.
Ispezionate la traduzione prima di aggiungere livelli
Guardate qualsiasi NAT sorgente su A e B prima di regolare qualsiasi altra cosa. Una regola che riscrive l'indirizzo di C prima che si applichi la policy IPsec può rompere i selettori concordati, e può anche cambiare ciò che D riceve dall'altra parte.
Il mascheramento ampio non diventa più sicuro con due livelli. Nasconde quale indirizzo vede l'estremità remota, ed è esattamente l'informazione che serve quando il tunnel è attivo e l'applicazione no.
Se una regola NAT è davvero necessaria, annotate con quale indirizzo ciascun lato crede di parlare. Quella singola riga risolve la maggior parte delle discussioni su se la colpa sia del tunnel o della traduzione. Dice anche al prossimo ingegnere dove guardare quando la regola verrà rimossa un anno dopo. Un ping non farà nulla di tutto questo.
Dimostrate il fail-closed e controllate l'MTU
La scomparsa di una rotta non è di per sé una policy fail-closed. Un'altra tabella, una rotta predefinita o una regola di policy possono fornire silenziosamente un ripiego, e l'unico modo per saperlo è abbassare il tunnel esterno e osservare cosa fa il traffico applicativo. Fatelo di proposito, in una finestra, invece di scoprirlo per caso.
Provate tre stati: tunnel esterno abbassato, tunnel interno abbassato e ripristino dopo che entrambi tornano. Usate i contatori delle policy su ogni gateway, perché due sessioni IKE stabilite dimostrano solo che la negoziazione del piano di controllo è riuscita.
Mettete in budget entrambi gli incapsulamenti. Un IKE funzionante è un risultato di pacchetti piccoli, e i pacchetti applicativi a dimensione piena possono ancora fallire una volta aggiunti due header; provate con una dimensione del payload nota sul percorso reale invece di supporre che i numeri tornino. L'aritmetica è facile, il percorso no.