Як запусціць адзін працэс Linux па-за тунелем WireGuard
Дайце адной праграме ўласны сеткавы кантэкст, каб яна выходзіла з хоста з поўным тунелем WireGuard, а затым выпраўце правілы перасылкі і маркіроўкі, якія яе блокуюць.
Вы не можаце вызваліць праграму ад хоста WireGuard з поўным тунелем, рэдагуючы маршруты. Маршруты выбіраюць шлях па прызначэнні, а вызваліць вы хочаце працэс, таму ядру няма з чым супастаўляць. Працаздольны падыход — даць гэтаму працэсу ўласны сеткавы кантэкст: прастора імёнаў з уласным інтэрфейсам, адрасамі і маршрутам па змаўчанні, злучаная з хостам парай veth. Я запускаў гэта на Ubuntu 24.04 з wireguard-tools 1.0.20210914, і прастора імёнаў ніколі не была праблемай — ёй былі палітыка перасылкі хоста і правілы маркіроўкі тунеля.
Спачатку абярыце тып кантэксту, які вам патрэбны
На практыцы сустракаюцца дзве формы. Калі хост трымае поўны тунель і адна праграма павінна выйсці праз шлях правайдэра, вы будуеце другую прастору імёнаў, злучаеце яе з хостам і дазваляеце хосту перасылаць і ператвараць трафік для яе. Калі прастора імёнаў ужо мае інтэрфейс VPN і вам патрэбна толькі каманда, запушчаная ўнутры яе, гэта звычайны ip netns exec выпадак, і большая частка працы з маршрутамі ўжо зроблена.
Ні адна з форм не дае вам правіла, абмежаванага адным ідэнтыфікатарам працэсу. Netfilter супастаўляе адрасы, порты, меткі і інтэрфейсы; табліцы маршрутаў для кожнага працэсу няма. Маркіроўка можа накіроўваць трафік, але метку трэба ставіць на пакеты, якія вы ўжо вызначылі, а гэта тая ж праблема на ўзровень ніжэй. Прастора імёнаў аддзяляе ўвесь стек для гэтага дрэва працэсаў, і менавіта таму гэта звычайны адказ.
Калі патрабаванне сапраўды ў тым, каб з тунеля нічога не выходзіла, спыніце замест гэтага тунель. Прастора імёнаў існуе для змяшанага выпадку: адна праграма вонкі, усё астатняе ўнутры, на адной машыне, адначасова.
Пабудуйце другі кантэкст і далучыце яго да хоста
Ілюстратыўная схема: хост мае інтэрфейс WireGuard, які нясе маршрут па змаўчанні, і сеткавую прастору імёнаў пад назвай clearnet злучаную з хостам парай veth. Адрасы ніжэй — прыклады.
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
Гэтая прастора імёнаў цяпер можа дасягнуць хоста і нічога больш. Хост павінен перасылаць трафік і перапісваць адрас крыніцы, бо 192.168.100.0/24 — прыватная, і ў вышэйшага маршрутызатара няма маршруту назад у яе:
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o <wan-interface> -j MASQUERADE
Пераканайцеся ў баку прасторы імёнаў, перш чым ісці далей.ip netns exec clearnet ip route павінна паказаць маршрут veth і маршрут па змаўчанні праз 192.168.100.1, а ping на гэты адрас павінен адказаць. Калі ping на адрас хоста не праходзіць, адрасы або стан злучэння няправільныя, і ніякае правіла фіярвола не дапаможа.
Калі імёны вырашаюцца, але нічога не вяртаецца, прачытайце FORWARD
Класічны збой выглядае як памылка маршрутызацыі: прастора імёнаў вырашае імя, пакет выходзіць, і адказ ніколі не прыходзіць. На хостах з палітыкай FORWARD DROP — так робяць некалькі дыстрыбутываў і большасць узмацнёных вобразаў — пакет адкідаецца па дарозе, і памылка, якую друкуе праграма, нічога не кажа пра фільтраванне.
Прачытайце ланцуг, перш чым нешта дадаваць:
iptables -S FORWARD
nft list chain inet filter forward
Затым прапусціце трафік у абодвух кірунках, з лічыльнікамі, каб ведаць, ці правіла калі-небудзь супала:
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'
Правіла з нулявым лічыльнікам пакетаў не ў шляху. Альбо імёны інтэрфейсаў адрозніваюцца ад тых, што вы меркавалі, альбо папярэдняе правіла ў ланцугу першым прыняло, адкінула або вярнула пакет. Выпраўце парадак, а не тэкст правіла.
Зваротны трафік — гэта палова, якую людзі забываюць. Правілу вяртання патрэбна тое ж імя veth плюс супастаўленне стану злучэння, альбо звычайнае прыняцце інтэрфейса, калі вы трымаеце палітыку адкрытай. Дадайце толькі правіла зыходу — і атрымаеце першапачатковы сімптом назад, а ваша новае правіла будзе выглядаць правільным.
Трымайце правілы маркіроўкі тунеля ў баку ад новага шляху
Гэты крок ператварае працаздольную прастору імёнаў у тую, што цячэ. Налады WireGuard звычайна ўсталёўваюць палітыку меткі фіярвола разам са сваімі правіламі маршрутызацыі і асобнай табліцай, таму пакеты без меткі вяртаюцца ў асноўную табліцу, а пакеты з меткай выкарыстоўваюць табліцу тунеля. Перасланы трафік з прасторы імёнаў ацэньваецца супраць палітычнай маршрутызацыі на выхадзе, і ў залежнасці ад таго, як напісаны гэтыя правілы, ён можа трапіць у табліцу тунеля.
Дзве дабаўкі раздзяляюць шляхі. Вярніцеся рана ў ланцугу mangle для падсеткі прасторы імёнаў і дадайце правіла на аснове крыніцы, якое змяшчае гэтую падсетку ў асноўную табліцу:
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
Прыярытэт 100 стаіць перад правіламі тунеля на маім хосце, таму для гэтай крыніцы вырашае звычайная табліца. Не капіруйце лік усляпую: прыярытэты, якія wg-quick усталёўвае, адрозніваюцца паміж версіямі і паміж наладамі IPv4 і IPv6, таму выканайце ip rule show і абярыце прыярытэт, які трапляе перад правіламі тунеля на вашай машыне.
Праверце пошукам па пэўнай крыніцы а не давяраючы спісу правілаў:
ip route get 1.1.1.1 from 192.168.100.2
ip netns exec clearnet ip route get 1.1.1.1
Калі першая каманда паведамляе інтэрфейс WireGuard, новае правіла яшчэ не перад палітыкай тунеля. Калі яна паведамляе інтэрфейс WAN, пакуль другая ўсё яшчэ паказвае маршрут па змаўчанні veth, хост і прастора імёнаў разыходзяцца, і вам трэба перачытаць абедзве табліцы маршрутаў.
Запусціце працэс, які адкрывае злучэнне
Запусціць каманду — адна радок, але запусціце працэс, які сапраўды стварае сокет.ip netns exec clearnet curl -s https://ifconfig.me гэта самы маленькі сумленны тэст: ён паказвае адрас, які прастора імёнаў паказвае свету, а не той, які выкарыстаў бы хост.
Для сэрвісу далучыце прастору імёнаў па шляху, каб працэс заставаўся ў ёй усё жыццё:
[Service]
NetworkNamespacePath=/run/netns/clearnet
Графічныя праграмы — гэта месца, дзе аднарадковы падыход ціха здае. Браўзер, запушчаны з меню, часта перадае запыт асобніку, які ўжо працуе па-за прасторай імёнаў, таму новае акно з'яўляецца, а трафік усё яшчэ выходзіць праз тунель. Дайце яму асобны профіль, каб новы асобнік сапраўды стварыўся, затым праверце кантэкст працэсу замест здагадак:
readlink /proc/$(pgrep -f clearnet-profile | head -1)/ns/net
readlink /run/netns/clearnet
Два выхады павінны супадаць. Тая ж праверка працуе для любой доўгажывучы праграмы, і варта рабіць яе раз на праграму, а не меркаваць, што запускальнік зрабіў тое, што вы мелі на ўвазе.
Вырашэнне імёнаў патрабуе ўласнага рашэння. Стварэнне прасторы імёнаў не дае ёй канфігурацыі рэзалвера; файлы для кожнай прасторы імёнаў падтрымліваюцца праз /etc/netns/<name>/resolv.conf і без яго вы атрымліваеце ў спадчыну паводзіны, якія лёгка прачытаць няправільна. IPv6 патрабуе таго ж: калі ў прасторы імёнаў няма маршруту па змаўчанні v6, пакуль праграма аддае перавагу v6, запыты могуць застойвацца перад вяртаннем, што выглядае як зламаны тунель.
Праверце афармленне, а не толькі адрас выхаду
Працаздольны публічны адрас даказвае маршрут, а не ўсё патрабаванне. Прайдзіце астатняе ў такім парадку:
ip netns exec clearnet ip route get 1.1.1.1паказвае маршрут па змаўчанні veth, а не інтэрфейс WireGuard.- Лічыльнікі FORWARD на абодвух правілах растуць, пакуль выконваецца запыт.
- Працэс праграмы паведамляе чаканы inode прасторы імёнаў.
- Пасля перазапуску прастора імёнаў існуе да старту сэрвісу; юніт, які запускаецца раней, церпіць няўдачу, або, што горш, працуе па-за прасторай імёнаў.
Затым вырашыце, што павінна адбывацца, калі тунель падае. Прастора імёнаў працягвае працаваць, і гэта мэта практыкавання, а таксама рызыка: вызваленая праграма застаецца падключанай, пакуль усё астатняе спыняецца. Запішыце гэта як палітычны выбар і будзьце яснымі ў тым, што вызваленне не пакрывае — ідэнтычнасць уліковага запісу, захаваны стан браўзера і ваш пастаўшчык DNS — усё гэта знаходзіцца па-за межамі сеткавай прасторы імёнаў, і стаўленне да вызвалення як да ананімнасці — гэта памылка, якая перажывае канфігурацыю.