У меня проблема с настройкой брандмауэра. Я хотел бы заблокировать все фрагментированные пакеты IPv6 в определенном интерфейсе. Итак, я попробовал:
# ip6tables -A INPUT -d <ipv6_address> -i eth0 -m ipv6header --header ipv6-frag --soft -j DROP
Но фрагментированный трафик IPv6 продолжает поступать.
Я также нашел эту ссылку: https://www.secfu.net/2015/03/25/how-to-block-incoming-ipv6-fragments-in-latest-red-hat-releases/ это объясняет, что ipv6-frag или frag не блокируют фрагментированный трафик ipv6 в последней версии CentOS, потому что после идентификатора ошибки 1011214 (kernel-2.6.32-437.el6) netfilter начал обрабатывать повторно собранный пакет вместо фрагментов, как это делает IPv4 . В той же статье предлагается использовать nftables, который будет выглядеть следующим образом:
table ip6 filter {
chain preroute500 {
type filter hook prerouting priority -500; policy accept;
ip6 nexthdr ipv6-frag counter packets 2 bytes 2104
}
}
Как я могу сделать что-то подобное с помощью ip6tables?
# cat /etc/system-release
CentOS Linux release 7.5.1804 (Core)
# uname -r
5.0.8-1.el7.elrepo.x86_64
Как уже было сказано, вы должны быть уверены, что блокировка фрагментов действительно является вашей целью, а не методом, который, по вашему мнению, лучше всего подходит для вашей цели, хотя существуют более эффективные методы. В любом случае, вы должны:
используйте достаточно свежее ядро. В характерная черта был добавлено в ядре 4.16. CentOS использует 3.10. Хотя многие функции имеют обратный перенос (начиная с nftables, который недоступен в ядре vanilla 3.10, но есть в RHEL / CentOS 3.10), эта функция не была перенесена на последнее ядро CentOS 7.6. Поскольку вы используете ядро "elrepo" 5.0.8, эта функция присутствует. Вот описание функции и почему она существует (в основном для маршрутизации или, по крайней мере, для ситуаций маршрутизации межсетевого экрана без отслеживания состояния / без NAT):
netfilter: nf_defrag:
Пропустить дефрагментацию, если установлено NOTRACK. Дефрагментация conntrack необходима только в том случае, если какой-либо модуль, например CONNTRACK или NAT, явно запрашивает ее. Для простых сценариев пересылки дефрагментация не требуется, и ее можно пропустить, если в правиле установлен NOTRACK.
Поскольку conntrack defrag в настоящее время имеет более высокий приоритет, чем необработанная таблица, установки NOTRACK недостаточно. Нам нужно переместить raw на более высокий приоритет только для iptables.
Это достигается за счет введения параметра модуля raw_before_defrag, который позволяет изменить приоритет исходной таблицы, чтобы поместить ее перед дефрагментацией. По умолчанию параметр отключен, а приоритет необработанной таблицы равен NF_IP_PRI_RAW для поддержки устаревшего поведения. Если параметр модуля включен, то приоритет необработанной таблицы устанавливается на NF_IP_PRI_RAW_BEFORE_DEFRAG.
(при необходимости удалите существующие необработанные правила ip6tables, выгрузите и) загрузите ip6table_raw
модуль с параметром raw_before_defrag=1
, поэтому обработчик raw (в PREROUTING) переключается с prio -300 на -450, перед дефрагментацией -400.
modprobe ip6table_raw raw_before_defrag=1
который должен получить сообщение ядра вроде ip6table_raw: Enabling raw table before defrag
Теперь в raw
таблица, и, вероятно, имеет смысл только в PREROUTING
, ip6tables сможете увидеть фрагменты. Он может фильтровать их там или пропустить conntrack (iptables -t raw -A PREROUTING ... -j CT --notrack
), который, как объясняется в патче функции, также пропускает дефрагментацию, позволяя другим цепочкам обрабатывать их (конечно, не включая nat
цепочки таблиц или любые другие функции, связанные с conntrack).
Обратите внимание, чтобы засвидетельствовать описанная проблема в тестовом сетевом пространстве имен необходимо сначала искусственно включить Conntrack операции для Conntrackзависимость от дефрагментировать, который не активируется, пока не понадобится. Вот пример сетевого пространства имен:
ip netns add sender
ip netns add receiver
ip -n sender link add veth0 address 02:00:00:00:00:01 type veth peer netns receiver name veth0 address 02:00:00:00:00:02
ip -n sender link set veth0 up
ip -n receiver link set veth0 up
Это работает:
# ip netns exec sender ping6 -s 4000 fe80::ff:fe00:2%veth0
PING fe80::ff:fe00:2%veth0(fe80::ff:fe00:2%veth0) 4000 data bytes
4008 bytes from fe80::ff:fe00:2%veth0: icmp_seq=1 ttl=64 time=0.069 ms
^C
После этого больше работать не будет:
ip netns exec receiver ip6tables -A INPUT -m ipv6header --header ipv6-frag --soft -j DROP
однажды Conntrack активируется в сетевом пространстве имен с этими командами, очевидно, приводящими к бездействию:
ip netns exec receiver ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED
ip netns exec receiver ip6tables -D INPUT -m conntrack --ctstate ESTABLISHED
также активируется дефрагментация ipv6. Теперь предыдущий пинг будет работать всегда, потому что правило в INPUT видит только дефрагментированные пакеты.
С ранее (повторно) загруженным ip6table_raw
модуль с параметром raw_before_defrag=1
, это восстановит блокировку фрагментированного пинга:
ip netns exec receiver ip6tables -t raw -A PREROUTING -m ipv6header --header ipv6-frag --soft -j DROP
Как вариант, интересные пакеты можно пометить как notrack, таким образом освобождая их от Conntrack, таким образом не получая дефрагментировать обработки, позволяя им снова фильтроваться с правилом в filter/INPUT
цепь. Так что вместо предыдущего raw
Правило, это также заблокировало бы пакеты ping (3 из них на ping), но на этот раз снова в filter/INPUT
цепочка:
ip netns exec receiver ip6tables -t raw -A PREROUTING -m ipv6header --header ipv6-frag --soft -j CT --notrack
Это всего лишь пример, который не имеет особого смысла.