Դուք չեք կարող ծրագիրն ազատել լրիվ թունելով WireGuard հոսթից՝ երթուղիները խմբագրելով։ Երթուղիները ուղի են ընտրում ըստ նպատակակետի, իսկ այն, ինչ ուզում եք ազատել, պրոցես է, ուստի միջուկը համեմատելու բան չունի։ Աշխատունակ մոտեցումն այն է, որ այդ պրոցեսին տրվի իր սեփական ցանցային համատեքստը՝ անվանատարածք իր ինտերֆեյսով, հասցեներով և լռելյայն երթուղիով, որը veth զույգով միացված է հոսթին։ Ես սա գործարկել եմ Ubuntu 24.04-ում wireguard-tools 1.0.20210914-ով, և անվանատարածքը երբեք խնդիր չի եղել — խնդիրը հոսթի փոխանցման քաղաքականությունն ու թունելի նշման կանոններն էին։

Նախ ընտրեք ձեզ անհրաժեշտ համատեքստի տեսակը

Գործնականում երկու ձև է հանդիպում։ Եթե հոսթը գործարկում է լրիվ թունել, և մեկ ծրագիր պետք է դուրս գա ISP-ի ուղիով, դուք կառուցում եք երկրորդ անվանատարածք, միացնում այն հոսթին և թույլ տալիս, որ հոսթը փոխանցի ու թարգմանի երթևեկությունը նրա համար։ Եթե անվանատարածքն արդեն կրում է 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-ը ձախողվի, հասցեները կամ կապի վիճակը սխալ են, և ոչ մի firewall կանոն չի օգնի։

Երբ անունները լուծվում են, բայց ոչինչ չի վերադառնում, կարդացեք 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 տեղադրումները սովորաբար տեղադրում են firewall-ի նշանի քաղաքականություն՝ իրենց երթուղային կանոններով և առանձին աղյուսակով, այնպես որ չնշված փաթեթները վերադառնում են հիմնական աղյուսակ, իսկ նշված փաթեթները օգտագործում են թունելի աղյուսակը։ Անվանատարածքից փոխանցված երթևեկությունը դուրս գալիս գնահատվում է քաղաքականության վրա հիմնված երթուղման դեմ, և կախված նրանից, թե ինչպես են գրված այդ կանոնները, այն կարող է հայտնվել թունելի աղյուսակում։

Երկու հավելումներն առանձնացնում են ուղիները։ Վերադարձեք շուտ 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 լռելյայնը, հոսթն ու անվանատարածքը համաձայն չեն, և դուք պետք է վերընթերցեք երկու երթուղային աղյուսակները։

Գործարկեք այն պրոցեսը, որը բացում է կապը

Հրամանը գործարկելը մեկ տող է, բայց գործարկեք այն պրոցեսը, որը իրականում ստեղծում է socket-ը։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

Երկու ելքերը պետք է համընկնեն։ Նույն ստուգումը աշխատում է ցանկացած երկարատև ծրագրի համար, և արժե այն անել մեկ անգամ յուրաքանչյուր ծրագրի համար՝ փոխարենը չենթադրելով, որ գործարկիչը արել է այն, ինչ դուք նկատի ունեիք։

Անունների լուծումը պահանջում է իր սեփական որոշումը։ Անվանատարածք ստեղծելը նրան resolver-ի կարգավորում չի տալիս, անվանատարածքով ֆայլերը աջակցվում են /etc/netns/<name>/resolv.conf միջոցով, և առանց դրա դուք ժառանգում եք վարքագիծ, որը հեշտ է սխալ կարդալ։ IPv6-ը նույն վերաբերմունքի կարիքն ունի, եթե անվանատարածքը v6 լռելյայն երթուղի չունի, մինչ ծրագիրը նախընտրում է v6-ը, հարցումները կարող են կանգ առնել նահանջելուց առաջ, ինչը նման է կոտրված թունելի։

Ստուգեք շրջանակը, ոչ միայն ելքի հասցեն

Աշխատող հանրային հասցեն ապացուցում է երթուղին, ոչ ամբողջ պահանջը։ Անցեք մնացածը այս հերթականությամբ:

  • ip netns exec clearnet ip route get 1.1.1.1 ցույց է տալիս veth լռելյայնը, ոչ WireGuard ինտերֆեյսը։
  • Երկու կանոնների FORWARD հաշվիչները աճում են, քանի դեռ հարցումը ընթանում է։
  • Ծրագրի պրոցեսը հայտնում է անվանատարածքի այն inode-ը, որը դուք սպասում եք։
  • Վերագործարկումից հետո անվանատարածքը գոյություն ունի մինչ ծառայության մեկնարկը, ավելի վաղ աշխատող unit-ը ձախողվում է, կամ ավելի վատ՝ աշխատում է անվանատարածքից դուրս։

Ապա որոշեք, թե ինչ պետք է տեղի ունենա, երբ թունելն ընկնի։ Անվանատարածքը շարունակում է աշխատել, ինչը վարժության նպատակն է և միևնույն ժամանակ ռիսկը, ազատված ծրագիրը մնում է միացված, մինչ մնացած ամեն ինչ կանգ է առնում։ Գրանցեք դա որպես քաղաքականության ընտրություն և եղեք պարզ այն հարցում, թե ինչ չի ծածկում ազատումը — հաշվի ինքնությունը, պահպանված բրաուզերի վիճակը և ձեր DNS մատակարարը բոլորն էլ գտնվում են ցանցային անվանատարածքի սահմաններից դուրս, և ազատումը որպես անանունություն դիտարկելը այն սխալն է, որը գոյատևում է կարգավորումից։

Առնչվող հոդվածներ