Un servizio dell’host deve rispondere a internet tramite il collegamento ascendente fisico mentre tutto il resto della macchina continua a usare il tunnel. Tre condizioni decidono se l’instradamento basato su criteri può sopportare quel carico, e ciascuna è economica da verificare prima di scrivere una regola. Il servizio deve terminare su questo host e non dietro un DNAT o una porta inoltrata, le regole della VPN stessa devono consentire l’eccezione, e bisogna far corrispondere la risposta invece della richiesta. Se una delle tre fallisce, i comandi qui sotto si caricano senza errori ma non fanno nulla di utile.

Verificate le tre condizioni prima di scrivere una regola

Un container che pubblica una porta tramite DNAT, o un server dietro un inoltro di porta, genera pacchetti che non hanno origine su questo host. Quei pacchetti vengono inoltrati, quindi una regola basata sull’input locale dell’host non li vede mai e il traffico continua a prendere la rotta predefinita. Confermate dove il servizio viene effettivamente eseguito prima di proseguire, perché è la condizione che la gente sbaglia più spesso.

La seconda condizione è politica, non meccanica. Qualsiasi rotta che aggira il tunnel è un’eccezione allo scopo del tunnel, e su un host gestito quella decisione spetta a chi possiede la politica, non a chi esegue il debug di un timeout.

Fate corrispondere la risposta, non la porta di destinazione del client

La risposta di un server in ascolto su TCP 443 lascia l’host con la porta di origine 443. Un browser sullo stesso host che si collega a un sito HTTPS remoto invia una porta di origine effimera e una porta di destinazione 443. Entrambe sono traffico sulla porta 443 e solo una dovrebbe usare la tabella WAN, per questo una corrispondenza sulla porta di destinazione catturerebbe la metà sbagliata.

La direzione della risposta è ciò che potete distinguere. Fate corrispondere la porta di origine, limitate la regola ai pacchetti generati localmente, e la regola copre le risposte del servizio stesso senza toccare le richieste del browser.

Costruite una tabella di ritorno completa prima che la regola vi faccia riferimento

Una tabella vuota significa nessuna rotta, cosa che sembra un servizio guasto più che una politica guasta. Riempitela prima, con un numero di tabella e una priorità che nient’altro sull’host rivendica:

ip -4 route add table 100 192.0.2.0/24 dev eth0
ip -4 route add table 100 default via 192.0.2.1 dev eth0
ip -4 rule add priority 1000 iif lo ipproto tcp sport 443 lookup 100

Leggete i numeri dall’host in esecuzione invece di copiarli. ip -4 rule show vi dice quali priorità sono occupate, e aggiungere una regola su una priorità già esistente cambia silenziosamente l’ordine di due regole che singolarmente sembrano a posto.

Due selettori fanno qui il lavoro vero. iif lo è il modo in cui il kernel segnala i pacchetti che l’host ha generato da sé, così la regola non può catturare per errore traffico inoltrato che arriva dall’esterno. ipproto tcp sport 443 la restringe a un trasporto e a una porta, il che è tanto stretto quanto il requisito consente. Togliete il selettore di protocollo e la regola intercetta anche UDP 443, che è un altro servizio con un altro comportamento.

Tenete le risposte private dentro il tunnel

Se lo stesso listener risponde anche ai client sul lato privato, una rotta WAN predefinita che cattura tutto nella tabella 100 tenterà di restituire quelle risposte tramite il collegamento ascendente. Aggiungete i prefissi privati che non devono seguire la rotta WAN predefinita, o lasciateli cadere sulla regola di politica successiva:

ip -4 route add table 100 throw 10.90.0.0/24

Una rotta throw termina la ricerca in questa tabella e restituisce il pacchetto all’elenco delle regole, così la politica VPN che segue ha la sua occasione. Non instrada nulla essa stessa nel tunnel, e se nessuna regola successiva ha una rotta corrispondente il pacchetto fallisce comunque; verificate la politica successiva invece di dare per scontato che il throw sia una correzione.

Il filtraggio del percorso inverso e le regole del firewall dell’host valgono ancora per la richiesta in arrivo. Guardate i loro verdetti reali prima di allentare la validazione, perché un’eccezione di instradamento non fa sì che rp_filter accetti un percorso di ritorno che considera impossibile.

Provate TCP, poi QUIC, poi un riavvio

Aprite una connessione da un client esterno autorizzato e una dal lato privato, poi ispezionate la ricerca della risposta con gli indirizzi e le porte reali. Se la risposta esterna prende la tabella 100 e quella privata no, la politica fa ciò che avete chiesto.

HTTP/3 è servito su UDP e non sarà intercettato da una regola TCP, quindi un listener QUIC ha bisogno del proprio selettore, altrimenti continuerà a usare il tunnel mentre HTTPS funziona. Salvate le regole su cui vi fermate con il componente che possiede l’interfaccia, e confermatele dopo una riconnessione o un rinnovo DHCP. Quando un gestore concorrente rimuove una rotta di runtime dopo un riavvio, è un problema di proprietà da risolvere all’origine, non un motivo per aggiungere regole NAT più ampie sopra.

Articoli correlati