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. Адказ-рэха, які дайшоў да 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 расказвае тую ж гісторыю для перанакіраваных партоў.
Апошняя праверка — тая, якую людзі прапускаюць: паўтарыце пошук пасля таго, як тунель апусціўся і зноў падняўся. Чатыры значэнні павінны супасці з тым, што вы запісалі: пункт прызначэння, наступны хоп, прылада і абраная крыніца. Калі хоць адно зрушылася, кліент перапісаў табліцу, і выпраўленне належыць яго хукам, а не гісторыі shell.