Назад | Перейти на главную страницу

Предотвращение спуфинга IPv6 NDP в Linux

Я не могу фильтровать пакеты 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

Редактировать на основе комментариев

Я понял вашу точку зрения и провел несколько исследований, позвольте мне поделиться этим с вами:

Как заблокировать трафик icmpv6 на основе целевого адреса (tgt)

Прежде всего, давайте перехватим пакет, который мы хотим заблокировать (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 поле.