Сторінка не перевірена
| Тип | віртуальна машина |
|---|---|
| Автор | Олексій Старовоїтов, Даніель Боркман[1][2] |
| Розробник | Спільнота з відкритим вихідним кодом,Meta,Google, Isovalent,Microsoft,Netflix[1] |
| Стабільний випуск | (2014; 12 років тому (2014)) |
| Операційна система | Linux,Windows[3] |
| Мова програмування | C |
| Ліцензія | Linux:GPL Windows:MIT License |
| Репозиторій | Linux:git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/ Windows:github.com/Microsoft/ebpf-for-windows/ |
| Вебсайт | ebpf.io |
eBPF є технологією, яка може виконувати програми впривілейованому контексті, такому якядро операційної системи.[4] Це наступникBerkeley Packet Filter (BPF, де "e" спочатку означало "розширений") механізму фільтрації в Linux і також використовується в не мережевих частинах ядра Linux.
Він використовується для безпечного та ефективного розширення можливостей ядра під часвиконання без необхідності вносити зміни допочаткового коду ядра або завантажуватимодулі ядра.[5] Безпека забезпечується через внутрішньоядерний верифікатор, який виконуєстатичний аналіз коду та відхиляє програми, які викликають збої, зависання або іншим чином негативно впливають на ядро.[6][7]
Ця модель валідації відрізняється від середовищ зпісочницею, де середовище виконання обмежене і не має уявлення про програму.[8] Прикладом програм, які автоматично відхиляються, є програми без надійних умов завершення (наприклад, цикли for/while без умов завершення) та програми, які здійснюють розіменування вказівників без перевірок на безпеку.[9]
Завантажені програми, які пройшли перевірку, абоінтерпретуються, або компілюються в ядрі за допомогоюкомпіляції під час виконання (JIT) для досягнення високої продуктивності. Модель виконання єподійно-орієнтованою та, за рідкими винятками, працює за принципомвиконання до завершення,[2] що означає, що програми можуть бути прикріплені до різних точокперехоплення в ядріопераційної системи та виконуються під час спрацювання події. Випадки використання eBPF включають (але не обмежуються)мережеві підсистеми, такі якXDP,трасування та підсистемибезпеки.[4] Завдяки ефективності та гнучкості eBPF відкрилися нові можливості для вирішення виробничих проблем, іБрендан Ґреґґ знаменито назвав eBPF "суперсилою для Linux".[10]Лінус Торвальдс зазначив: "BPF насправді був дуже корисним, і його реальна сила полягає в тому, як він дозволяє створювати спеціалізований код, який активується лише тоді, коли це потрібно".[11] Завдяки успіху в Linux, середовище виконання eBPF було портовано на інші операційні системи, такі якWindows.[3]
eBPF еволюціонував із класичного Berkeley Packet Filter (cBPF, ретроактивно надана назва). На базовому рівні він запровадив використання десяти 64-бітних регістрів (замість двох 32-бітних регістрів у cBPF), інші семантики переходів, інструкцію виклику та відповідну конвенцію передачі регістрів, нові інструкції та інше кодування для цих інструкцій.[12]
| Дата | Подія |
|---|---|
| Квітень 2011 | Перший JIT-компілятор (Just-in-time compiler) для класичного фільтра пакетів Берклі (BPF) був інтегрований в ядро Linux.[13] |
| Січень 2012 | Перше некласичне використання класичного фільтра пакетів Берклі — seccomp-bpf.[14] |
| Березень 2014 | Девід С. Міллер, головний адміністратор мережевої підсистеми Linux, прийняв переробку старого інтерпретатора BPF в ядрі. Його замінив інтерпретатор eBPF, а ядро Linux тепер перекладає класичний BPF (cBPF) у команди eBPF.[15] |
| Вересень 2014 | Введено системний виклик bpf, який забезпечив доступ до набору інструкцій eBPF з користувацького простору.[16] |
| Березень 2015 | Можливість прикріплювати eBPF до kprobe була інтегрована як перший випадок використання для трасування.[17] |
| Серпень 2015 | Модуль компілятора eBPF був інтегрований у версію LLVM 3.7.0.[18] |
| Вересень 2015 | Брендан Грегг оголосив про новий набір інструментів для трасування на основі eBPF, відомий як проект bcc.[19] |
| Липень 2016 | eBPF отримав можливість бути прикріпленим до ядра драйвера для обробки вхідних пакетів. Цей рівень відомий як eXpress DataPathXDP.[20] |
| Серпень 2016 | Cilium був представлений як проект для швидкої мережевої комунікації IPv6 для контейнерів за допомогою eBPF і XDP.[21] |
| Листопад 2016 | Netronome додав можливість оффлоаду програм eBPF для XDP та BPF.[22] |
| Травень 2017 | Впроваджено балансувальник навантаження Katran відMeta, який використовує eBPF та XDP.[23] |
| Листопад 2017 | eBPF став окремим підсистемою ядра для спрощення управління патчами ядра.[24] |
| Січень 2018 | Випущена нова родина сокетів AF_XDP для високошвидкісної обробки пакетів.[25] |
| Грудень 2019 | Випущено першу книгу на 880 сторінок про BPF, написану Бренданом Греггом.[26] |
| Липень 2022 | Microsoft випустила eBPF для Windows.[3] |
eBPF мапи — це ефективнісховища ключ/значення, які знаходяться впросторі ядра та можуть використовуватися для обміну даними між декількома програмами eBPF або для комунікації між користувацьким простором та кодом eBPF, що працює в ядрі. Програми eBPF можуть використовувати мапи eBPF для зберігання та отримання даних у широкому спектрі структур даних. Реалізації мап надаються ядром. Існують різні типи,[27] включаючи хеш-мапи, масиви та кільцеві буфери.
На практиці eBPF мапи зазвичай використовуються у таких сценаріях, як запис конфігураційної інформації програмою користувацького простору для отримання програмою eBPF, збереження стану програмою eBPF для подальшого отримання іншою програмою eBPF (або під час повторного запуску тієї ж програми), або запис результатів чи метрик програмою eBPF у мапу для отримання програмою користувацького простору, яка представить результати.[28]
Віртуальна машина eBPF працює в межах ядра та приймає програму у вигляді байткоду eBPF, який конвертується унативні машинні інструкції, що виконуються на процесорі. Ранні реалізації eBPF виконували інтерпретацію байткоду, проте тепер цей процес замінено накомпіляцію Just-in-Time (JIT) для підвищення продуктивності та безпеки.[28]Віртуальна машина eBPF складається з одинадцяти 64-бітних регістрів з 32-бітними підрегістрами,лічильника команд та 512-байтного стека BPF. Ці регістри загального призначення зберігають стан під час виконання програм eBPF.[29]
Хвостовий виклик дозволяє викликати та виконувати іншу програму eBPF, замінюючиконтекст виконання, подібно до того, як системний викликexecve() працює для звичайних процесів. Це дозволяє програмі eBPF викликати іншу програму eBPF. Хвостові виклики реалізуються як довгий стрибок, використовуючи ту самуфрейм стека. Хвостові виклики особливо корисні в eBPF, де стек обмежений 512 байтами. Під час виконання функціональність може бути додана або замінена атомарно, змінюючи поведінку виконання програми BPF.[29] Популярним випадком використання хвостових викликів є розподіл складності програм eBPF на кілька програм. Інший варіант використання — заміна або розширення логіки шляхом заміни вмісту масиву програми під час її використання. Наприклад, для оновлення версії програми безперерви в роботі або для ввімкнення/вимкнення логіки.[30]
Загальноприйнятою практикою в розробці програмного забезпечення є групування загального коду вфункції, що інкапсулюють логіку для повторного використання. До версії ядра Linux 4.16 та LLVM 6.0 типова програма eBPF на мові C повинна була явно вказувати компіляторувбудовувати функцію, що призводило до створення об'єктного файлу BPF з дубльованими функціями. Це обмеження було знято, і сучасні компілятори eBPF тепер підтримують написання функцій у програмах eBPF природним чином. Це зменшує розмір згенерованого коду eBPF, роблячи його більш дружнім до кешу інструкцій процесора.[28][29]
Верифікатор є основним компонентом eBPF, і його головне завдання — гарантувати, що програма eBPF є безпечною для виконання. Він проводить статичний аналіз байткоду eBPF для забезпечення його безпеки. Верифікатор аналізує програму, оцінюючи всі можливі шляхи виконання. Він крокує по інструкціях у порядку їх виконання і оцінює їх. Процес верифікації починається зпошуку в глибину по всіх можливих шляхах програми, при цьому верифікатор симулює виконання кожної інструкції, відстежуючи стан регістрів і стека. Якщо якась інструкція може призвести до небезпечного стану, верифікація не проходить. Процес триває доти, поки всі шляхи не будуть проаналізовані або не буде знайдено порушення. Залежно від типу програми, верифікатор перевіряє порушення певних правил. До цих правил може входити перевірка того, що програма eBPF завжди завершується за розумний час (безнескінченних циклів або нескінченноїрекурсії), перевірка того, що програмі eBPF не дозволяється читати довільну пам'ять, оскільки це може дозволити програмі витікати конфіденційну інформацію, перевірка того, що програми, пов'язані з мережею, не мають доступу до пам'яті поза межамипакета, оскільки сусідня пам'ять може містити конфіденційну інформацію, перевірка того, що програми не можуть створювативзаємне блокування, тому всіSpinlock повинні бути звільнені, і одночасно можна утримувати лише один замок, щоб уникнути взаємного блокування між кількома програмами, перевірка того, що програми не мають доступу до неініціалізованої пам'яті. Це не є вичерпним списком перевірок верифікатора, і є винятки з цих правил. Наприклад, програми трасування мають доступ до хелперів, які дозволяють їм читати пам'ять контрольованим чином, але такі типи програм вимагаютьпривілеїв суперкористувача і тому не становлять загрози для безпеки.[30][28]
З часом верифікатор eBPF розвинувся, включивши нові функції та оптимізації, такі як підтримка обмежених циклів,Елімінація мертвого коду, верифікація по функціям ізворотні виклики.
Програми eBPF використовують пам'ять іструктури даних ядра. Деякі структури можуть змінюватися між різними версіями ядра, змінюючи розташування пам'яті. Оскільки ядро Linux постійно розвивається, немає гарантії, що внутрішні структури даних залишаться незмінними в різних версіях. CO-RE є основним поняттям у сучасній розробці eBPF, яке дозволяє програмам eBPF бути портативними між різними версіями та конфігураціями ядра. Це вирішує проблему варіацій у структурах ядра між різнимидистрибутивами Linux іверсіями. CO-RE складається з BTF (BPF Type Format) —формату метаданих, який описує типи, що використовуються в ядрі та програмах eBPF, і надає детальну інформацію про структури, зсуви полів і типи даних. Це забезпечує доступ до типів ядра під час виконання, що є ключовим для розробки та верифікації програм BPF. BTF включений в образ ядра для підтримуваних версій. Спеціальні релокації генеруютьсякомпілятором (наприклад, LLVM). Ці релокації захоплюють опис високого рівня того, до якої інформації програма eBPF має намір звертатися. Бібліотекаlibbpf адаптує програми eBPF для роботи з макетом структури даних на цільовому ядрі, де вони виконуються, навіть якщо цей макет відрізняється від того, на якому код було скомпільовано. Для цього libbpf потребує інформацію про релокації BPF CO-RE, згенеровану Clang під час процесу компіляції.[28] Скомпільована програма eBPF зберігається у форматіELF (Executable and Linkable Format). Цей файл містить інформацію про типи BTF та релокації, згенерованіClang. Формат ELF дозволяє завантажувачу eBPF (наприклад, libbpf) обробляти та налаштовувати програму BPF динамічно для цільовогоядра.[31]
Назва eBPF часто використовується взаємозамінно з BPF,[2][32] наприклад, у спільноті ядра Linux. eBPF і BPF згадуються як технологія, подібно доLLVM.[2] eBPF розвинувся з машинної мови для фільтруючої віртуальної машини вФільтр Berkeley Packet як розширена версія, але оскільки його сфери використання вийшли за межі мереж, сьогодні "eBPF" найчастіше тлумачиться якпсевдоакронім.[2]
Бджола є офіційним логотипом eBPF. Під час першого саміту eBPF було проведено голосування, на якому маскот-бджолу назвали "eBee".[33][34] Логотип спочатку був створений Вадимом Щеколдіним.[34] Раніше існували неофіційні маскоти eBPF,[35] але вони не отримали широкого поширення.
Фонд eBPF був створений у серпні 2021 року з метою розширення внесків, спрямованих на розширення потужних можливостей eBPF та виходу за межі Linux.[1] Засновниками виступилиMeta,Google, Isovalent,Microsoft таNetflix. Метою є збір, бюджетування та витрачання коштів на підтримку різних проєктів з відкритим вихідним кодом, відкритими даними та/або відкритими стандартами, пов'язаних із технологіями eBPF,[36] для подальшого розвитку та впровадження екосистеми eBPF. З моменту заснування до них приєдналисяRed Hat,Huawei,CrowdStrike, Tigera, DaoCloud, Datoms, FutureWei.[37]
eBPF був прийнятий рядом великих користувачів на виробництві, наприклад:
Через легкість програмування, eBPF використовувався як інструмент для реалізації мікроархітектурних атак черезбічний канал, таких якSpectre, проти вразливихмікропроцесорів.[83] Хоча eBPF без привілеїв реалізовував міграційні заходи проти атак тимчасового виконання,[84] використання без привілеїв зрештою було відключене спільнотою ядра за замовчуванням для захисту від використання проти майбутніх апаратних вразливостей.[85]