Perché nftables non vede il traffico tra client di OpenVPN
Il traffico tra pari viene consegnato all'interno del processo VPN, quindi i contatori di inoltro non si muovono mai. Contarlo significa scegliere tra il percorso del kernel e quello del processo.
Due client su un solo server si scambiano file, il trasferimento riesce e ogni regola di inoltro puntata sul tunnel riporta zero pacchetti. Le regole non sono rotte e la catena non è fuori posto. Con l'inoltro tra pari attivo, il pacchetto viene consegnato all'interno del processo del server e lo stack dell'host non diventa mai il router, quindi il firewall del kernel non ha nulla da contare. Capire questa separazione decide se mantenere la scorciatoia o ricostruire il percorso attraverso il kernel.
Segui un pacchetto attraverso il server
In un tunnel instradato, il demone consegna il pacchetto decifrato di ogni client al dispositivo di tunnel. Da lì l'host lo instrada, l'hook di inoltro viene eseguito e una regola che corrisponde al dispositivo di tunnel può contare o scartare il traffico. È il percorso che presuppongono la maggior parte degli esempi di firewall.
| Forwarding path | Who decides | What the host firewall sees |
|---|---|---|
| Kernel routing between clients | Host routing table and forward rules | Every inner packet, with interface names |
| Peer forwarding inside the server process | The VPN daemon's own peer table | Only the outer encrypted transport |
La scorciatoia toglie l'host dal mezzo. Il pacchetto decifrato di una sessione viene consegnato a un'altra sessione all'interno del demone, e il pacchetto interno non viene mai emesso sul dispositivo di tunnel né instradato dall'host. Il traffico incapsulato attraversa comunque l'interfaccia fisica, quindi una cattura esterna sembra occupata mentre le regole interne restano mute. Una cattura presa sul dispositivo di tunnel non mostra assolutamente nulla, il che sorprende chi si aspetta di vedere lì il trasferimento. Quell'asimmetria è il modo più rapido per riconoscere la scorciatoia dall'esterno del demone.
Il test del contatore che stabilisce quale percorso è stato usato
Collega un contatore alla regola che dovrebbe applicarsi, esegui un trasferimento tra due client che quella regola dovrebbe bloccare, poi leggi il contatore.
sudo nft list ruleset
sudo nft add rule inet filter forward iifname "tun0" oifname "tun0" counter accept
sudo nft list chain inet filter forward
Se il trasferimento riesce e il contatore resta a zero, il kernel non ha mai gestito quei pacchetti, e nessuna modifica delle regole lo cambierà. Ripeti lo stesso test contro un servizio sul server stesso, perché quel flusso attraversa davvero lo stack dell'host e il suo contatore si muove. È il confronto dei due risultati a dare la risposta.
Due dettagli evitano una lettura falsa. Un nome di interfaccia scritto in un'etichetta di catena non filtra nulla da solo, perché la corrispondenza avviene sui campi dell'interfaccia dentro le regole. E un progetto a ponte di livello 2 si comporta ancora diversamente: lì i client condividono un dominio di broadcast, quindi la scoperta dei pari è attesa e non un guasto di instradamento.
Uno switch non è una lista di accesso
Questa è la parte che costa un pomeriggio. L'inoltro tra pari è un'unica impostazione acceso o spento, e finché è accesa il demone è l'unico punto di inoltro. Il firewall dell'host non può esprimere chi può raggiungere chi, e i file per client non trasformano lo switch in una matrice di criteri.
Se servono regole per singolo pari, la scelta è tra rinunciare alla scorciatoia e rinunciare al firewall dell'host come controllo. Disattivarla ripristina l'inoltro del kernel, che richiede l'inoltro IP sul server e regole esplicite per i flussi desiderati. Lasciarla attiva significa che il criterio vive nella configurazione del demone, che in pratica è tutti i pari o nessuno.
Processi server separati con i propri intervalli di indirizzi e porte sono la via di mezzo praticabile. Ogni processo porta esattamente una decisione di accesso, quindi due gruppi possono avere regole diverse senza una matrice di criteri. L'host può instradare tra gli intervalli quando è voluto, e allora il firewall vede quei flussi perché attraversano l'host. Il costo sono porte aggiuntive, certificati aggiuntivi e un profilo per gruppo.
Scegliere il punto di inoltro
Scegli l'inoltro del kernel quando il firewall è il motore dei criteri, quando serve registrazione per flusso o quando la contabilità conta. Il costo è il throughput attraverso lo stack dell'host e più regole da mantenere. Il vantaggio è che ogni strumento esistente, dai contatori agli esportatori di flussi, descrive di nuovo il traffico. Su un server piccolo quel costo è invisibile; su un relè occupato non lo è.
Scegli l'inoltro nel processo quando il traffico tra pari è tutto consentito o tutto negato e il server è dimensionato per questo. Il costo è che contatori, discipline di coda e tracciamento delle connessioni non descrivono più i flussi interni; è accettabile solo se poi nessuno vi fa affidamento.
Qualunque cosa scegli, scrivila accanto alle regole del firewall. Un insieme di regole che sembra permettere il traffico tra pari mentre il demone decide comunque inganna la persona successiva che esegue il debug di un trasferimento fallito. Chi legge solo le regole presumerà che il kernel sia il cancello.
Cosa verificare prima di cambiare le regole
Leggi la configurazione che il server ha davvero caricato, non il file che ricordi di aver modificato, e conferma se l'opzione dei pari è presente. Se l'hai cambiata, assicurati che il servizio si sia ricaricato e non abbia solo riscritto un file su disco.
Poi ripeti il test con un flusso da client a server per dimostrare che la regola corrisponde almeno, e controlla le rotte inviate, perché una rotta mancante sembra esattamente un blocco del firewall dal lato client. Cambia l'ordine delle regole solo quando sai quale punto di inoltro possiede la decisione.