Комментарии 61
Хабр торт и не торт. Великолепная статья, и уже почти два часа ни одного комментария. Я прямо представляю сколько автор это ковырял, как писал эту статью и насколько обидно что нет ни одного комментария по делу. На самом деле даже сложно что-то комментировать, очень много очень полезной информации
Спасибо.
А почему, когда IP-адреса на интерфейсе нет — сетевой стек отбрасывает пакет. Почему бы не принимать бродкаст-пакеты?
Процитирую Бориса Лыточкина :)
Если очень грубо, для обработки ip-пакетов (через raw socket), в том числе броадкасты, сетевому стеку нужен настроенный ip-адрес. Собственно, именно так и работает dhcp-сервер. и чтобы получать броадкаст-поток с интерфейса и выдавать адреса он требует наличия адреса из раздаваемой сети, иначе не запустится.
raw socket - это raw ip socket, для него нужен сконфигурированный на интерфейсе IP стек. иначе работать нужно уже на уровне ethernet. Например, через bpf
Я однажды задал похожую, но намного более простую, задачку на собеседовании: "как работает ping". Хотел услышать хотя бы просто рассуждения на тему, даже не рассказ про RAW socket. А целый CCIE из интегратора мне сказал: "Ну вы же понимаете, как сдается CCIE..."
icmp, osi level 2 protocol инкапсулируется в айпи пакет и использует 7,8,9,11 типы. Баян молодости)
UPD: запрос идёт с 8 типом, добавил его. А ответы в дампе могут быть уже 7,9,11 типов.
Ты просто не CCIE
Да, всё так. Почему-то огромную сложность для понимания вызывает тот факт, что icmp reply отвечает само ядро ОС, а не какой-то сторонний daemon. И что мы можем, например, написать свой обработчик, отключив этот механизм через "echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all" (в linux)
level 2?
я тоже думал что 3й, но по факту второй. ICMP можно в fc сетях использовать, если из актуальных рассматривать.
А там именно icmp 8 0 используется, которая прямо на уровне фреймов инкапсулируется, или просто одноименная имплементация?
Потому что так-то и ATM ping и OSI ping (это не опечатка) существовали, но это просто название одинаковое.
Вам не кажется что вы напрашиваетесь уже на статью по истории развития вычислительных сетей?) Как сказали ниже, я не CCIE)
Насколько я могу судить там своя имплементация протокола.
Очень познавательно, спасибо!
Мне вот почему-то кажется, что я блокировал DHCP на L2 firewall в RouterOS (мы понимаем, что это тот же linux плюс минус). У MikroTik в стеке есть отличный L2 firewall, который решает различные задачи, как раз до L3 (неожиданно )), мне больше всего нравится элегантность так называемого transpered firewall. А как насчет защиты от ложных (вредительских) DHCP-серверов дела обстоят в Linux, где это настраивается?
Жаль только, что почти любые (кроме vlan фильтрации) правила bridge filter ломают bridge fast path на большей части свич-чипов и пользовать железку на гигабите с натом становится невозможно.
Вы не уловили суть: речь о блокировке на стороне клиента, а не о транзитном трафике.
офигеть...
я бы заблочил выше на свиче с помощью acl?
Боря Лыточкин и Паша Пушкарёв
Закидывайте лекцию в ExYa уже -)
https://yandex.ru/yaintern/training/devops-training
Выяснилось в личке, что если достаточно долго скроллить и смотреть глазами, а не как я, то записи там есть -)
Спасибо )
А какой практический смысл блокировки протокола? Если у вас есть сервер раздающий адреса, значит вам это нужно. Если вы не желаете получать адрес, то указываете его статическим и останавливаете клиент. И т.д.
Все эти задачи с подковыркой оторванные от реально опыта сделают специалиста хакером. Он будет хернёй на работе страдать с гордостью, конечно, но всё же. И будет думать, что занят скучными и бесполезными делами и от того хотеть "крутых" задач. И, возможно, создавать невероятные проблемы, которые можно героически решать.
А надо чтобы всё было по стандартам сделано. Скучно, да, но стандартно, чтобы когда уйдёшь с работы ваша смена смогла быстро понять почему на хосте dhclient не работает.
В итоге выяснилось, что вы давали задачу не убедившись, что она имеет решение, которого она не имеет. Я бы не стал считать допустимым решением задачи написание сишного кода. Такое нередко имеет отрицательные последствия, разделяя людей на тех кто уважает стандарты и тех кто стандарты не уважает.
Смысл в том, что это даёт понимание "а как эта штуковина вообще говоря работает", и мир начинает чуть меньше состоять из магии.
Это было интересное чтиво, но применять полученное от его прочтения знание — негде, кроме парочки сверхузких ниш.
Так что оно обязательно забудется. И мир начинает чуть меньше состоять из магии на этом закончится.
Зато ребята вот нашли, где на практике применить XDP-программку с пользой для дела)
Несомненно )
Но польза одноразового прочтения развлекательных статей — а вне связей с профессиональной деятелньностью любое чтение будет развлекательным, несмотря на его хардкорность — слишком переоценена.
З.Ы. Ваша статья получилась весьма хардконой, большое вам спасибо за труд )
У вас какая-то разнарядка на изучение eBPF?
В 2 из 4 просмотренных лекций авторы говорят "очень хочу изучить, но никак не найду времени", ещё один знающий его решил не грузить и без того сложный урок, а в последней тема статьи.
Для тех кто пользуется документацией в линуксе нет магии. Вопрос был не "зачем вы занимались этим увлекательным исследованием?", а "зачем вы даёте задачи, которые сами не можете решить?" и которые без как раз "магии" решить не сможет никто.
Вы меня, конечно, извините, но
Сначала мы убрали эту задачку под звёздочку. Подумали — убрали под две. А потом вообще исключили из домашки.
Да, мы потом после нашего исследования предложили тем, кто чувствует в себе силу, посмотреть на это. Но как-то градус вашей категоричности не соответствует такой формулировке.
Простите, если я излишне резок в своих выражениях. Моё грандиозное почтение, кстати, за циклы замечательных статей "Для самых маленьких". Я упустил слово "домашка" и видимо подумал про условия найма, и думал что речь идёт о будущих сотрудниках в штате системных/сетевых администраторов. Бесспорно, поддерживать в учениках увлечённость и любознательность благое дело.
И тут на сцену победным шагом выходит tc
О, да, я как-то про него вообще забыл написать.
Добрыйвечер.
Да, причём именно в egress направлении замечательно фильтруется. Вешаем любую classfull дисциплину и навешиваем несложный фильтр. Например:
~/# tc q add dev <iface> root handle 1: prio
~/# tc f add dev <iface> parent 1: protocol ip prio 1 flower ip_src 0.0.0.0/32 ip_dst 255.255.255.255 ip_protocol udp src_port 68 dst_port 67 action drop
Но нужно дополнительно исследовать поведение, когда на сокете выставлена опция PACKET_QDISC_BYPASS
. Тут я навскидку не скажу - надо читать код ядра.
Для ядер, начиная с 5.16 доступен дополнительный способ вместо tc - там добавлен хук netdev/egress, который можно использовать из nftables.
~/# nft -i
nft> flush ruleset
nft> add table netdev t
nft> add chain netdev t egress_chain { type filter hook egress device <iface> priority 0; }
nft> add rule netdev t egress_chain ip saddr 0.0.0.0/32 ip daddr 255.255.255.255/32 meta l4proto udp udp sport 68 udp dport 67 counter drop
А вот в направлении ingress фильтрация через tc / nftables обламывается, потому что клонирование пакета происходит раньше, чем эти инструменты вступают в работу. Это можно увидеть на прекрасной диаграмме из вики (на ней есть неточности, так что не верьте всему и перепроверяйте всегда).
UPD: ни через tc, ни через netdev / ingress хук невозможно заблокировать получение датаграм на сокеты af_packet / pf_packet, т.к. клонирование происходит вот здесь (при условии, что у нас в системе есть фильтры, которые отбирают данные датаграммы; если таких фильтров нет, то и клонирования не происходит - т.н. ленивое поведение), а обработка tc qdisc ingress происходит чуть дальше по коду, и только после происходит обработка через netdev / ingress хук. Так что, похоже, XDP является одним из немногих оставшихся вариантов дропнуть подобный трафик, т.к. выполнение XDP программы происходит чуть раньше, чем происходит клонирование датаграммы.
На вход - да, af/pf_packet не дропнешь т.к. они раньше происходят. Я писал именно в контексте конкретной задачи "дропнуть на клиенте dhcp запросы". @eucariotдаже ближе к концу статьи сокрушался о том, что заблокировался только ответный трафик, но не исходящий.
Хотяяяяя... А если отправлять пакеты через af_packet и mmap tx ring...? Кажется опять придётся запускать коллайдер.
блин, насколько же проще забанить DHCP кому-то со стороны сервера DHCP или где-то по дороге :-D
спасибо за погружение!
Эта статья настолько хороша, что я не поленился зарегистрироваться на хабре, чтобы просто поблагодарить вас. За 30 минут я узнал больше нового, чем за предшествующий месяц. Не уверен, что будет случай применить эти знания на практике, но, на какой-то момент у меня отпала челюсть.
Остаётся загадкой, как всякие Cilium блокируют Egress
Во-первых, при помощи tc, а не XDP. XDP используется только на железках, на veth (и прочих виртуальных устройствах) его использовать смысла нет, так как skb все равно создается. (Кроме этого, xdpgeneric кривой, а нативный xdp на veth еще более кривой.)
Во-вторых, tc программа сажается на внешний кусок veth, находящийся в рутовом namespace, так как внутренний может быть доступен приложению внутри контейнера, которое может поменять логику BPF программы. (Это поменяется, когда мы станем использовать новый виртуальный девайс netkit, см. https://lpc.events/event/17/contributions/1581/ и сможем сажать программу прямо внутрь.)
А насчет сабжа у меня когда-то был dhcpclient на XDP (https://github.com/aspsk/xdp-dhcp), который сажался на tap и отвечал виртуалочке.
Просто интересно, а как с этим дело обстоит во FreeBSD и других ос?
Пунтим вопрос обратно на мозг: как так iptables пакет считает в статистику, но не может дропнуть? Или может?
На стековерфлоу есть ответ на вопрос, почему счётчики правил для отбрасывания пакетов инкрементируются (и эти пакеты на самом деле дропаются), а dhcp клиент продолжает работать без проблем.
Мне, как человеку, который раньше точно блокировал DHCP через iptables было интересно узнать, что теперь там во всю BPF и просто так уже не получится
Спасибо за статью! Было интересно покопаться. У dhclient
есть флаг -v
и он может многое прояснить :)
Пунтим вопрос обратно на мозг: как так
iptables
пакет считает в статистику, но не может дропнуть? Или может?Тут можно обойтись простыми вещами: делаем два правила в iptables(один по маку, второй по
UDP
) и смотрим счётчики. Становится ясно что никакого квантового пакета не появляется и расщепление происходит где-то раньше. Если ещё и поднятьnetcat
наUDP
то без iptables правил ончто-то
получит. А если заблокировать - то нет.Как
libpcap
видит все пакеты, которые никак не захватываются никакими*tables
?А это уже на отдельную статью по
libpcap
скорее тянет :)
Тут у нас другая лаба. Два неймспейса в виртуалке: в одном DHCP-клиент, в другом — DHCP-сервер. Они соединены друг с другом через veth-пару.
Нет ли здесь какого-то подвоха? Будет ли работать предложенное решение с оригинальной постановкой задачи, или нельзя просто так взять и завести XDP в общем случае?
Что ты такое, dhclient?