Учебное пособие по работе с eBPF в Linux

eBPF расшифровывается как extended Berkeley Packet Filter. Когда вы работаете с Linux и хотите взаимодействовать с ядром, вам необходим такой фреймворк, как eBPF. eBPF - это фреймворк, который призван помочь разработчикам беспрепятственно запускать низкоуровневые программы ядра.

С помощью eBPF можно быстро загружать и запускать программы с минимальными накладными расходами на настройку. Если вы новичок в eBPF и работаете с программами ядра, это руководство поможет вам разобраться в eBPF и понять, как его использовать. Мы представим несколько примеров инъекции кода в ядро с использованием eBPF.

Что такое eBPF

eBPF - это аббревиатура расширенного фильтра Berkeley Packer Filter. Он выступает в качестве интерфейса в ядре Linux, позволяющего разработчикам внедрять код для взаимодействия с ядром, например, изменять его поведение или наблюдать за ним.

Впервые eBPF был выпущен как трассировщик пакетов, но в 2014 году был расширен и интегрирован в ядро Linux. Хотя в основном он помогает решать задачи трассировки, у него есть множество функциональных возможностей, в том числе он позволяет приложениям пользовательского пространства выполнять программы в пространстве ядра.

В памяти компьютера есть пространство пользователя и пространство ядра. В пространстве пользователя выполняются пользовательские программы, а пространство ядра отведено для работы драйверов и ядра. Пользовательские программы не могут выполняться в пространстве ядра. Это делается для того, чтобы исключить возможность внедрения в ядро небезопасных программ или других уязвимостей и его разрушения.

Однако eBPF предоставляет возможность запускать пользовательские программы в пространстве ядра в виде байткода. Поскольку байт-коды сложны в написании, для написания eBPF-программ необходимы фреймворки разработки, такие как BCC или Bpftrace. Эти фреймворки имеют открытый исходный код, и любой желающий может их использовать. Вы можете установить фреймворки BCC или Bpftrace и создавать программы eBPF.

Установка BCC

BCC - это набор инструментов компилятора BPF, которые помогают при написании и выполнении программ eBPF.

Начните с обновления репозитория apt:

Установите инструменты коллекции компиляторов BPF с помощью следующей команды:

Будут найдены и установлены инструменты BCC, соответствующие архитектуре вашего ядра. Нажмите "y" для подтверждения установки.

sudo apt-get install bpfcc-tools linux-headers-$(uname -r)
Убедиться в том, что BCC установлен и работает, можно, запустив одну из его утилит для получения PID любой команды, выполняемой в терминале.

Откройте два окна терминала. В первом терминале выполните следующую команду bpfcc:

На втором терминале выполните несколько команд, как показано на следующем рисунке:

Различные команды в терминале
Если BCC и eBPF работают на первом терминале, то во втором окне вы увидите PID команд, которые вы ввели, и временные метки.

sudo /usr/sbin/bashreadline-bpfcc
Ваш BCC установлен. Теперь вы можете выполнять различные программы eBPF для внедрения кода в ядро для различных целей.

Установка Bpftrace

Помимо использования фреймворка BCC, вы можете использовать фреймворк Bpftrace. Он идеально подходит для решения различных задач и представляет собой утилиту командной строки, позволяющую напрямую выполнять команды eBPF.

Установите ее с помощью следующей команды:

sudo apt install bpftrace

Установив Bpftrace, вы можете развернуть свои программы eBPF. Рассмотрим несколько примеров развертывания различных программ с помощью утилиты командной строки.

Из репозитория Bpftrace GitHub можно развернуть различные "однострочные" программы. Например, можно вывести список потребления диска различными процессами, запустив следующую программу:

sudo bpftrace -e 'tracepoint:block:block_rq_issue { printf("%s %d\n", comm, args->bytes); }'
Из вывода можно заметить, что в столбцах отображаются имя процесса, размер диска и размер диска.

В выводе отображаются все процессы в ядре.

Если вы также хотите проверить количество системных вызовов по процессам, вы можете воспользоваться программой Bpftrace one-liners, выполнив следующую команду:

sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter {@[comm] = count(); }'

Вывод системных вызовов осуществляется после нажатия Ctrl + C для завершения команды. На выходе отображается имя процесса, а отчет, содержащий карту, отображается как ассоциативный массив.

В count() заносится счетчик частоты вызовов системы для каждого процесса. Если необходимо вывести список всех зондов, можно воспользоваться командой bpftrace -l, как показано ниже:

sudo bpftrace -l 'tracepoint:syscalls:sys_enter_*'

Вот так можно работать с программой eBPF в Linux.

Заключение

eBPF - это способ вставки кода в ядро Linux. Для создания и запуска eBPF-программ можно использовать такие фреймворки, как BCC и Bpftrace. В этой заметке были представлены eBPF и фреймворк для написания и выполнения eBPF-программ. Кроме того, мы привели несколько примеров программ eBPF, которые можно запустить.

Понравилась статья? Поделиться с друзьями:
Добавить комментарий