Learning eBPF: Programming the Linux Kernel for Enhanced Observability, Networking, and Security (Final Release)

This document was uploaded by one of our users. The uploader already confirmed that they had the permission to publish it. If you are author/publisher or own the copyright of this documents, please report to us by using this DMCA report form.

Simply click on the Download Book button.

Yes, Book downloads on Ebookily are 100% Free.

Sometimes the book is free on Amazon As well, so go ahead and hit "Search on Amazon"

What is eBPF? With this revolutionary technology, you can write custom code that dynamically changes the way the kernel behaves. It's an extraordinary platform for building a whole new generation of security, observability, and networking tools. This practical book is ideal for developers, system administrators, operators, and students who are curious about eBPF and want to know how it works. Author Liz Rice, chief open source officer with cloud native networking and security specialists Isovalent, also provides a foundation for those who want to explore writing eBPF programs themselves. The entire eBPF program is defined as a string called “program” in the Python code. This C program needs to be compiled before it can be executed, but BCC takes care of that for you. The eBPF program is loaded into the kernel and attached to an event, so the program will be triggered whenever a new executable gets launched on the machine. All that remains to do in the Python code is to read the tracing that is output by the kernel, and write it on screen. In the Chapter 2, you saw a simple eBPF Hello World, written using the BCC framework. In the Chapter 3 I’ll show you a version of Hello World entirely in C, so that you can see some of the details that BCC took care of in the previous chapter. I’ll also show you the stages that an eBPF program goes through on its journey from source code to execution. eBPF programs can be used to dynamically change the behavior of the system. There’s no need to reboot the machine or restart existing processes - eBPF code starts taking effect as soon as it is attached to an event. What we call “eBPF” today has its roots in the BSD Packet Filter, first described in 1993 in a paper1 written by Lawrence Berkeley National Laboratory’s Steven McCanne and Van Jacobson. This paper discusses a pseudomachine that can run filters, which are programs written to determine whether to accept or reject a network packet. These programs were written in the BPF instruction set, a general-purpose set of 32-bit instructions that closely resembles assembly language. You can imagine (or, indeed, refer to the paper to find examples of) more complex filter programs that make decisions based on other aspects of the packet. Importantly, the author of the filter can write their own custom programs to be executed within the kernel, and this is the heart of what eBPF enables. With this book, you will: Learn why eBPF has become so important in the past couple of years Write basic eBPF code, and manipulate eBPF programs and attach them to events Explore how eBPF components interact with Linux to dynamically change the operating system's behavior Learn how tools based on eBPF can instrument applications without changes to the apps or their configuration Discover how this technology enables new tools for observability, security, and networking Who This Book Is For: This book is for developers, system administrators, operators, and students who are curious about eBPF and want to know more about how it works. It will provide a foundation for those who want to explore writing eBPF programs themselves. Since eBPF provides a great platform for a whole new generation of instrumentation and tooling, there will likely be gainful employment for eBPF developers for some years to come. But you don’t necessarily need to be planning to write eBPF code yourself for this book to be useful to you. If you work in operations, security, or any other role that involves software infrastructure, you’re likely to come across eBPF-based tooling, now or over the next few years. If you understand something about the internals of these tools, you’ll be in a better position to use them effectively. For example, if you know how events can trigger eBPF programs, you’ll have a better mental model for exactly what an eBPF-based tool is really measuring when it shows you performance metrics. If you’re an application developer, you might also come into contact with some of these eBPF-based tools—for example, if you are performance tuning an application, you might use a tool like Parca to generate flame graphs showing which functions are taking the most time. If you are evaluating security tools, this book will help you understand where eBPF shines and how to avoid using it in a naïve way that is less effective against attacks. Even if you’re not using eBPF tools today, I hope this book will give you interesting insights into areas of Linux that you might not have considered before. Most developers take the kernel for granted, as they use programming languages with convenient higher-level abstractions that allow them to focus on the work of application development—which is plenty hard enough! They use tools like debuggers and performance analyzers to help them do their job effectively. Knowing the internals of how a debugger or performance tool works might be interesting, but it’s not essential.

Author(s): Liz Rice
Publisher: O’Reilly Media
Year: 2023

Language: English
Commentary: Final Release
Pages: 329

