Program z hostitele WireGuard s plným tunelem nevyjmete úpravou tras. Trasy volí cestu podle cíle, a vy chcete vyjmout proces, takže jádro nemá co porovnávat. Schůdný přístup je dát tomu procesu vlastní síťový kontext: jmenný prostor s vlastním rozhraním, adresami a výchozí trasou, připojený k hostiteli párem veth. Spustil jsem to na Ubuntu 24.04 s wireguard-tools 1.0.20210914 a jmenný prostor nikdy nebyl problém — problémem byla politika předávání na hostiteli a pravidla značení tunelu.

Nejprve zvolte druh kontextu, který potřebujete

V praxi se objevují dvě podoby. Pokud hostitel provozuje plný tunel a jeden program má odejít cestou ISP, postavíte druhý jmenný prostor, připojíte ho k hostiteli a necháte hostitele, aby za něj prováděl předávání a překlad. Pokud už jmenný prostor nese rozhraní VPN a potřebujete jen příkaz spuštěný uvnitř, jde o obvyklý případ ip netns exec a většina práce s routováním je hotová.

Ani jedna podoba vám nedá pravidlo omezené na jedno ID procesu. Netfilter porovnává adresy, porty, značky a rozhraní; tabulka tras pro každý proces neexistuje. Značení může provoz usměrnit, ale značka se musí aplikovat na pakety, které jste už identifikovali, což je stejný problém o vrstvu níž. Jmenný prostor odděluje celý zásobník pro ten strom procesů, a proto je obvyklou odpovědí.

Pokud je požadavek skutečně takový, že z tunelu nic neodejde, raději tunel zastavte. Jmenný prostor existuje pro smíšený případ: jeden program ven, vše ostatní dovnitř, na stejném stroji, ve stejnou dobu.

Postavte druhý kontext a připojte ho k hostiteli

Ilustrativní uspořádání: hostitel má rozhraní WireGuard nesoucí výchozí trasu a síťový jmenný prostor nazvaný clearnet připojený k hostiteli párem veth. Adresy níže jsou příklady.

ip netns add clearnet
ip link add veth-clear-out type veth peer name veth-clear-in
ip addr add 192.168.100.1/24 dev veth-clear-out
ip link set veth-clear-out up
ip link set veth-clear-in netns clearnet
ip netns exec clearnet ip addr add 192.168.100.2/24 dev veth-clear-in
ip netns exec clearnet ip link set veth-clear-in up
ip netns exec clearnet ip route add default via 192.168.100.1

Tento jmenný prostor teď dosáhne na hostitele a na nic jiného. Hostitel musí provoz předávat a přepisovat zdrojovou adresu, protože 192.168.100.0/24 je soukromá a nadřazený router nemá cestu zpět do ní:

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o <wan-interface> -j MASQUERADE

Než budete pokračovat, ověřte stranu jmenného prostoru.ip netns exec clearnet ip route má ukázat trasu veth a výchozí trasu přes 192.168.100.1 a ping na tuto adresu má odpovědět. Pokud ping na adresu hostitele selže, adresy nebo stav spoje jsou špatné a žádné pravidlo firewallu nepomůže.

Když se jména přeloží, ale nic se nevrací, přečtěte FORWARD

Klasické selhání vypadá jako chyba routování: jmenný prostor přeloží jméno, paket odejde a odpověď nikdy nedorazí. Na hostitelích s politikou FORWARD DROP — tak to dělá několik distribucí a většina zpevněných obrazů — se paket cestou zahodí a chyba, kterou aplikace vypíše, o filtrování nic neříká.

Přečtěte řetězec, než cokoli přidáte:

iptables -S FORWARD
nft list chain inet filter forward

Potom propusťte provoz v obou směrech, s počítadly, abyste poznali, zda pravidlo někdy odpovídalo:

iptables -A FORWARD -i veth-clear-out -o <wan-interface> -j ACCEPT
iptables -A FORWARD -i <wan-interface> -o veth-clear-out -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
watch -n1 'iptables -L FORWARD -v -n'

Pravidlo s nulovým počítadlem paketů není na cestě. Buď se názvy rozhraní liší od předpokladu, nebo dřívější pravidlo v řetězci paket přijalo, zahodilo či vrátilo první. Opravte pořadí, ne text pravidla.

Odpovědní provoz je polovina, na kterou se zapomíná. Pravidlo návratu potřebuje stejný název veth plus shodu stavu spojení, nebo obyčejné přijetí rozhraní, pokud politiku držíte otevřenou. Přidejte jen odchozí pravidlo a původní příznak se vrátí, zatímco vaše nové pravidlo tam stojí a vypadá správně.

Držte pravidla značení tunelu mimo novou cestu

