VPN клиент на LAN сървър: защо отговорите излизат по грешния път
Хост, който се свързва с VPN, получава маршрут по подразбиране, затова отговорите към LAN клиенти излизат през тунела. Добавете по-тесния обратен маршрут и го проверете.
Симптомите следват една форма: хост работи, после се свързва с VPN като клиент, и сега LAN клиентите го достигат, докато отговорите му изчезват. Прихващане на хоста показва, че отговорите излизат през устройството на тунела, а не през LAN интерфейса. В тунела нищо не е счупено и поправката е маршрут, а не повторно свързване. Изпълнете четирите проверки по-долу по ред и спрете на първата, която се провали.
Отговорът е нов пакет, а не обръщане на пътя
Полезно е да изоставите идеята, че отговорът се връща по пътя, по който е минала заявката. Маршрутизацията се решава за всеки пакет и за всяка посока на изпращащия хост. Заявка, пристигнала от 10.64.0.23 в тунела, не създава обратен път; когато хостът отговори, този отговор се сравнява с таблицата като нов пакет и излиза по маршрута, който победи.
Затова клиент с пълен тунел на машина, която също обслужва LAN, дава такава объркваща повреда. Клиентът инсталира маршрут по подразбиране или двата полумаршрута по подразбиране, които някои клиенти предпочитат, и отговорът към LAN клиент вече съвпада с тунела. Той отива при доставчика, който няма причина да го препраща, а LAN клиентът вижда таймаут, въпреки че хостът работи и отговаря локално. Прихващането го прави очевидно, а таблицата за маршрутизация го обяснява.
Дръжте две подмрежи в главата си, докато четете останалото. Едната е пулът с VPN адреси, от който идват отдалечените клиенти, в този пример 10.64.0.0/24. Другата е LAN, която трябва да продължи да работи, 172.16.24.0/24 с нейния рутер на 172.16.24.1. Проблемът е, че трафикът между тях се решава от маршрута по подразбиране.
Докажете го с прихващането и справката
Преди да промените нещо, потвърдете кое устройство ще използва отговорът. Справката е по-бърза от прихващане и отговаря на точния въпрос, на който ядрото ще отговори при изграждането на пакета.
ip route get 10.64.0.23 from 172.16.24.10
tcpdump -ni any -c 6 icmp
Четете отговора на две части. Ако посочва dev tun0, хостът ще инкапсулира отговора и ще го предаде на доставчика, и LAN клиентът никога няма да го види. Ако посочва dev eth0, но клиентът все още получава таймаут, маршрутът вече е правилен и пакетът се изхвърля по-късно, което е друг проблем с друга поправка.
Прихващането в същата стъпка решава съмнението, което ping не може. Пристигнал echo отговор при LAN клиента доказва, че някакъв път работи, а не кой интерфейс го е пренесъл, затова правете прихващането на самия хост и гледайте откъде излизат кадрите. Принтер в същата подмрежа продължава да отговаря, защото директният му маршрут е по-конкретен от маршрута на тунела по подразбиране. Пренасочен порт се проваля точно като всеки друг поток, защото интерфейсът се избира от таблицата, а не от връзката.
Инсталирайте най-тесния маршрут, който превъзхожда тунела
Решава дължината на префикса, а не метриката, затова маршрут за пула клиенти през LAN рутера побеждава всеки маршрут по подразбиране, който VPN клиентът инсталира. Не е нужна хирургия на метрики и маршрутът по подразбиране може да остане точно там, където клиентът го е поставил.
ip route replace 10.64.0.0/24 via 172.16.24.1 dev eth0
ip route get 10.64.0.23 from 172.16.24.10
Използвайте replace, а не add, защото клиент, който се свърже отново, ще е инсталирал своя запис и вторият add се проваля с грешка за съществуващ маршрут, която звучи като проблем с права. На Windows хост еквивалентът е route add 10.64.0.0 mask 255.255.255.0 172.16.24.1 -p, където -p запазва записа между рестартиранията, тъй като клиентът може да преустрои таблицата, когато тунелът отново се вдигне. На съвременен Windows хост поддържаният еквивалент е New-NetRoute -DestinationPrefix 10.64.0.0/24 -NextHop 172.16.24.1 -InterfaceAlias Ethernet -PolicyStore PersistentStore, а по-старата команда route се запазва като наследена форма.
Една подробност решава дали това е правилно, или само правдоподобно: следващият хоп трябва да е рутерът, който действително притежава пътя обратно към клиентите. Насочването на маршрута към адрес, който сам се достига през тунела, създава цикъл, който се проявява като периодична загуба, а не като чист провал. Потвърдете, че следващият хоп е в LAN подмрежата, преди да въведете реда.
Запазете отговора след повторно свързване
Маршрут, добавен на ръка, оцелява в най-добрия случай до следващото повторно свързване. Ако пулът клиенти е динамичен, закрепете го в конфигурацията на сървъра, за да остане префиксът, който сте маршрутизирали, префиксът, който клиентите получават; иначе записът сочи към празен диапазон и симптомът се връща седмици по-късно без очевидна причина. Записването на маршрута в собствения up-скрипт на клиента е другата надеждна опция, защото той се изпълнява, след като клиентът е пренаписал таблицата.
Пакетен филтър със състояние може да победи правилен маршрут. Ако прихващането сега показва, че отговорът излиза през eth0, а клиентът все още получава таймаут, проверете дали хостът не изхвърля пакета преди изпращане. Строга филтрация на обратния път и net.ipv4.conf.all.rp_filter, зададен на 1, изхвърлят пакети, чийто източник не би се маршрутизирал обратно през интерфейса, по който са пристигнали, което е точно асиметричният случай, който току-що създадохте и после поправихте, а състоянието на conntrack разказва същата история за пренасочените портове.
Последната проверка е тази, която хората пропускат: повторете справката, след като тунелът е паднал и се е вдигнал отново. Четири стойности трябва да съвпадат с това, което сте записали: дестинацията, следващият хоп, устройството и избраният източник. Ако някое от тях се е преместило, клиентът е пренаписал таблицата и поправката принадлежи на неговите hook-ове, а не на историята на shell.