Preface
Who This Book Is For
What This Book Covers
Prerequisite Knowledge
Example Code and Exercises
Is eBPF Only for Linux?
Conventions Used in This Book
Using Code Examples
O’Reilly Online Learning
How to Contact Us
Acknowledgments
1. What Is eBPF, and Why Is It Important?
eBPF’s Roots: The Berkeley Packet Filter
From BPF to eBPF
The Evolution of eBPF to Production Systems
Naming Is Hard
The Linux Kernel
Adding New Functionality to the Kernel
Kernel Modules
Dynamic Loading of eBPF Programs
High Performance of eBPF Programs
eBPF in Cloud Native Environments
Summary
2. eBPF’s “Hello World”
BCC’s “Hello World”
Running “Hello World”
BPF Maps
Hash Table Map
Perf and Ring Buffer Maps
Function Calls
Tail Calls
Summary
Exercises
3. Anatomy of an eBPF Program
The eBPF Virtual Machine
eBPF Registers
eBPF Instructions
eBPF “Hello World” for a Network Interface
Compiling an eBPF Object File
Inspecting an eBPF Object File
Loading the Program into the Kernel
Inspecting the Loaded Program
The BPF Program Tag
The Translated Bytecode
The JIT-Compiled Machine Code
Attaching to an Event
Global Variables
Detaching the Program
Unloading the Program
BPF to BPF Calls
Summary
Exercises
4. The bpf() System Call
Loading BTF Data
Creating Maps
Loading a Program
Modifying a Map from User Space
BPF Program and Map References
Pinning
BPF Links
Additional Syscalls Involved in eBPF
Initializing the Perf Buffer
Attaching to Kprobe Events
Setting Up and Reading Perf Events
Ring Buffers
Reading Information from a Map
Finding a Map
Reading Map Elements
Summary
Exercises
5. CO-RE, BTF, and Libbpf
BCC’s Approach to Portability
CO-RE Overview
BPF Type Format
BTF Use Cases
Listing BTF Information with bpftool
BTF Types
Maps with BTF Information
BTF Data for Functions and Function Prototypes
Inspecting BTF Data for Maps and Programs
Generating a Kernel Header File
CO-RE eBPF Programs
Header Files
Kernel header information
Headers from libbpf
Application-specific headers
Defining Maps
eBPF Program Sections
Memory Access with CO-RE
License Definition
Compiling eBPF Programs for CO-RE
Debug Information
Optimization
Target Architecture
Makefile
BTF Information in the Object File
BPF Relocations
CO-RE User Space Code
The Libbpf Library for User Space
BPF Skeletons
Loading programs and maps into the kernel
Accessing existing maps
Attaching to events
Managing an event buffer
Libbpf Code Examples
Summary
Exercises
6. The eBPF Verifier
The Verification Process
The Verifier Log
Visualizing Control Flow
Validating Helper Functions
Helper Function Arguments
Checking the License
Checking Memory Access
Checking Pointers Before Dereferencing Them
Accessing Context
Running to Completion
Loops
Checking the Return Code
Invalid Instructions
Unreachable Instructions
Summary
Exercises
7. eBPF Program and Attachment Types
Program Context Arguments
Helper Functions and Return Codes
Kfuncs
Tracing
Kprobes and Kretprobes
Attaching kprobes to syscall entry points
Attaching kprobes to other kernel functions
Fentry/Fexit
Tracepoints
BTF-Enabled Tracepoints
User Space Attachments
LSM
Networking
Sockets
Traffic Control
XDP
Flow Dissector
Lightweight Tunnels
Cgroups
Infrared Controllers
BPF Attachment Types
Summary
Exercises
8. eBPF for Networking
Packet Drops
XDP Program Return Codes
XDP Packet Parsing
Load Balancing and Forwarding
XDP Offloading
Traffic Control (TC)
Packet Encryption and Decryption
User Space SSL Libraries
eBPF and Kubernetes Networking
Avoiding iptables
Coordinated Network Programs
Network Policy Enforcement
Encrypted Connections
Summary
Exercises and Further Reading
9. eBPF for Security
Security Observability Requires Policy and Context
Using System Calls for Security Events
Seccomp
Generating Seccomp Profiles
Syscall-Tracking Security Tools
BPF LSM
Cilium Tetragon
Attaching to Internal Kernel Functions
Preventative Security
Network Security
Summary
10. eBPF Programming
Bpftrace
Language Choices for eBPF in the Kernel
BCC Python/Lua/C++
C and Libbpf
Go
Gobpf
Ebpf-go
Libbpfgo
Rust
Libbpf-rs
Redbpf
Aya
Rust-bcc
Testing BPF Programs
Multiple eBPF Programs
Summary
Exercises
11. The Future Evolution of eBPF
The eBPF Foundation
eBPF for Windows
Linux eBPF Evolution
eBPF Is a Platform, Not a Feature
Conclusion
Index