Tento krok promění fungující jmenný prostor v prosakující. Nastavení WireGuard obvykle instalují politiku značky firewallu spolu s vlastními pravidly routování a vyhrazenou tabulkou, takže neoznačené pakety spadnou do hlavní tabulky, zatímco označené používají tabulku tunelu. Předávaný provoz z jmenného prostoru se na cestě ven vyhodnocuje proti politickému routování a podle toho, jak jsou tato pravidla napsaná, může skončit v tabulce tunelu.

Dva doplňky cesty oddělí. Vraťte se brzy v řetězci mangle pro podsíť jmenného prostoru a přidejte pravidlo založené na zdroji, které tuto podsíť umístí do hlavní tabulky:

iptables -t mangle -I PREROUTING -s 192.168.100.0/24 -j RETURN
ip rule add from 192.168.100.0/24 lookup main priority 100

Priorita 100 se na mém hostiteli řadí před pravidly tunelu, takže pro tento zdroj rozhoduje běžná tabulka. Neopisujte číslo naslepo: priority, které wg-quick instaluje, se liší mezi verzemi a mezi nastaveními IPv4 a IPv6, proto spusťte ip rule show a vyberte prioritu, která na vašem stroji padne před pravidla tunelu.

Ověřte pomocí vyhledání specifického pro zdroj místo spoléhání na seznam pravidel:

ip route get 1.1.1.1 from 192.168.100.2
ip netns exec clearnet ip route get 1.1.1.1

Pokud první příkaz hlásí rozhraní WireGuard, nové pravidlo ještě není před politikou tunelu. Pokud hlásí rozhraní WAN, zatímco druhý stále ukazuje výchozí trasu veth, hostitel a jmenný prostor se neshodují a měli byste obě tabulky tras přečíst znovu.

Spusťte proces, který otevírá spojení

Spustit příkaz je jeden řádek, ale spusťte proces, který skutečně vytváří socket.ip netns exec clearnet curl -s https://ifconfig.me je nejmenší poctivý test: ukazuje adresu, kterou jmenný prostor představuje světu, ne tu, kterou by použil hostitel.

U služby připojte jmenný prostor cestou, aby v něm proces zůstal celý život:

[Service]
NetworkNamespacePath=/run/netns/clearnet

Grafické aplikace jsou místem, kde jednorádkový přístup tiše selhává. Prohlížeč spuštěný z nabídky často předá požadavek instanci, která už běží mimo jmenný prostor, takže se objeví nové okno a provoz stále odchází tunelem. Dejte mu samostatný profil, aby se skutečně vytvořila nová instance, a pak zkontrolujte kontext procesu místo hádání:

readlink /proc/$(pgrep -f clearnet-profile | head -1)/ns/net
readlink /run/netns/clearnet

Oba výstupy se musí shodovat. Stejná kontrola funguje pro každý dlouho běžící program a stojí za to ji udělat jednou na aplikaci, místo abyste předpokládali, že spouštěč udělal, co jste mysleli.

Překlad jmen potřebuje vlastní rozhodnutí. Vytvoření jmenného prostoru mu nedá konfiguraci resolveru; soubory pro jednotlivé jmenné prostory jsou podporovány přes /etc/netns/<name>/resolv.conf a bez něj zdědíte chování, které se snadno přečte špatně. IPv6 potřebuje stejné zacházení: pokud jmenný prostor nemá výchozí trasu v6, zatímco aplikace dává přednost v6, požadavky se mohou zaseknout před návratem, což vypadá jako rozbitý tunel.

Zkontrolujte rámování, ne jen výstupní adresu

Fungující veřejná adresa dokazuje trasu, ne celý požadavek. Projděte zbytek v tomto pořadí:

  • ip netns exec clearnet ip route get 1.1.1.1 ukazuje výchozí trasu veth, ne rozhraní WireGuard.
  • Počítadla FORWARD na obou pravidlech rostou, dokud požadavek běží.
  • Proces aplikace hlásí inode jmenného prostoru, který očekáváte.
  • Po restartu jmenný prostor existuje dřív, než služba začne; unit, který běží dřív, selže, nebo co je horší, běží mimo jmenný prostor.

Pak rozhodněte, co se má stát, když tunel spadne. Jmenný prostor funguje dál, což je smysl cvičení a zároveň riziko: vyjmutý program zůstává připojený, zatímco všechno ostatní se zastaví. Zapište to jako rozhodnutí politiky a buďte jasní v tom, co výjimka nepokrývá — identita účtu, uložený stav prohlížeče a váš poskytovatel DNS stojí všechny mimo rozsah síťového jmenného prostoru, a považovat výjimku za anonymitu je chyba, která přežije konfiguraci.

Související články