Есть роутер OpenWRT 22.03 (с nftables). Провайдер выдаёт динамический IP адрес из частного диапазона - 10.что-то-там. Ну и как обычно есть интерфейсы br0 - 192.168.1.1 и wan - 10.что-то-там от провайдера. Я хочу, чтоб некоторые сайты грузились через vpn.
Ставлю wireguard. Для внутренней сети wg использую сетку 192.168.2.. Сервер - 192.168.2.1, openWRT роутер - 192.168.2.2. Настраиваю интерфейс wg0 на роутере openWRT. Ставлю и настраиваю wg на VPN сервере, чтоб он всё с адресами 192.168.1. (и всё с внутренних адресов wg - 192.168.2.*) отправлял в интерфейс wg0. Настраиваю masquerading на wg vpn сервере для транзитных пакетов роутер -> wg0 -> internet.
Проверяю - маршрутизация работает. Все кого надо видят, пингуют.
Создаю ipset на роутере OpenWRT и хочу, чтоб все адреса из этого ipset грузились через wg vpn сервер.
Настраиваю роутер OpenWRT. Для проходящего трафика от клиентов всё работает - добавляю nft цепочку type filter hook prerouting. Всем пакетам из LAN: from br0 to мой_ip_set добавляю mark. Создаю дополнительную таблицу ip route, которая всё отправляет в интерфейс wg0 по умолчанию. Настраиваю ip rule, которая по моему mark, который я установил в nft цепочке активирует дополнительную таблицу ip route. Из локалки приходит пакет, nft его помечает, включается ip rule, активируется специальная ip route talbe пакет уходит в интерфейс wg0, всё хорошо, все смеются, все довольны.
Проверяю клиента в локалке - всё работает как надо - сайты из моего_ip_set-а грузятся через wg. Запускаю curl на роутере с параметром –interface wg0 - всё работает - нужные сайты грузятся через wg.
Теперь хочу, чтоб обычный исходящий траффик от процессов самого роутера OpenWRT работал так же и определенные ip адреса грузил через wg. Создаю цепочку в nftables hook output, помечаю пакеты тем же mark, не работает. Логично. Потому что исходящие пакеты имеют адрес 10.что-то-там, который мне дал провайдер. И интерфейс wg на VPN сервере их просто отбрасывает, потому что для wg на VPN сервере настроен Peer.AllowedIPs=192.168.1.* + внутренний адрес wg - 192.168.2.2.
Почему-то правило nft ip saddr set _правильный_IP_
не работает - в conntrack вижу оригинальный, неправильный IP - 10.что-то-там, полученный от провайдера. (Правильный ip адрес - это, например, 192.168.1.1, или 192.168.2.2).
Вопрос - как через nftables дёшево подменить source address. Рабочие варианты:
- использовать snat в nftables цепочке type nat hook postrouting. Мне не нравится - не хочется на ровном месте делать nat
- добавить правило в таблицу маршрутизации: ip rule add to ip table my_table. Я так понимаю в этом случае правила выполняются перед nftables и пакеты сразу получают правильный ip адрес. Нерабочий вариант - таблица маршрутизации не предназначена для такого, не потянет, неправильно, плохо
- добавить адрес от провайдера 10.что-то-там в список адресов wg интерфейса на wg VPN сервере. Рабоче, но криво.
- сделать, чтоб адресом по умолчанию на OpenWRT сервере был локальный адрес 192.168.1.1, настроить snat вместо masquerading. Сразу два минуса - адрес от провайдера надо будет прописывать в конфигурации. Весь траффик от локальных процессов OpenWRT в интернет пойдёт через snat.
- всё-таки сделать, чтоб заработал nftables stateless nat. Тем более, что в документации пишут, что это работает, надо просто отключить connection tracking. Вроде отключил, соединение не показывается в conntrack, но маршрутизация не работает - может sateless nat несовместим с mark/fwmark. Например на [stack exchange пишут|https://serverfault.com/questions/1100976/routing-fwmark-to-vpn-gateway-using-nftables-mark], что route rule используют connectiontrack, а не packet mark. Я не смог нагуглить точно что есть fwmark - mark, или ct mark.
Поэтому хотелось бы более прямого и надёжного решения - как изменить source interface или source ip address для некоторых destintaion IP. Что-то гуглил-гуглил и ничего не понял. Подскажите, чем сможете.
Конфиги не выкладываю, но если что выложу. Для простоты немного упростил названия интерфейсов и ip адреса.
PS: вот человек выложил [инструкцию на github-е|https://github.com/bol-van/zapret/blob/master/docs/wireguard/wireguard_iproute_openwrt.txt]. Он пишет то же самое - для использования wg interface локальными процессами роутера надо либо настроить snat, либо добавить локальный