![Как использовать nft на мосту Linux, чтобы заблокировать доступ к определенному IP-адресу?](https://rvso.com/image/789281/%D0%9A%D0%B0%D0%BA%20%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20nft%20%D0%BD%D0%B0%20%D0%BC%D0%BE%D1%81%D1%82%D1%83%20Linux%2C%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%20%D0%BA%20%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%BC%D1%83%20IP-%D0%B0%D0%B4%D1%80%D0%B5%D1%81%D1%83%3F.png)
У меня есть Ubuntu box с определенным мостом br0
. Мост подключен eth0
к интернет-сервису и eth1
подключен к сетевому порту ПК. Мост функционирует как и ожидалось и пропускает весь трафик между eth0
и eth1
.
Я хочу ввести правило, которое будет блокировать доступ к определенным внешним IP-адресам (например, 1.1.1.1) с ПК. Я предполагаю, nft
что это способ сделать это. Как мне написать правило, чтобы ничто не могло пройти, br0
идя на/от 1.1.1.1.
Целью здесь является возможность имитировать определенные отказы для тестирования.
решение1
Это делается с помощьюnftables'семья моста.
nftablesобеспечивает семейство мостов в качестве заменыebtables.
Создайте таблицу вмостсемья:
# nft add table bridge t
Создайте цепочку для фильтрации пересылаемых кадров:
# nft add chain bridge t c '{ type filter hook forward priority 0; policy accept; }'
Создайте правило, запрещающее IP-пакетамeth1для достижения 1.1.1.1:
# nft add rule bridge t c iif eth1 ether type ip ip daddr 1.1.1.1 drop
Вот и все, что касается межсетевого экрана без сохранения состояния.
СЯдро Linux 5.3 nftablesтакже имеет поддержку прямого межсетевого экрана с отслеживанием состояния вмостпуть:
Добавить собственную поддержку отслеживания соединений для моста. До этого патча единственным шансом для людей сделать фильтрацию с учетом состояния было использование
br_netfilter
слоя эмуляции, это шаг вперед к его отмене [...]
Это позволяет легко изолировать систему в одном направлении. Например, чтобы разрешить:
- входящий доступ к ПК по SSH
- исходящий доступ с ПК: ПК для использованияпинги DNS (
th
ниже обозначает оба варианта)tcpиудп) - ARP (без которого невозможно подключение по протоколу IPv4)
- все необходимоеответ трафика(как первое правило по соображениям производительности)
- и ничего больше
можно использовать:
# nft add rule bridge t c ct state related,established accept
# nft add rule bridge t c oif eth1 ether type ip tcp dport 22 accept
# nft add rule bridge t c iif eth1 ether type ip meta l4proto {tcp, udp} th dport 53 accept
# nft add rule bridge t c iif eth1 ether type ip icmp type echo-request accept
# nft add rule bridge t c ether type arp accept
# nft add rule bridge t c drop
Определенная факторизация, безусловно, возможна и должна быть рассмотрена (например, с использованием множеств иконкатенации).
Все вышеприведенные примеры не повлияют на саму коробку Ubuntu, которая все еще может достичь и быть достигнута обеими сторонами. Чтобы повлиять на трафик от ПК к коробке Ubuntu (или соответственно от коробки Ubuntu к ПК), те же самые правила могут быть сделаны на цепочке, подключающейсявход(соотв.выход) вместовперед.
Примечание:
Thebr_netfilter
модуль не должен быть загружен (включив по умолчанию свойство sysctl net.bridge.bridge-nf-call-iptables = 1
), чтобы избежать непредвиденных взаимодействий между собственнымимостправила иipсемейные правила, которые также влияютnftablesтак же хорошо, какiptables. Это значитСледует избегать запуска Docker или Kubernetes (два обычных пользователя br_netfilter
) на одной системе.при проведении сетевых экспериментов (но это все еще возможно при дополнительной осторожности, например: путем адаптацииэтот UL SE Q/A).
Загрузка br_netfilter
(и net.bridge.bridge-nf-call-iptables = 1
) введет вас в заблуждение, заставив думать, что нормальным способом работы будет фильтрация вipсемья вфильтр/впередкрючок. Это не обычный случай, иnftablesотсутствуют дополнительные функции, использующие это, такие какiptables'physdev
модуль соответствия: вместо этого целью всегда было сделать это изначально вмостсемья и не полагаться на br_netfilter
.
решение2
Если ваш хост Linux работает как маршрутизатор, вам также необходимо настроить ip_forwarding.
Чтобы ответить на ваш вопрос, вы можете использовать nftables следующим образом:
#!/usr/bin/nft
flush ruleset
table inet my_table {
chain INPUT {
iifname br0 saddr 1.1.1.1 drop
iifname br0 daddr 1.1.1.1 drop
}
chain FORWARD {
iifname br0 saddr 1.1.1.1 drop
iifname br0 daddr 1.1.1.1 drop
}
}
и выполните это с помощью nft -f /path/to/your/nft.file
Хотя это немного бесполезно (я знаю, что вы изучаете nftables, не воспринимайте это слишком серьезно). Лучшая практика — это отказаться от всего и разрешить только то, что требуется, то есть не отказываться от определенного трафика, а разрешить определенный трафик.
Я нашел документацию Red Hat 8 по nftables очень хорошей, возможно, вы сможете извлечь из нее столько же пользы, сколько и я: