Как заблокировать входящие фрагменты IPv6?
У меня проблема с настройкой брандмауэра. Я хотел бы заблокировать все фрагментированные пакеты 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
1 ответ
Как уже было сказано, вы должны быть уверены, что блокирование фрагментов - это действительно ваша цель, а не метод, который, по вашему мнению, лучше всего подходит для вашей цели, в то время как существуют лучшие методы. Во всяком случае, для чего это стоит, вы должны:
используйте достаточно свежее ядро. Функция была добавлена в ядро 4.16. CentOS использует 3.10. Хотя многие функции перенесены в бэкпорт (начиная с nftables, который недоступен в ядре vanilla 3.10, но есть в RHEL/CentOS 3.10), эта функция не была перенесена в последнюю версию ядра CentOS 7.6. Поскольку вы используете ядро "elrepo" 5.0.8, эта функция присутствует. Вот описание функции и почему она существует (в основном для маршрутизации или, по крайней мере, для ситуаций с брандмауэрами без сохранения состояния / без NAT):
Сетевой фильтр: nf_defrag:
Пропустить дефрагментацию, если установлено NOTRACK. Контрарагивание дефрагментации необходимо, только если какой-либо модуль, такой как CONNTRACK или NAT, явно запрашивает его. Для простых сценариев пересылки дефрагментация не требуется и может быть пропущена, если в правиле установлен NOTRACK.
Поскольку дефрагментация conntrack в настоящее время имеет более высокий приоритет, чем необработанная таблица, настройка NOTRACK не является достаточной. Нам нужно перейти на более высокий приоритет только для iptables.
Это достигается введением параметра модуля raw_before_defrag, который позволяет изменить приоритет необработанной таблицы для ее размещения перед дефрагментацией. По умолчанию параметр отключен, и приоритет необработанной таблицы - NF_IP_PRI_RAW для поддержки устаревшего поведения. Если параметр модуля включен, то приоритет необработанной таблицы устанавливается на NF_IP_PRI_RAW_BEFORE_DEFRAG.
(при необходимости удалите существующие необработанные правила ip6tables, выгрузите и) загрузите
ip6table_raw
модуль с параметромraw_before_defrag=1
Таким образом, хук необработанного кода (в 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 от defrag, которая не активируется до первой необходимости. Вот пример сетевого пространства имен:
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
Правило, это также будет блокировать пинг-пакеты (3 из них на пинг), но на этот раз снова в filter/INPUT
цепь:
ip netns exec receiver ip6tables -t raw -A PREROUTING -m ipv6header --header ipv6-frag --soft -j CT --notrack
Это только пример, который не имеет особого смысла.