Odkaz OpenVPN můžete spustit uvnitř jmenného prostoru a poté spustit každý příkaz, který chcete použít tento odkaz OpenVPN uvnitř jmenného prostoru. Podrobnosti o tom, jak to udělat, jsou uvedeny ve Spuštění tunelu OpenVPN uvnitř síťového jmenného prostoru od Sebastiana Thorarensen.
Zkusil jsem to a funguje to. Záměrem je poskytnout vlastní skript pro provádění fáze up a směrování připojení OpenVPN uvnitř konkrétního jmenného prostoru namísto globálního. Zde je odpověď založená na výše uvedeném zdroji, ale upravená tak, aby byla přidána Google DNS do resolv.conf
.
Nejprve vytvořte --up skript pro OpenVPN. Tento skript vytvoří rozhraní tunelu VPN uvnitř síťového jmenného prostoru s názvem vpn , namísto výchozího jmenného prostoru.
$ 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
Poté spusťte OpenVPN a řekněte mu, aby použil naše --up skript namísto provádění ifconfig a route.
openvpn --ifconfig-noexec --route-noexec --up netns-up --route-up netns-up --down netns-up
Nyní můžete spustit programy k tunelování takto:
ip netns exec vpn command
Jediný háček je v tom, že pro vyvolání ip netns exec ...
musíte být root a možná nechcete, aby vaše aplikace běžela jako root. Řešení je jednoduché:
sudo ip netns exec vpn sudo -u $(whoami) command
Ukázalo se, že můžete vložte rozhraní tunelu do síťového jmenného prostoru. Celý můj problém spočíval v chybě při vyvolání rozhraní:
ip addr add dev $tun_tundv \
local $ifconfig_local/$ifconfig_cidr \
broadcast $ifconfig_broadcast \
scope link
Problém je v "odkazu na rozsah", který jsem špatně pochopil tak, že ovlivňuje pouze směrování. Způsobí, že jádro nastaví zdrojovou adresu všech paketů odeslaných do tunelu na 0.0.0.0
; pravděpodobně by je pak server OpenVPN zrušil jako neplatné podle RFC1122; i kdyby tomu tak nebylo, cíl by zjevně nebyl schopen odpovědět.
Všechno fungovalo správně bez síťových jmenných prostorů, protože vestavěný skript konfigurace sítě openvpn tuto chybu neudělal. A bez "odkazu na rozsah" funguje můj původní skript také.
(Jak jsem to zjistil, ptáte se? Spuštěním strace
v procesu openvpn nastavte na hexdump vše, co přečetl z deskriptoru tunelu, a poté ručně dekódujte hlavičky paketů.)
Chyba při pokusu o vytvoření zařízení veth je způsobena změnou způsobu ip
interpretuje argumenty příkazového řádku.
Správné vyvolání ip
vytvořit pár veth zařízení je
ip link add name veth0 type veth peer name veth1
(name
místo dev
)
Jak nyní dostat provoz z jmenného prostoru do tunelu VPN? Vzhledem k tomu, že máte k dispozici pouze zařízení tun, musí "hostitel" směrovat. Tj. vytvořte pár veth a vložte jeden do jmenného prostoru. Připojte druhý přes směrování do tunelu. Povolte tedy předávání a poté přidejte potřebné trasy.
Pro příklad předpokládejme, že eth0
je vaše hlavní rozhraní, tun0
je rozhraní vašeho tunelu VPN a veth0
/veth1
dvojice rozhraní, z nichž veth1
je ve jmenném prostoru. Do jmenného prostoru přidáte pouze výchozí trasu pro veth1
.
Na hostiteli musíte použít směrování zásad, viz například zde. Co musíte udělat:
Přidat/připojit záznam jako
1 vpn
na /etc/iproute2/rt_tables
. Tímto způsobem můžete volat (dosud nevytvořenou) tabulku jménem.
Potom použijte následující příkazy:
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
Nemohu to zde vyzkoušet s nastavením, jako je vaše, ale mělo by to dělat přesně to, co chcete. Můžete to rozšířit pravidly paketového filtru tak, aby nebyla rušena ani vpn, ani síť "hostů".
N.B. Přesouvám tun0
do jmenného prostoru na prvním místě vypadá jako správná věc. Ale stejně jako ty se mi to nepodařilo. Směrování zásad vypadá jako další správná věc. Řešení Mahendra je použitelné, pokud znáte sítě za VPN a všechny ostatní aplikace nikdy nebudou mít přístup k těmto sítím. Ale vaše počáteční podmínka („veškerý provoz a pouze provoz do/z konkrétních procesů prochází přes VPN") zní, jako by to nebylo možné zaručit.