- Вопрос или проблема
- Шаг 1, определите отдельную таблицу nft.
- Шаг 2, добавьте выделенную таблицу маршрутизации для pbr
- Шаг 3, создайте маршрут в таблице для приема всего трафика
- Шаг 4, критический шаг, создайте ip rule для обрабатывания fwmark
- Шаг 5, используйте любой предпочитаемый вами метод, чтобы добавлять элементы в nftset
- Ответ или решение
- Настройка маршрутизации трафика по fwmark через VPN-шлюз с использованием nftables
- 1. Создание таблицы для маршрутизации
- 2. Настройка правил маркировки трафика
- 3. Настройка маршрутов для таблицы
- 4. Проверка правил маршрутизации
- 5. Тестирование и отладка
- Заключение
Вопрос или проблема
Я пытаюсь настроить избирательную маршрутизацию трафика, отфильтрованного по IP-адресу, через OpenVPN на своем роутере OpenWRT
У меня есть профиль OpenVPN, который работает с опцией route-nopull для отключения настройки шлюза по умолчанию.
Следующие команды предназначены для того, чтобы пакеты, направленные на набор IP-адресов и помеченные меткой 0x1 в секции mangle prerouting:
nft add set inet fw4 marker { type ipv4_addr \;}
nft add element inet fw4 marker {40.81.94.43}
nft insert rule inet fw4 mangle_prerouting ip daddr @marker counter meta mark set 0x1
Затем я настроил таблицу маршрутизации ip для маршрутизации помеченных пакетов через шлюз VPN:
ip rule add fwmark 1 table vpn
ip route add default via 10.211.1.118 dev tun_vpn table vpn
Эта настройка не работает по какой-то причине: трафик просто проходит через шлюз по умолчанию wan, хотя счетчик nft показывает, что пакеты попадают в правило маркировки.
Однако, если я явно устанавливаю таблицу маршрутизации для использования для IP-адреса, это работает, как ожидалось:
ip rule add to 40.81.94.43 table vpn
направляет трафик к 40.81.94.43 через шлюз VPN, как и предполагалось
Кажется, либо nft не помечает пакеты меткой 0x1, либо ip rule add fwmark 1
по какой-то причине не фиксирует это.
Что я упускаю?
Я узнал МНОГО из этого вопроса, но поскольку конфигурация nftables не “с легкостью” для всех, я хочу поделиться своей конфигурацией, я постараюсь поделиться как можно более подробно, чтобы кто-то мог получить более интуитивное представление о том, как сделать pbr с помощью nftables:
Шаг 1, определите отдельную таблицу nft.
table inet classify {
set pbrips {
type ipv4_addr
elements = { 1.0.0.1, 8.8.4.4,
8.8.8.8 }
}
chain output {
type route hook output priority filter; policy accept;
# Это должно быть ^^^^^ маршрут, а не фильтр
ip daddr @pbrips counter packets 29795 bytes 3021764 ct mark set 0x00000002
ip daddr @pbrips counter packets 29795 bytes 3021764 meta mark set ct mark
}
chain prerouting {
type filter hook prerouting priority mangle; policy accept;
ip daddr @pbrips counter packets 193712 bytes 60796012 ct mark set 0x00000002
ip daddr @pbrips counter packets 193712 bytes 60796012 meta mark set ct mark
}
}
Здесь я определил отдельную таблицу, называемую classify, вместо того чтобы использовать существующую таблицу fw4
OpenWRT 23.05, я делаю это, потому что пытался манипулировать непосредственно таблицей fw4
, но это, похоже, не дало эффекта.
В таблице я определил набор nft с именем pbrips
, с некоторыми предопределенными IP-адресами (в моем случае я всегда буду перенаправлять эти IP-адреса). В этом наборе каждый IP предназначен для маршрутизации на другой интерфейс вместо шлюза по умолчанию, таким образом, это называется маршрутизация на основе политик, т.е. pbr.
Вы, может быть, заметили часть counter packets 29795 bytes 3021764, она генерируется автоматически nftables, когда вы создаете правила, и вам нужно только обыкновенная директива counter
.
По какой-то причине мне нужно разместить там две цепочки: цепочку output
и цепочку prerouting
, пожалуйста, обратите внимание на хуки, используемые внутри каждой цепочки, они являются ключевыми точками, если вы хотите перенаправить трафик. Причина, по которой я разместил две цепочки здесь, заключается в том, что если я использую только цепочку output, только трафик (связанный с 3 IP-адресами в наборе) от самого роутера OpenWRT может быть перенаправлен, в то время как с цепочкой prerouting весь трафик из моей LAN может быть правильно перенаправлен (п.с. Если кто-то знает, пожалуйста, напомните мне, как это исправить Спасибо!)
Шаг 2, добавьте выделенную таблицу маршрутизации для pbr
Вот мой /etc/iproute2/rt_tables
:
root@OpenWrt:~# cat /etc/iproute2/rt_tables
#
# зарезервированные значения
#
128 prelocal
255 local
254 main
253 default
0 unspec
#
# локальный
#
#1 inr.ruhep
123 pbr
Вы можете видеть в последней строке, что я добавил новую таблицу с идентификатором 123
и именем pbr
, вы можете использовать любой идентификатор и имя здесь, просто не используйте уже существующие выше, они являются значениями системного уровня. вы можете редактировать этот файл напрямую с vi и сохранять его
Шаг 3, создайте маршрут в таблице для приема всего трафика
Вот мой вывод ip route list table 123
(обратите внимание, что вы можете ссылаться на таблицу как по ее идентификатору, так и по ее имени, оба варианта правильны)
root@OpenWrt:~# ip route list table 123
default dev tun0 scope link
root@OpenWrt:~#
Как видите, в таблице 123 только одно правило, и если вы хотите перенаправить весь трафик через таблицу 123, этого маршрута достаточно.
Шаг 4, критический шаг, создайте ip rule для обрабатывания fwmark
Вот мой вывод ip rule
root@OpenWrt:~# ip rule
0: from all lookup local
32765: from all fwmark 0x2 lookup pbr
32766: from all lookup main
32767: from all lookup default
root@OpenWrt:~#
И ключевой момент здесь заключается в третьей строке, т.е. в части fwmark 0x2
, здесь 0x2 относится к шестнадцатеричному значению 2, но шестнадцатеричное значение 0x2 эквивалентно десятичному значению 2, и значение в моем nft правиле – 0x00000002
, потому что 0x00000002
– это точно то же самое шестнадцатеричное значение, что и 0x2
, и оба равны десятичному значению 2
, я рекомендую всегда использовать десятичное значение, как 1,2,3, а не 0x1,0x2,0x3, чтобы не путаться (как я делал раньше)
Шаг 5, используйте любой предпочитаемый вами метод, чтобы добавлять элементы в nftset
Пока вы добавляете новые элементы (т.е. IP-адреса) в nftset pbrips
, вы можете протестировать это через traceroute 8.8.8.8
, чтобы проверить, работает ли политика pbr или нет. Теоретически вы готовы к работе сейчас.
И еще раз спасибо, Алексей Мартемьянов, за ваш вопрос и ваш ответ как хорошую ссылку, чтобы помочь мне изучить pbr!
Отвечая на свой вопрос, на случай если это может быть полезно кому-то:
После нахождения темы “[РЕШЕНО] iproute2 игнорирует отметки соединений, установленные с помощью nftables” я обновил набор правил nft до следующего:
nft insert rule inet fw4 mangle_prerouting ip daddr @marker counter ct mark set 390
nft add rule inet fw4 mangle_prerouting ip daddr @marker counter meta mark set ct mark
И это сработало!
Выяснилось, что мне нужно было установить отметку соединения, а не мета-отметку
Ответ или решение
Настройка маршрутизации трафика по fwmark через VPN-шлюз с использованием nftables
Проблема, с которой вы столкнулись, связана с маршрутизацией трафика по определённым IP-адресам через VPN-шлюз с использованием OpenVPN и nftables на маршрутизаторе OpenWRT. Давайте рассмотрим шаги, необходимые для корректной реализации данной задачи.
1. Создание таблицы для маршрутизации
Для начала необходимо определить таблицу в nftables и добавить в неё набор IP-адресов, которые будут помечены при обработке трафика.
nft add table inet fw4
nft add set inet fw4 marker { type ipv4_addr \; }
nft add element inet fw4 marker {40.81.94.43}
2. Настройка правил маркировки трафика
Мы будем использовать цепочку prerouting
для маркировки входящего трафика. В вашем случае, первоначально использовались правила, которые устанавливали meta mark
. Вместо этого следует установить ct mark
, чтобы iproute2 смог обнаружить это метки.
nft insert rule inet fw4 mangle_prerouting ip daddr @marker counter ct mark set 0x1
Это правило обеспечивает маркировку соединений, что является ключевым моментом, так как iproute2 будет использовать маркировку соединений для маршрутизации.
3. Настройка маршрутов для таблицы
Создайте отдельную таблицу в /etc/iproute2/rt_tables
, если вы этого ещё не сделали:
echo "123 pbr" >> /etc/iproute2/rt_tables
Затем добавьте маршрут в таблицу, который будет использоваться для трафика, помеченного fwmark
.
ip rule add fwmark 0x1 table pbr
ip route add default via 10.211.1.118 dev tun_vpn table pbr
4. Проверка правил маршрутизации
Проверьте все правила, чтобы убедиться, что ваши настройки применены корректно.
ip rule show
Убедитесь, что правило с fwmark
настроено правильно и отображает ожидаемый идентификатор.
5. Тестирование и отладка
После всех настроек протестируйте маршрутизацию. Используйте команду traceroute
для проверки, проходит ли трафик через VPN:
traceroute 40.81.94.43
Если всё настроено правильно, трафик должен маршрутизироваться через VPN-шлюз, как вы и планировали.
Заключение
Проблема с тем, что трафик продолжает маршрутизироваться через основной шлюз, скорее всего, возникает из-за неправильного использования меток. Убедитесь, что вы используете ct mark
для маркировки соединений, так как это позволяет iproute2 корректно идентифицировать трафик для маршрутизации. С настройками, описанными выше, ваша конфигурация должна работать корректно.
При необходимости вы можете расширить набор IP-адресов и адаптировать настройки под свои нужды. Надеемся, что эта информация будет полезной для вас.