Я применял для очень маленькой задачи вместо модуля ядра - полный пример тут, может быть полезно KernelScript 0.1.0 (комментарий)
Безопасность с точки зрения «не уронить случайно систему самому» - довольно высокая, защита от случайных ошибок много выше чем при написании модуля ядра.
С точки зрения поверхности атак и подобного не анализировал.
По сути да, вся соль в верификаторе и архитектуре, событийная модель и всё такое.
Если умудриться обдурить верификатор, то ой.
Насколько сложно иметь с ним дело?
Ровно настолько насколько сложно прочитать документацию https://docs.ebpf.io/linux/ я пока не осоилил.
Но там ещё момент на eBPF нельзя (вроде) писать что хочешь, а только определённые виды программ, на которые
повесили события которые пробрасываются в eBPF https://docs.ebpf.io/linux/program-type/ на что тот может лишь реагировать и что-то делать.
А так тема интересная, подпишусь может чего интересного напишут. Хотя по сути надо просто сесть и читать доки, пробуя по малому примитивные вещи делать.
Но там ещё момент на eBPF нельзя (вроде) писать что хочешь, а только определённые виды программ, на которые повесили события которые пробрасываются в eBPF https://docs.ebpf.io/linux/program-type/ на что тот может лишь реагировать и что-то делать.
Это я уже понял.
Хотя по сути надо просто сесть и читать доки
Ну, это само собой разумеется. Но я хотел ещё и «живые» мнения послушать :)
Можно запускать перф как диды, после чего - скрипт на перле, который перегонит собранные с ядра стектрейсы в правильный формат и при этом сожрёт десятки гигов оперативки.
Либо можно применить тулзу по ссылке, которая с помощью ебпф заставит ядро выводить трейсы сразу в нужном формате. Несложный выбор.
По докам я бы сказал что самое сложное для понимания - то что многие библиотеки/фреймворки для BPF сочетают в себе компоненты для сборки и user-space компоненты для взаимодействия с bpf-программами в runtime и это воспрнимается как единое целое. Однако для понимания сути работы - может быть понятней смотреть на это по этапам:
этап создание eBPF программы - можем использовать любой подходящий под задау стек сборки и получить универсальный собранный «бинарник» программы. Это вовсе необязательно делать на том же хосте гле будет запуск
этап загрузки бинарника я в ядро - это НЕ требует обязательного написание своего userspace-кода, можно обойтись обойдясь bpftool (причём даже не обязательно совпадающей с ядром версии).
этап runtime-работы eBOF программы. Если логика её работы подразмевает принятие или передачу данных в userspace - потребуется ещё и userspace-компонент, который будет с ней взаимодействовать. А елси для логики программы этого компонента не требуется- то его может и не быть.
Склеить все 3 этапа в единый запуск userspace-программы которая и скопилироует и загрузит и потом будет взаимодействовать - можно, но это делается только тогда когда это удобно, а не потому что «только так»
Конечно. Я пробовал в варианте XDP/eBPF, есть куча проектов на этом стеке.
Действительно ли оно так безопасно, как заявлено?
В верификаторе, наверное, есть какие-то дыры, но если программировать «честно», то его очень непросто обмануть
Насколько сложно иметь с ним дело?
eBPF это просто таргет, можно компилировать в него что угодно. А вот верификатор, который проверяет модуль перед загрузкой в ядро - иногда приходится буквально ублажать.
Обычно эти ограничения можно как-то обойти. А вот что обойти никак нельзя - это производительность. Хоть и заявляется, что XDP это что-то вроде замены DPDK, но это, скажем, не совсем так
Самое крутое, на мой взгляд, что даёт БПФ - это подключение к работающим прикладным программам. Правда есть нюанс, который заключается в необходимости либо наличия символов в бинарнике, либо точных адресов в виртуальной памяти. Обычно в прод окружении символов нет, поэтому нужно парсить бинарник. И вот этот парсинг даже сложнее, чем собственно само написание логики работы БПФ проги. Зато если сделал один раз, то можно пользоваться постоянно, хотя бы для одного компилятора.