Предупреждаю сразу: это пост батхерта!
Тут ко мне обратился френд с довольно простой задачей - необходимо работать из страны А с IP-адресом из страны B, но только так, чтобы адрес не палился как датацентр. То бишь с резидентным IP-шником. Нашли человека в стране B, который оказался готовым за более дорогой тариф интернета разместить у себя точку выхода VPN и попросили меня рассказать как это сделать.
Сам я давно являюсь приверженцем OpenWrt, но исходя из технического (с точки зрения прошивки девайсов кастомными прошивками) уровня моего собеседника, я понимал, что квест купить Redmi и прошить его OpenWrt не для него, а тем более не для резидента страны B. Нужно было решение, которое можно купить на местном маркетплейсе и воткнуть его. Когда-то давно я был наслышан, что Keenetic - это что-то типа брендированного OpenWrt, кроме того, на глаза попадались статьи на Хабре (правда я их не читал) о том, как на Keenetic можно взгромоздить хоть XTLS-Reality, поэтому порекомендовал обоим поставить по такому роутеру. Да и в общем-то альтернативных решений из коробки я точно не знаю больше, если не брать в расчёт Microtik - который из-за санкций я им советовать не стал.
Сказано - сделано. Дальше начинается процесс настройки. Настройка усугублялась тем, что в стране B (по крайней мере у того провайдера, к которому подключен резидент) не предоставляются (даже за доп.плату) белые IPv4 адреса - роутер получает адрес из серого сегмента 100.64.0.0/10. Зато белый IP-шник можно получить в стране A.
Наклёвывался такой setup - роутер B подключается к роутеру A, чтобы установить какой-нибудь VPN, чтобы потом гнать по этому VPN-у интернет трафик через B. В качестве протокола был выбран WireGuard так как он в этом плане симметричный: не важно, кто является сервером VPN - раздачей интернета может заниматься любой peer. Downside такой схемы в том, что по ней нету готовой инструкции, поэтому наш герой снова вернулся ко мне с задачей настройки.
Без меня они успели уже поднять WireGuard, который горел в обеих адмиках зелененьким, хэндшейки периодически обновлялись, но пинги не шли.
Приступив, мне стало понятно, что для начала не хватало банальных маршрутов. Добавили ручные маршруты и роутеры стали пинговать друг друга через WireGuard. Но дальше дело не шло - роутер на первом хопе провайдера B не пинговался с роутера A.
Первое что приходит в голову - это то, что необходимо делать NAT и подменять source IP для пакетов, приходящих на роутер B с роутера A. Потому что скорее всего маршрутизация пакетов в WAN интерфейс происходила, но роутер провайдера ничего не знал про IP-адреса роутера A, чтобы дать ответ.
И тут вот первая непонятнка с этими Keenetic'ами: роутер B успешно выполняет NAT для адресов домашней сети резидента B. Почему он это делает? Где это включается? Почему этого не происходит для пакетов с интерфейса wireguard? Все эти вопросы без ответа.
Начать с того, что управление самим NAT'ом возможно только через CLI. Тут ждал первый сюрприз. Я был уверен, что если Keenetic - это брендированный OpenWrt, то попав в него через ssh я попаду в Linux и сделаю там хоть чёрта лысого. Но вместо этого меня ждал какой-то Cisco-подобный шел с крайне урезанными возможностями. Я не являюсь спецом по кискам, и никогда их не конфигурил, поэтому я не знаю на сколько реализация CLI Keenetic соответствует кискам, но первое что меня потрясло: я могу, допустим, включить NAT командой ip nat <interface>
, могу выключить командой no ip nat <interface>
, но я нигде не могу посмотреть статус NAT на интерфейсе. Команда show ip nat
показывает просто текущую таблицу NAT, show interface <interface>
тоже вопрос не проясняла.
А нужно это хотя бы для того, чтобы понять, где его, NAT, включать и в этом ли проблема. В норме, когда настраиваешь masquerading на Linux, то вешаешь его на postrouting на исходящий интерфейс. И я бы предполагал, что и в Keenetic он будет включаться на WAN интерфейсе, для того, чтобы домашний трафик резидента B успешно "натился". Но как выяснилось в Кинетиках эта логика переиначена - включается NAT для интерфейса, через который пакет попадает в роутер. Узнал я об этом случайно, надыбав команду show running-config
, которая выплевывает всю конфигурацию, и там, пролистав пару экранов, можно заметить места, на каких интерфейсах включается NAT. Офигительно удобно (нет)!
Ну что ж - включил NAT для интерфейса Wireguard0, и..... Не помогло. Я беру конфиг wireguard для роутера B и подключаюсь вместо него к роутеру A своим лэптопом с Linux, настраиваю у себя masquerading для пакетов с iifname этого интерфейса и всё работает - через меня вся домашняя сеть за роутером А успешно может ходить в интернет. Значит проблема точно на роутере B.
И вот что дальше делать - совершенно не понятно. Нет никакого способа удаленно соснифать какие пакеты отправляются на провайдерский роутер нет - tcpdump отсутствует. Да, возможно его можно поставить через opkg, но беглый гугл говорит о том, что для этого в роутер надо вставить USB-флэшку, а её у резидента B нет. Настроить логирование пакетов, что делает за 5 минут через nftables я не могу, так как к nft нету доступа. Тупик.
Пара часов гадания на кофейной гуще, и чисто случайно меняю на роурете B маску IP-адреса интерфейса Wireguard0 с /32 на /24 (изначально не я настраивал туннель), и всё начинает работать - а заодно появляется автоматический маршрут, аналог которого был добавлен руками. Что это? Почему это? Где документировано, что NAT не работает, если у интерфейса маска /32? Как вообще это можно диагностировать?
В общем первое знакомство с кинетиками меня обожгло и больше я никому не буду рекомендовать это решение.
Если тут есть представители Кинетика, то расскажите — зачем вы взяли охренительно мощный и гибкий инструмент под названием Linux и кастрировали его своим шелом? Причем безальтернативно. Лавры Apple по ограничению возможностей своих девайсов не дают покоя? Или захотелось стать киской для домохозяек? Самое печальное во всей этой истории, что команды управления сетевой конфигурацией имплементированы в какой‑то внутренней логике создателей и совершенно не понятно во что они выливаются на уровне линукса и какие side effect'ы они порождают, и что самое главное - это никак не проверить, запустив пару линуксовых команд.
Автор: dmitrmax