Nuove connessioni su una nuova uscita VPN, i vecchi flussi restano come sono
Un drain pianificato sposta solo i flussi non classificati. Confrontatelo con un cambio di rotta e osservate i marchi, le tabelle e lo stato conntrack che lo fanno reggere.
Due uscite VPN sane, un lungo caricamento già in corso e il requisito che la prossima connessione usi l’altro tunnel. Ci sono due modi per soddisfarlo, e solo uno è sicuro su un gateway in produzione. Scambiare la rotta predefinita sposta ogni pacchetto, compresi quelli che appartengono al caricamento. Un drain pianificato cambia la scelta per le nuove connessioni lasciando i flussi tracciati sul percorso su cui sono partiti.
Due modi per cambiare un’uscita
Lo scambio di rotta è un solo comando ed è reversibile in pochi secondi, ed è per questo che si usa durante gli incidenti. È anche indiscriminato: i pacchetti del caricamento esistente escono all’improvviso da un altro tunnel, con un altro indirizzo di origine pubblico e uno stato di traduzione separato.
Se l’estremo remoto traccia i flussi per indirizzo di origine, il caricamento può semplicemente smettere di essere riconosciuto. Il drain lo evita prendendo la decisione una volta per connessione e memorizzandola, così il vecchio caricamento mantiene la sua uscita finché non finisce. È tutto il valore dell’esercizio: l’estremo remoto non vede alcun cambiamento che debba interpretare. Continua a ricevere pacchetti che corrispondono alla connessione che già conosce.
Il costo è la complessità: due tabelle di routing, un classificatore che gira all’hook giusto e marchi che vanno coordinati con tutto il resto che li usa sulla macchina.
Date a ogni uscita la sua tabella
Riservate una tabella di routing per uscita e valori di marchio o bit distinti per le due scelte. Ogni tabella ha bisogno delle rotte adatte al suo ruolo, non solo di un nome, e ha bisogno di un esito di guasto deliberato per il caso mancante. Una tabella vuota che ricade silenziosamente nella tabella principale — è così che il traffico esce da un’uscita che nessuno ha scelto.
ip rule add fwmark 0x10/0x10 table 101
ip rule add fwmark 0x20/0x20 table 102
ip route add default via 192.0.2.1 dev wg-a table 101
ip route add default via 198.51.100.1 dev wg-b table 102Aggiungete una rotta blackhole alla fine di ogni tabella, così una ricerca senza corrispondenza fallisce rumorosamente invece di sfuggire a un default che non avete scelto.
Scegliete una volta, al primo pacchetto
Classificate dopo che esiste il tracciamento delle connessioni e prima della ricerca di rotta che conta. Per una connessione LAN nuova e non classificata, scegliete l’uscita e salvatela nello stato della connessione. Nei pacchetti successivi, ripristinate il valore salvato nel marchio di pacchetto che legge il routing per policy.
La parte sottile è che cosa significa nuovo. Conntrack può ancora riportare NEW per i pacchetti iniziali e le ritrasmissioni prima che si veda una risposta, quindi un classificatore che si basa solo su quello stato può sovrascrivere una scelta già fatta. Verificate che per la connessione non sia salvata alcuna uscita prima di assegnarne una.
nftables tiene separati i marchi di pacchetto e di connessione, e la guida ai metadati documenta la copia esplicita tra i due. Un marchio di connessione non diventa da solo il marchio di pacchetto a cui corrisponde la vostra regola, ed è la ragione più comune per cui un classificatore scritto con cura non ha alcun effetto.
Limitate il ripristino alla direzione e al traffico che intendete. Applicare un marchio di uscita internet ai pacchetti di ritorno può mandare le risposte verso l’uscita invece che verso la LAN, e il sintomo è una connessione unidirezionale che sembra un problema di firewall. Leggete il percorso di risposta prima di toccare una regola di firewall, perché il pacchetto viene instradato, solo non di ritorno al mittente.
Quattro fasi di un drain
Preparate B senza toccare A: routing, inoltro, autorizzazione, NAT e percorso di ritorno. Installate la sua tabella e la sua politica di selezione tramite il proprietario di configurazione esistente del gateway.
Cambiate il classificatore in modo che le connessioni nuove e non classificate scelgano B, conservando le scelte salvate. Una transazione nftables atomica evita una finestra in cui lo stato vecchio va cancellato.
Lasciate A attivo finché i suoi flussi non finiscono. La sua interfaccia, tabella, uscita remota e mappature NAT fanno ancora parte di quei flussi, e modificare una regola NAT non ricostruisce i binding già esistenti.
Ritirate A quando la condizione di drain è soddisfatta, giudicata dallo stato delle connessioni e dal comportamento dell’applicazione anziché da un solo intervallo tranquillo.
Ciò che un drain non può promettere
Una richiesta del browser non è una nuova connessione di trasporto; il pooling continua a inviare richieste su quella vecchia. Al contrario, un flusso UDP può invecchiare fuori da conntrack e un pacchetto successivo viene classificato di nuovo. Il drain segue i flussi tracciati, non l’idea che un’applicazione ha di una sessione.
Se A si guasta prima che i suoi flussi finiscano, il marchio salvato non li salva. Si riconnettono tramite B, oppure non si riconnettono affatto. Un drain pianificato compra continuità finché il percorso originale è sano; non è replicazione di stato tra uscite indipendenti.
Verificate entrambe le metà
Avviate una connessione consentita di lunga durata prima del cambiamento e una davvero nuova dopo. Confermate quale tunnel usa ciascuna e quale indirizzo di origine pubblico vede l’estremo remoto, poi verificate che il traffico di ritorno torni.
Non svuotate la tabella conntrack per far comparire la nuova scelta. Questo distrugge esattamente lo stato che il drain dovrebbe preservare, e trasforma una migrazione controllata in un’interruzione con un test dall’aria pulita.