Программа eBPF для пересылки HTTP-запросов на другой порт
Я пытаюсь реализовать функцию, где в зависимости от пути HTTP-запроса я могу переслать запрос на другой порт.
Например, если запрос GET /foo, я бы хотел перенаправить его на порт 81, а если это /bar, я бы хотел перенаправить его на порт 82. И если это что-то еще, я хотел бы продолжить пересылать его на порт 80 как он был входящим.
Есть ли пример программы eBPF, как это?
Я пытаюсь выяснить, как я буду определять, что такое HTTP-запрос, потому что eBPF будет применяться на уровне пакета
1 ответ
Я не знаю такого примера в настоящее время. Я знаю, что проект Cilium использует BPF для создания фильтров на уровне HTTP API, но они генерируют программы BPF на лету, и я не верю, что в репозитории есть предварительно скомпилированные примеры.
Как вы упомянули, программы e BPF обрабатывают весь пакет, включая заголовки L2/L3/L4. Итак, чтобы определить ваш HTTP-запрос, вам нужно сделать что-то вроде этого:
- Получить эфирный тип
- Если ethertype не IPv4 или IPv6, выйдите (например, передайте или отбросьте пакет), в противном случае продолжайте
- Получить тип протокола IP
- Если тип протокола IP не TCP, выйдите
- Получить порт назначения TCP
- Если этот порт не 80, выход
- Получить первые 4 байта слоя приложения
- Эти байты
GET␣
? Если нет, выход. - Если да, попробуйте сопоставить следующие байты с вашими путями
/foo
а также/bar
- Если это соответствует, измените порт назначения на 81 или 82 соответственно
По крайней мере, для первых шагов (обработка Ethernet, IP, TCP) у вас есть доступные примеры в Интернете. От parse_simple.c
в образцах ядра - в более сложные, такие как балансировщик нагрузки L4 в хранилище образцов Netronome.