Я не могу фильтровать пакеты Neighbor Advertising на основе поля целевого адреса, которое в пакетах этого типа известно как поле 'tgt'.
Сообщение, когда какое-то устройство с MAC aa:bb:cc:dd:ee:ff
пытается использовать адрес 2001:ffff:1002:51::
в Wireshark выглядит так:
src: fe80 :: aabb: ccff: fedd: eeff dst: ff02 :: 1 прото: ICMPv6 (тип 136) Информация: Neighbor Advertising 2001: ffff: 1002: 51 :: (rtr) находится по адресу aa: bb: cc: dd: ee: ff
Тот же пакет в tcpdump:
16:57:40.303118 IP6 fe80::aabb:ccff:fedd:eeff > ff02::1: ICMP6, neighbor advertisement, tgt is 2001:ffff:1002:51::, length 32
Оказывается, нет возможности отфильтровать их с помощью ip6tables, потому что он не дает возможности указать tgt
поле в icmpv6
прото. Их отсутствие затрудняет предотвращение атак отравления NDP на маршрутизаторах на базе Linux. Еще в 2010 году в списке рассылки netfilter был кто-то, кто сделал предположение о возможном существовании инструмента под названием ndptables в качестве альтернативы для arptables, используемого для IPv4, но эта идея потерпела неудачу.
Мне известно о SEcure Neighbor Discovery (SEND), которое можно было бы использовать для этого, но я не могу найти какой-либо достойной информации о том, как настроить его в Debian или Ubuntu.
Что следует использовать для фильтрации этих пакетов на маршрутизаторе под управлением Linux?
Я лично использую ipv6
и ipv4
в двойном стеке, но вы всегда можете заблокировать ipv6 icmpv6
с участием firehol
например.
ipv6 interface any v6interop proto icmpv6
policy drop
Если вы не хотите использовать firehol
попробуй проверить какие ip6tables
правила, созданные этим помощником. Больше информации Firehol doc
Я понял вашу точку зрения и провел несколько исследований, позвольте мне поделиться этим с вами:
Прежде всего, давайте перехватим пакет, который мы хотим заблокировать (136 = Neighbor Advertisement icmpv6
пакеты)
tcpdump -ttt -vvv -xx -n -i eno1 "icmp6 && ip6[40] == 136"
В результате я получил вот такой пакет например
00:00:05.054822 IP6 (class 0xe0, hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::2ff:ffff:feff:fffe > fe80::ec4:7aff:fed9:7d0e: [icmp6 sum ok] ICMP6, neighbor advertisement, length 32, tgt is fe80::2ff:ffff:feff:fffe, Flags [router, solicited, override]
destination link-address option (2), length 8 (1): 00:ff:ff:ff:ff:fe
0x0000: 00ff ffff fffe
0x0000: 0cc4 7ad9 7d0e 00ff ffff fffe 86dd 6e00
0x0010: 0000 0020 3aff fe80 0000 0000 0000 02ff
0x0020: ffff feff fffe fe80 0000 0000 0000 0ec4
0x0030: 7aff fed9 7d0e 8800 8f7a e000 0000 fe80
0x0040: 0000 0000 0000 02ff ffff feff fffe 0201
0x0050: 00ff ffff fffe
IPv6 IP имеет длину 40 байт, поэтому icmpv6
начать с 8800 8f7a e000 0000
и icmpv6 тело приходит после с fe80 0000 0000 0000 02ff ffff feff fffe
. Последняя часть согласно RFC Целевой адрес или tgt
.
Теперь посмотрим, как фильтровать эти пакеты с помощью ip6tables
. Я обнаружил два интересных модуля netfilter, string
и u32
. Я не понял, как фильтровать string
модуль, но u32
работает отлично.
Предполагая tgt
вы хотите заблокировать это fe80::2ff:ffff:feff:fffe
ip6tables
правило будет примерно таким
ip6tables -I INPUT 1 -p icmpv6 --icmpv6-type neighbor-advertisement -m u32 --u32 "48=0xfe800000 && 52=0x00000000 && 56=0x02ffffff && 60=0xfefffffe" -j LOG --log-prefix "Bad neighbor-advertisement tgt:"
Обратите внимание, что я не хочу блокировать его, просто зарегистрируйте данный пакет, чтобы увидеть, соответствует ли правило.
Aug 20 09:45:24 squanchy kernel: Bad neighbor-advertisement tgIN=eno1 OUT= MAC=0c:c4:7a:d9:7d:0e:00:ff:ff:ff:ff:fe:86:dd SRC=fe80:0000:0000:0000:02ff:ffff:feff:fffe DST=fe80:0000:0000:0000:0ec4:7aff:fed9:7d0e LEN=72 TC=224 HOPLIMIT=255 FLOWLBL=0 PROTO=ICMPv6 TYPE=136 CODE=0
Я снова бегу firehol
на моем сервере, поэтому журналы немного отличаются от того, что вы увидите с необработанными ip6tables
P.S учтите, что правило здесь основано на tgt
а не исходный адрес, который выглядит таким же, как tgt
поле.