GNU/Linux >> Linux Esercitazione >  >> Linux

Alimenta tutto il traffico tramite OpenVPN solo per uno spazio dei nomi di rete specifico

Puoi avviare il collegamento OpenVPN all'interno di uno spazio dei nomi e quindi eseguire tutti i comandi che desideri utilizzare quel collegamento OpenVPN all'interno dello spazio dei nomi. I dettagli su come farlo sono presentati in Esecuzione di un tunnel OpenVPN all'interno di uno spazio dei nomi di rete, di Sebastian Thorarensen.

L'ho provato e funziona. L'idea è quella di fornire uno script personalizzato per eseguire le fasi di up e route-up della connessione OpenVPN all'interno di uno spazio dei nomi specifico invece che globale. Ecco una risposta basata sulla fonte sopra, ma modificata per aggiungere Google DNS a resolv.conf .

Per prima cosa crea un --up script per OpenVPN. Questo script creerà l'interfaccia del tunnel VPN all'interno di uno spazio dei nomi di rete chiamato vpn , invece dello spazio dei nomi predefinito.

$ cat > netns-up << 'EOF'
#!/bin/sh
case $script_type in
        up)
                ip netns add vpn
                ip netns exec vpn ip link set dev lo up
                mkdir -p /etc/netns/vpn
                echo "nameserver 8.8.8.8" > /etc/netns/vpn/resolv.conf
                ip link set dev "$1" up netns vpn mtu "$2"
                ip netns exec vpn ip addr add dev "$1" \
                        "$4/${ifconfig_netmask:-30}" \
                        ${ifconfig_broadcast:+broadcast "$ifconfig_broadcast"}
                test -n "$ifconfig_ipv6_local" && \
                        ip netns exec vpn ip addr add dev "$1" \
                                "$ifconfig_ipv6_local"/112
                ;;
        route-up)
                ip netns exec vpn ip route add default via "$route_vpn_gateway"
                test -n "$ifconfig_ipv6_remote" && \
                        ip netns exec vpn ip route add default via \
                                "$ifconfig_ipv6_remote"
                ;;
        down)
                ip netns delete vpn
                ;;
esac
EOF

Quindi avvia OpenVPN e digli di utilizzare il nostro --up script invece di eseguire ifconfig e route.

openvpn --ifconfig-noexec --route-noexec --up netns-up --route-up netns-up --down netns-up

Ora puoi avviare i programmi da incanalare in questo modo:

ip netns exec vpn command

L'unico problema è che devi essere root per invocare ip netns exec ... e forse non vuoi che la tua applicazione venga eseguita come root. La soluzione è semplice:

sudo ip netns exec vpn sudo -u $(whoami) command

Si scopre che puoi inserire un'interfaccia tunnel in uno spazio dei nomi di rete. Tutto il mio problema era dovuto a un errore nel richiamare l'interfaccia:

ip addr add dev $tun_tundv \
    local $ifconfig_local/$ifconfig_cidr \
    broadcast $ifconfig_broadcast \
    scope link

Il problema è "collegamento ambito", che ho frainteso in quanto riguarda solo il routing. Fa sì che il kernel imposti l'indirizzo di origine di tutti i pacchetti inviati nel tunnel a 0.0.0.0; presumibilmente il server OpenVPN li eliminerebbe quindi come non validi per RFC1122; anche se così non fosse, la destinazione ovviamente non sarebbe in grado di rispondere.

Tutto ha funzionato correttamente in assenza di spazi dei nomi di rete perché lo script di configurazione di rete integrato di openvpn non ha commesso questo errore. E senza "scope link", anche il mio script originale funziona.

(Come l'ho scoperto, chiedi? Eseguendo strace sul processo openvpn, imposta su hexdump tutto ciò che legge dal descrittore del tunnel, quindi decodifica manualmente le intestazioni del pacchetto.)


L'errore nel tentativo di creare i dispositivi veth è causato da un cambiamento di come ip interpreta gli argomenti della riga di comando.

La corretta invocazione di ip creare una coppia di dispositivi veth è

ip link add name veth0 type veth peer name veth1

(name invece di dev )

Ora, come far uscire il traffico dallo spazio dei nomi al tunnel VPN? Poiché hai a disposizione solo dispositivi tun, l'"host" deve instradare. Cioè. creare la coppia veth e inserirne una nello spazio dei nomi. Connetti l'altro tramite routing al tunnel. Pertanto, abilita l'inoltro e quindi aggiungi i percorsi necessari.

Per esempio supponiamo che eth0 è la tua interfaccia principale, tun0 è la tua interfaccia del tunnel VPN e veth0 /veth1 la coppia di interfacce di cui veth1 è nello spazio dei nomi. All'interno dello spazio dei nomi aggiungi solo un percorso predefinito per veth1 .

Sull'host è necessario utilizzare l'instradamento dei criteri, ad esempio vedere qui. Cosa devi fare:

Aggiungi/aggiungi una voce come

1   vpn

a /etc/iproute2/rt_tables . Con questo puoi chiamare la tabella (ancora da creare) per nome.

Quindi utilizzare le seguenti istruzioni:

ip rule add iif veth0 priority 1000 table vpn
ip rule add iif tun0 priority 1001 table vpn
ip route add default via <ip-addr-of-tun0> table vpn
ip route add <ns-network> via <ip-addr-of-veth0> table vpn

Non posso provarlo qui con una configurazione come la tua, ma questo dovrebbe fare esattamente quello che vuoi. Puoi aumentarlo con regole di filtro dei pacchetti tali che né la VPN né la rete "ospite" siano disturbate.

N.B. Spostamento di tun0 nello spazio dei nomi in primo luogo sembra la cosa giusta da fare. Ma come te non l'ho fatto funzionare. Il policy routing sembra la prossima cosa giusta da fare. La soluzione di Mahendra è applicabile se conosci le reti dietro la VPN e tutte le altre applicazioni non accederanno mai a tali reti. Ma la tua condizione iniziale ("tutto il traffico e solo il traffico, verso/da specifici processi passa attraverso la VPN") sembra che quest'ultima non possa essere garantita.


Linux
  1. 6 opzioni di filtro del traffico di rete tcpdump

  2. Utilizzo dello strumento SS per la risoluzione dei problemi di rete

  3. Utilizzo di Tcpdump per la registrazione di tutte le attività di rete che passano attraverso un server router?

  4. Come assicurarsi che tutto il traffico Internet passi solo attraverso VPN?

  5. CentOS / RHEL:come impostare SFTP su Chroot Jail solo per un gruppo specifico

Apri le porte e instrada il traffico attraverso il firewall

Come utilizzare Wireshark per acquisire e analizzare i pacchetti di rete

Accesso in sola lettura a tutti i file in una sottocartella specifica?

Come posso elencare tutti gli IP nella rete connessa, preferibilmente tramite Terminal?

Instrada solo traffico specifico tramite VPN

Cambia proprietario e gruppo solo per proprietari specifici