Una normale applicazione Linux usa la VPN senza toccare TUN
Il daemon possiede il dispositivo TUN e il tunnel; le applicazioni aprono solo socket. Mantieni il privilegio di configurazione e l'accesso alla rete come confini separati.
Un browser che usa una VPN Linux già stabilita non apre /dev/net/tun. Apre un socket e il kernel decide da quale interfaccia escono i pacchetti di quel socket. Il processo che ha creato il tunnel svolge un lavoro diverso dal processo di cui trasporta il traffico. Tenere separati questi due ruoli risponde alla maggior parte delle domande sui permessi prima che vengano poste.
Segui un pacchetto dal socket al tunnel
Un'applicazione normale chiama connect o send e il kernel cerca una rotta per la destinazione. Se la rotta scelta punta all'interfaccia del tunnel, il pacchetto viene messo in coda al dispositivo che il daemon VPN legge. Il daemon lo cifra e lo invia attraverso l'interfaccia fisica. Ogni freccia di quella descrizione è un punto in cui si può rispondere a una domanda sui permessi.
Nulla in quel percorso richiede che l'applicazione conosca il dispositivo. Il daemon detiene il descrittore di file ed esegue le operazioni sull'interfaccia, mentre l'applicazione vede solo una normale API di rete.
Disegna le due metà una volta e le domande sui permessi diventano più facili da collocare. La metà superiore è il mondo delle applicazioni e quella inferiore appartiene al daemon.
Decidi chi ha bisogno del dispositivo e chi no
Creare o collegarsi a un'interfaccia TUN richiede l'accesso al dispositivo e in più la capacità di configurarla, per questo un servizio VPN supportato parte con l'autorità di amministrazione di rete o usa un helper privilegiato. Quel requisito appartiene al daemon. Non dice nulla sul browser, sul client di database o sullo strumento di trasferimento file. Un servizio che ha bisogno della capacità la richiede per il proprio passo di configurazione, non per i suoi client.
Una volta che la rotta e la policy sono in posizione, un processo normale usa il percorso risultante tramite le sue solite chiamate di socket. Non ha bisogno del nodo del dispositivo e non ha bisogno di root.
Cambiare i permessi del dispositivo non è un modo per concedere a un'applicazione l'accesso alla destinazione. Sposta solo il confine del dispositivo altrove.
Controlla lo spazio dei nomi in cui l'applicazione viene davvero eseguita
Un container, o un secondo spazio dei nomi di rete, dà ai suoi processi un insieme di interfacce e una tabella di routing separati. Un tunnel sull'host non compare lì automaticamente e nessuna modifica dei permessi del dispositivo lo cambia. L'applicazione instraderà semplicemente attraverso ciò che quello spazio dei nomi fornisce. Per questo un'immagine di container non può ereditare per caso un tunnel dell'host.
Controlla con ip netns list e ip -n NAME route, oppure ispezionando il collegamento dello spazio dei nomi del processo. La risposta di solito è visibile con un solo comando.
Anche a due utenti sullo stesso host si possono assegnare percorsi diversi tramite policy. È una decisione di rete, non una prova sulla proprietà del dispositivo.
Separa le capacità dalla policy di rete
Alcuni strumenti hanno bisogno di più di un socket. Catturare pacchetti richiede un socket grezzo e cambiare le rotte richiede l'autorità di amministrazione. Sono operazioni separate con concessioni separate, e concederne una non va letto come requisito generale per usare la VPN.
Un programma che implementa il proprio tunnel è un terzo caso. Apre davvero TUN perché assume il ruolo del daemon, ed è per questo che ha bisogno dei privilegi del daemon.
Nomina l'operazione prima di nominare il privilegio. Di solito i due sono più facili da separare di quanto sembri.
Verifica la separazione con due account
Connetti il tunnel come servizio, poi esegui l'applicazione come utente normale e conferma che raggiunge la risorsa privata. Controlla ip route get per la destinazione dalla shell di quell'utente per vedere quale interfaccia è stata scelta. Se la rotta è corretta e la connessione fallisce ancora, il problema è la policy e non il privilegio.
Il progetto che ne risulta è il minimo privilegio con un confine esplicito: un componente possiede la configurazione e le risorse del tunnel, i carichi di lavoro mantengono i loro account normali e la policy di rete decide cosa può passare. Eseguire tutto come root fa crollare quei ruoli senza spiegare nulla.