Как стать автором
Обновить

Комментарии 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)

Не обязательно быть CCIE, чтобы сделать вывод о странности утверждения насчет layer 2, тем более в контексте IP, на основании совпадения названия одной специфической имплементации.

Насколько я могу судить там своя имплементация протокола.

Очень познавательно, спасибо!

Мне вот почему-то кажется, что я блокировал DHCP на L2 firewall в RouterOS (мы понимаем, что это тот же linux плюс минус). У MikroTik в стеке есть отличный L2 firewall, который решает различные задачи, как раз до L3 (неожиданно )), мне больше всего нравится элегантность так называемого transpered firewall. А как насчет защиты от ложных (вредительских) DHCP-серверов дела обстоят в Linux, где это настраивается?

Жаль только, что почти любые (кроме vlan фильтрации) правила bridge filter ломают bridge fast path на большей части свич-чипов и пользовать железку на гигабите с натом становится невозможно.

Вы не уловили суть: речь о блокировке на стороне клиента, а не о транзитном трафике.

Сегодня сервер. Завтра клиент, тут все понятно. А так L2 firewall это специфическая штука. Для решения общих задач она не нужна. По крайней мере мой опыт говорит об этом. А вот с академической точки зрения - интересно)

офигеть...
я бы заблочил выше на свиче с помощью acl?

Да вопросов нет, что это можно разными способами сделать.

Просто тут случился интересный, хотя и практически бесполезный разрыв привычных представлений)

Боря Лыточкин и Паша Пушкарёв

Закидывайте лекцию в ExYa уже -)

https://yandex.ru/yaintern/training/devops-training
Выяснилось в личке, что если достаточно долго скроллить и смотреть глазами, а не как я, то записи там есть -)
Спасибо )

А какой практический смысл блокировки протокола? Если у вас есть сервер раздающий адреса, значит вам это нужно. Если вы не желаете получать адрес, то указываете его статическим и останавливаете клиент. И т.д.
Все эти задачи с подковыркой оторванные от реально опыта сделают специалиста хакером. Он будет хернёй на работе страдать с гордостью, конечно, но всё же. И будет думать, что занят скучными и бесполезными делами и от того хотеть "крутых" задач. И, возможно, создавать невероятные проблемы, которые можно героически решать.
А надо чтобы всё было по стандартам сделано. Скучно, да, но стандартно, чтобы когда уйдёшь с работы ваша смена смогла быстро понять почему на хосте dhclient не работает.
В итоге выяснилось, что вы давали задачу не убедившись, что она имеет решение, которого она не имеет. Я бы не стал считать допустимым решением задачи написание сишного кода. Такое нередко имеет отрицательные последствия, разделяя людей на тех кто уважает стандарты и тех кто стандарты не уважает.

Смысл в том, что это даёт понимание "а как эта штуковина вообще говоря работает", и мир начинает чуть меньше состоять из магии.

Это было интересное чтиво, но применять полученное от его прочтения знание — негде, кроме парочки сверхузких ниш.
Так что оно обязательно забудется. И мир начинает чуть меньше состоять из магии на этом закончится.

Зато ребята вот нашли, где на практике применить XDP-программку с пользой для дела)

Несомненно )
Но польза одноразового прочтения развлекательных статей — а вне связей с профессиональной деятелньностью любое чтение будет развлекательным, несмотря на его хардкорность — слишком переоценена.

З.Ы. Ваша статья получилась весьма хардконой, большое вам спасибо за труд )

У вас какая-то разнарядка на изучение eBPF?

В 2 из 4 просмотренных лекций авторы говорят "очень хочу изучить, но никак не найду времени", ещё один знающий его решил не грузить и без того сложный урок, а в последней тема статьи.

Для тех кто пользуется документацией в линуксе нет магии. Вопрос был не "зачем вы занимались этим увлекательным исследованием?", а "зачем вы даёте задачи, которые сами не можете решить?" и которые без как раз "магии" решить не сможет никто.

Вы меня, конечно, извините, но

Сначала мы убрали эту задачку под звёздочку. Подумали — убрали под две. А потом вообще исключили из домашки.

Да, мы потом после нашего исследования предложили тем, кто чувствует в себе силу, посмотреть на это. Но как-то градус вашей категоричности не соответствует такой формулировке.

Простите, если я излишне резок в своих выражениях. Моё грандиозное почтение, кстати, за циклы замечательных статей "Для самых маленьких". Я упустил слово "домашка" и видимо подумал про условия найма, и думал что речь идёт о будущих сотрудниках в штате системных/сетевых администраторов. Бесспорно, поддерживать в учениках увлечённость и любознательность благое дело.

Недопонимание устранено)

Спасибо на добром слове!

О, да, я как-то про него вообще забыл написать.

Добрыйвечер.

Да, причём именно в 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 Snooping на [виртуальном] коммутаторе.

Эта статья настолько хороша, что я не поленился зарегистрироваться на хабре, чтобы просто поблагодарить вас. За 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 и других ос?

Как минимум во FreeBSD, судя по всему -- аналогично. Нужен BPF перехват по той же причине. Про OpenBSD есть упоминание в статье у Марата.
Интересно, как в Windows это устроено.

Пунтим вопрос обратно на мозг: как так iptables пакет считает в статистику, но не может дропнуть? Или может?

На стековерфлоу есть ответ на вопрос, почему счётчики правил для отбрасывания пакетов инкрементируются (и эти пакеты на самом деле дропаются), а dhcp клиент продолжает работать без проблем.

Дыг ответ достаточно очевиден даже если не подглядывать в ссылку. Потому, что dhcp клиент получает свою копию пакета, а iptables свою.

Мне, как человеку, который раньше точно блокировал DHCP через iptables было интересно узнать, что теперь там во всю BPF и просто так уже не получится

Возможно, вы блокировали его на стороне сервера - там проблем нет)

Спасибо за статью! Было интересно покопаться. У dhclient есть флаг -v и он может многое прояснить :)

  • Пунтим вопрос обратно на мозг: как так iptables пакет считает в статистику, но не может дропнуть? Или может?

    Тут можно обойтись простыми вещами: делаем два правила в iptables(один по маку, второй по UDP) и смотрим счётчики. Становится ясно что никакого квантового пакета не появляется и расщепление происходит где-то раньше. Если ещё и поднять netcat на UDP то без iptables правил он что-то получит. А если заблокировать - то нет.

  • Как libpcap видит все пакеты, которые никак не захватываются никакими *tables?

    А это уже на отдельную статью по libpcap скорее тянет :)

Да, всё так) И про dhclient или libpcacp)

А это уже на отдельную статью по libpcap скорее тянет :)

Пишите! )

Тут у нас другая лаба. Два неймспейса в виртуалке: в одном DHCP-клиент, в другом — DHCP-сервер. Они соединены друг с другом через veth-пару.

Нет ли здесь какого-то подвоха? Будет ли работать предложенное решение с оригинальной постановкой задачи, или нельзя просто так взять и завести XDP в общем случае?

Хм, что-то даже любопытно стало: а не проще ли было для целей dhcp клиента назначить интерфейсу временный ip-адрес, чтобы не городить эти вот неблокируемые фильтры и свои реализации стека IP? Если что, я про сеть 169.254.0.0/16 из RFC 3927

Зарегистрируйтесь на Хабре, чтобы оставить комментарий