eBPF расшифровывается как extended Berkeley Packet Filter (расширенный пакетный фильтр Berkeley). Когда вы работаете с Linux и хотите взаимодействовать с ядром, вам нужна такая платформа, как eBPF. eBPF — это фреймворк, призванный помочь разработчикам беспрепятственно запускать низкоуровневые программы ядра.
С помощью eBPF вы можете быстро загружать и запускать программное обеспечение с минимальными затратами на настройку. Если вы новичок в eBPF и работаете с программами ядра, эта статья поможет вам понять, что такое eBPF и как его использовать. Мы представим несколько примеров внедрения кода в ядро с помощью eBPF.
Давай начнем!
Что такое eBPF
eBPF — это аббревиатура от расширенного фильтра Berkeley Packer. Он действует как интерфейс в ядре Linux, который позволяет разработчикам вводить код для взаимодействия с ядром, например, изменять его поведение или наблюдать за ним.
eBPF был впервые выпущен как трассировщик пакетов, но позже был расширен в 2014 году и интегрирован в ядро Linux. Хотя это в основном помогает с отслеживанием задач, у него есть множество функций, включая разрешение приложениям пользовательского пространства выполнять программы в пространстве ядра.
Память компьютера имеет пространство пользователя и пространство ядра. Пользовательские программы выполняются в пространстве пользователя, а пространство ядра зарезервировано для запуска драйверов и ядра. Пользовательские программы не могут работать в пространстве ядра. Цель состоит в том, чтобы гарантировать, что небезопасные программы или другие уязвимости не могут быть вставлены в ядро и привести к его сбою.
Однако eBPF предлагает вам путь для запуска пользовательских программ в пространстве ядра в виде байт-кода. Поскольку писать байт-коды сложно, для написания программ eBPF вам понадобятся такие среды разработки, как BCC или Bpftrace. Эти фреймворки с открытым исходным кодом, и каждый может их использовать. Вы можете установить фреймворки BCC или Bpftrace и создать программы eBPF.
Установка скрытой копии
BCC — это набор инструментов сбора компилятора BPF, которые помогают писать и запускать программы eBPF.
Начните с обновления репозитория apt:
sudo apt-get update;
Установите инструменты коллекции компилятора BPF с помощью следующей команды:
sudo apt-get install bpfcc-tools linux-headers-$(uname -r);
Подходящие инструменты BCC для вашей архитектуры ядра загружаются и устанавливаются. Нажмите «y», чтобы подтвердить установку.
Вы можете убедиться, что BCC установлен и работает, запустив один из его инструментов, чтобы получить PID любой команды, которую вы запускаете на терминале.
Откройте два окна терминала. Запустите следующую команду bpfcc на первом терминале:
sudo /usr/sbin/bashreadline-bpfcc;
Запустите несколько команд, как показано на следующем изображении, на втором терминале.
Если BCC и eBPF работают на первом терминале, вы увидите PID команд, которые вы ввели во втором окне, и временные метки.
ΤΙΜΕ PID COMMAND 08:51:11 12304 ls 08:51:14 12304 whoami 08:51:16 12304 uname -r 08:51:19 12304 uname
Ваш BCC установлен. Теперь вы можете выполнять различные программы eBPF для внедрения кода в ядро для различных целей.
Установка Bpftrace
Помимо использования фреймворка BCC, вы можете использовать фреймворк Bpftrace. Он идеально подходит для различных задач и предлагает утилиту командной строки, которая позволяет пользователям напрямую выполнять команды eBPF.
Установите его с помощью следующей команды:
sudo apt install bpftrace;
Установив Bpftrace, вы можете развернуть свои программы eBPF. Давайте рассмотрим несколько примеров развертывания различных программ с помощью утилиты командной строки.
Из репозитория Bpftrace GitHub вы можете развернуть различные «однострочные» программы. Например, вы можете вывести список использования диска различными процессами, запустив следующую программу:
bpftrace -e 'tracepoint:block:block_rq_issue { printf("%s %d\n", comm, args->bytes); }'
Из вывода вы заметите, что в столбцах отображается имя процесса, размер диска и размер диска.
$ sudo bpftrace -e 'tracepoint:block:block_rq_issue { print f("%s %d\n", comm, args->bytes); }' Attaching 1 probe… kworker/u2:0 8 kworker/0:1H 4096 kworker/0:1H 4096 kworker/0:1H 4096 pulseaudio 8192 kworker/0:1H 4096 gjs 4096 gjs 8192 gjs 8192 kworker/u2:0 8 kworker/u2:0 4096 kworker/0:1H 4096
Вывод отображает все процессы в вашем ядре.
Если вы также хотите проверить количество системных вызовов по процессам, вы можете использовать однострочную программу Bpftrace со следующей командой:
sudo bpftrace -e ‘tracepoint:raw_syscalls:sys_enter {@[comm] = count(); }’
$ sudo bpftrace -e 'tracepoint: raw_syscalls: sys_enter (@[co = count(); Attaching 1 probe. . . ^C @[gvfs-afc-volume]: 2 @[ibus-extension-]: 2 @[JS Watchdog]: 2 @[dockerd]: 4 @[systemd-journal]: 5 Q[containerd]: 6
Системные вызовы отображаются после нажатия Ctrl + C для уничтожения команды. В выходных данных отображается имя процесса, а отчет, содержащий карту, отображается как ассоциативный массив.
count() заполняет количество раз, которое система вызывает для выполнения каждого процесса. Если вы хотите вывести список всех зондов, вы можете использовать команду bpftrace -l, чтобы вывести их список, как показано ниже:
sudo bpftrace -l 'tracepoint:syscalls:sys_enter_*'
$ sudo bpftrace -l ' tracepoint:syscalls:sys_enter_*' tracepoint:syscalls:sys_enter_accept tracepoint: syscalls:sys_enter_accept4 tracepoint:syscalls:sys enter access tracepoint:syscalls:sys_enter_acct tracepoint:syscalls:sys_enter_add_key tracepoint:syscalls:sysenter adjtimex tracepoint:syscalls:sys_enter_alarm tracepoint:syscalls: sys_enter_arch_prctl tracepoint:syscalls:sys enter_bind tracepoint:syscalls:sys_enter_bpf
Вот как вы работаете с программой eBPF в Linux.
Заключение
eBPF — это способ вставки кода в ядро Linux. Вы можете использовать такие платформы, как BCC и Bpftrace, для создания и запуска программ eBPF. В этом посте представлен eBPF и структура для написания и запуска программ eBPF. Кроме того, мы представили несколько примеров программ eBPF, которые вы можете запустить. Вот и все!