Три WireGuard скока стижу до мреже без јавне адресе, а затим средња машина престаје да одговара на порту на којем је требало да слуша. Тунел даље и даље ради, удаљени домаћин и даље одговара, и само је средњи сервер утихнуо споља. Та комбинација збуњује управо зато што је сама себи нанета: средњи скок слуша своју сопствену табелу рутирања, а табела шаље његове одговоре на погрешну страну.

Ланац који ради док не проговориш са средњом кутијом

Узмите илустративан ланац: клијент A стиже до сервера B преко UDP 500, а B иде даље до сервера C преко UDP 500. C прихвата саобраћај само са адресе свог јединог партнера, што га чини листом и одржава његово понашање једноставним. B није лист, и све занимљиво у вези са овим кваром дешава се управо тамо.

Разлика је важна јер улоге листа и средине вуку у супротним смеровима. Лист може послати све у један тунел без последица, јер ништа друго не зависи од њега. Средњи скок је истовремено крајња тачка за клијенте и клијент према удаљеној страни, а та два посла желе различито рутирање.

Зашто одговор излази кроз тунел

На B, интерфејс окренут ка C носи AllowedIPs = 0.0.0.0/0 заједно са одговарајућом подразумеваном рутом. Зато сваки пакет који B створи одлази у тај тунел, осим ако нешто конкретније не добије предност.

Пакет од A упућен B стиже и бива прихваћен, јер је B одредиште и локална достава се дешава прва. Одговор је потпуно нов, локално генерисан пакет усмерен на A-ову јавну адресу, а то одредиште одговара подразумеваној рути у тунел. C га прима, не поседује ту адресу и одбацује га.

Симптом изгледа као проблем са заштитним зидом или неусклађеност кључа, а овде ниједно није тачно. Снимак на тунелу према C показује да одговори иду у погрешном смеру. То једно запажање штеди више времена од било каквог читања конфигурације, па га запишите пре него што почнете да мењате кључеве. Свако ко није видео снимак претпоставиће да је сам тунел покварен.

Уско поправљање: правила политике која одговарају изворном порту

Одговори са B-овог сокета за слушање излазе са изворним портом 500. Правило политике може се поклопити с тим и вратити те пакете назад у обичну табелу:

ip rule add sport 500 table main priority 100
ip rule add sport 8080 table main priority 101

Правила политике се прегледају по редоследу приоритета, а главна табела стоји на 32766, па се правило на 100 пита пре него што подразумевана рута тунела добије реч. Додајте по један унос за сваки порт који мора остати доступан споља и ништа више, како би прослеђени саобраћај наставио да користи тунел за који је направљен.

Знајте границу овог трика. Селектор sport одговара локално генерисаним пакетима, што покрива тачно случај одговора и намерно не покрива саобраћај који B само прослеђује за неког другог. Услуга хостована иза B и даље захтева сопствени одговор, а тврђење супротног даје поправку која ради за прву услугу а пада за другу.

Дајте правилу власника

Правило откуцано у командној линији нестаје следећи пут кад се интерфејс поново изгради. У WireGuard подешавању ставите га тамо где се интерфејс ствара и уклања:

PostUp = ip rule add sport 500 table main priority 100
PostDown = ip rule del sport 500 table main priority 100

Ако интерфејсом управља NetworkManager, хук дистрибуције или улазна тачка контејнера, пар припада том власнику, а не ручно уређеној датотеци. Проверите ефективна правила након поновног повезивања, не само након првог покретања, јер је прво покретање случај који увек ради.

Упоредите алтернативе искрено

Правило изворног порта један је од четири излаза и најужји је од њих. Предност му је што уопште не дира политику тунела, због чега обично преживи касније измене. Уске поправке такође гласно падају кад престану да важе, док широки изузетак тихо наставља да ради дуго након што је разлог за њега нестао. Та разлика је важнија од елеганције кад после две године кутијом управља неко други.

ApproachWhat it costsWhere it breaks
Source-port policy ruleOne rule per exposed portAnything B forwards rather than originates
Destination exception routeA route pinned to specific client addressesClients whose address changes
Stop full-tunnelling on BLoses the catch-all path toward CDesigns that depend on it
Split into two tunnelsMore interfaces and more policyNothing, at the cost of complexity

Проверите са оба краја након што одаберете. Са A стране започните везу ка B-овом порту и држите је заузетом неко време. На B натерајте кернел да оправда пут одговора нечим попут ip route get <address-of-A> sport 500 и потврдите да наводи WAN интерфејс, а не тунел. Након тога проверите да нешто иза C још увек одговара кроз ланац, што доказује да је изузетак остао узак уместо да се претвори у заобилазницу. На крају запишите портове у дизајнерске белешке, иначе следећи оператер открије ово на другој услузи.

Повезани чланци