Un’applicazione vincolata all’indirizzo VPN usa ancora la route sbagliata
Un socket vincolato all’indirizzo VPN segue la route predefinita ordinaria. Verificate la proprietà dell’indirizzo e la ricerca consapevole dell’origine prima di aggiungere regole di policy.
Un’applicazione si vincola all’indirizzo della VPN e la connessione esce comunque dalla route predefinita ordinaria. Nel bind non è fallito nulla: ha fatto esattamente quello che fa un bind. Vincolare un socket a un indirizzo locale sceglie l’indirizzo di origine che il kernel mette nell’intestazione. Non installa una route e non crea una regola di policy che mandi i pacchetti con quell’origine in un tunnel specifico.
Il resto di questo manuale è l’ordine di controllo che uso, insieme al comando che produce ogni osservazione.
Che cosa decide davvero un bind
Un bind assegna un indirizzo locale al socket. Poi il kernel esegue la stessa ricerca di route che avrebbe eseguito altrimenti, a meno che una regola di policy non cambi quale tabella legge quella ricerca.
Per questo un pacchetto può uscire con un indirizzo di origine VPN su un’interfaccia fisica. Dall’altro lato arriva da un intervallo privato che la rete non si aspettava su quel percorso, il traffico di ritorno non ha una route per tornare e la connessione si blocca o si azzera.
La documentazione dei socket IP di Linux descrive la semantica del bind. La metà del routing vive in ip-rule e ip-route, e sono pagine di manuale separate per un motivo.
Confermate che l’indirizzo appartiene a questo namespace
Un indirizzo a cui potete vincolarvi deve esistere su un’interfaccia dentro il namespace di rete in cui gira l’applicazione. Un indirizzo di peer, un indirizzo di gateway o un indirizzo che esiste solo in un altro namespace non è vincolabile, e la chiamata fallisce con EADDRNOTAVAIL.
ip -br addr show
ip netns identify <pid>
ss -tanp | grep <port>Eseguite quei tre nello stesso contesto dell’applicazione: stesso namespace e stesso utente, se riuscite a ottenerlo. Un vecchio schema net30 non è una prova di quale indirizzo la vostra topologia attuale abbia assegnato al client. Leggete l’interfaccia realmente attiva.
Leggete la ricerca per quell’origine e quella destinazione
Un solo comando risponde alla domanda a cui il bind non ha risposto:
ip route get 203.0.113.10 from 10.8.0.2
ip rule showLa prima riga stampa la route che prenderebbe un pacchetto da quell’origine a quella destinazione, comprese l’interfaccia di uscita e l’origine preferita. Se nomina l’interfaccia fisica, bind e route sono in disaccordo, e il pacchetto uscirà con un’origine a cui il percorso non può tornare.
Poi ip rule show vi dice se qualche regola avrebbe scelto un’altra tabella. Le priorità contano qui, perché vince la prima regola corrispondente e una regola che cattura tutto sopra la vostra rende invisibile la vostra.
Installate una regola di policy solo se è questo il progetto
Il routing basato sull’origine è un progetto deliberato, non una riparazione per una singola applicazione. Se il proprietario della policy vuole che il traffico della sottorete del tunnel usi il tunnel, la regola appartiene alla sua configurazione e non a un comando una tantum sul vostro portatile.
Una forma praticabile è una tabella dedicata con una route predefinita attraverso il tunnel, più una regola che manda l’intervallo di origine della VPN in quella tabella. Aggiungete le eccezioni che il progetto richiede, perché una tabella che contiene solo un default del tunnel catturerà destinazioni che devono restare locali o raggiungibili dal percorso fisico.
ip route add default dev tun0 table 100
ip rule add from 10.8.0.2 table 100 priority 100
ip route get 203.0.113.10 from 10.8.0.2Annullate con ip rule del e ip route flush table 100. Tutto ciò che viene aggiunto così sparisce al riavvio, a meno che un gestore non lo scriva, il che è insieme una proprietà di sicurezza e un motivo per non tenere l’unica copia nella cronologia della shell.
Verificate con tre osservazioni
Registrate l’origine richiesta dall’applicazione, la route scelta dalla ricerca e l’origine che il server ha effettivamente visto.
Queste tre possono discordare, e ogni discordanza punta altrove. Una cattura sull’interfaccia del tunnel dimostra che il pacchetto è uscito con l’origine giusta. Una cattura sull’interfaccia fisica dimostra che è uscito dalla strada sbagliata. Solo la vista lato server dimostra il percorso da estremo a estremo.
Se l’applicazione offre un’opzione di vincolo a un dispositivo o una modalità di routing per applicazione, trattatela come un meccanismo diverso con vincoli diversi. Impostazioni dall’aspetto simile non portano tutte alla stessa decisione del kernel.