Привет, Хабр! Я Алексей Кашавкин, инженер отдела облачных операций в G-Core Labs, последние пять лет занимаюсь администрированием OpenStack. Сегодня расскажу о костыле нестандартном использовании технологий или о том, как посадить брокеры Kafka за Nginx, используя протокол HTTPS. Если у вас почему-то нет другого способа принимать сообщения — эта заметка как раз для вас. Проблема возникла, когда мне довелось настраивать кластер Kafka, чтобы поднять тестовый стенд для проверки концепции нового проекта. Перед созданием самого сервиса — центрального хранилища логов — мы решили провести PoC-тестирование и выяснить, как Kafka будет работать c Elasticsearch. Стенд сразу начали делать с шифрованием (SSL/TLS), но имеющиеся PEM-сертификаты Kafka принимать отказалась. Решить проблему напрямую мне запрещали регламенты, так как сертификаты курирует и приносит на наши серверы другой отдел с помощью Puppet. Пришлось делать ход конём и в таком виде пытаться добавить их в Nginx. Но с этим возникло несколько сложностей: во-первых, Kafka не использует протокол HTTP для коммуникаций, а REST Proxy от Confluent я не стал брать в расчёт из-за условий лицензии; во-вторых, при проксировании TCP требовалась SSL-терминация, а в официальной документации Nginx эта возможность упоминается в описаниях платной версии. На самом деле, для проксирования можно было использовать и доступные из коробки модули Nginx, но я в результате решил подготовить собственное решение с отдельными модулями. О том, как мне удалось это сделать, сохранив при этом роутинг сообщений по топикам, я описал ниже. Надеюсь, эта мини-инструкция поможет кому-то в схожих условиях. Понятно, что такое решение кому-то покажется странным, но оно может прийтись весьма кстати в legacy-проектах, где нет возможности написать своего продюсера и интегрировать его в код, но есть интерфейс вывода какой-либо информации посредством HTTP/HTTPS, который можно задействовать. Метод, который я опишу достаточно лаконичен. Для него необходимо собрать два динамических модуля Nginx: echo kafka-log После того как сборка будет завершена, конфигурационный файл для работы модулей не вызовет трудностей в написании. Я лишь приведу простенький пример c последующими комментариями к нему, а вы уже сможете дописать его c учётом ваших особенностей: Разберём конфигурационный файл по порядку: Модули: ngx_http_echo_module.so необходим для передачи тела запроса когда не используются директивы proxy_pass, fastcgi_pass, uwsgi_pass и scgi_pass; ngx_http_kafka_log_module.so — модуль для передачи сообщений из Nginx в топики Kafka. kafka_log_kafka_brokers — непосредственно брокеры Kafka. Дальше идет блок http c блоком server, в котором содержится условие для $request_uri. Это условие нужно, чтобы убрать “/” из $request_uri, так как rewrite тут использовать не получится — он вызовет return и завершит обработку до директивы echo_read_request_body. В переменной $request_key получаем название топика без обратного слеша. Было — /topic_name, стало — topic_name. Блок location задает работу с двумя модулями: kafka_log — отправляем в топики Kafka тело запроса; echo_read_request_body— прочитываем тело запроса, чтобы передать в $request_body. На этом всё — теперь вы можете принимать сообщения для Kafka, отправляя их на URL вида https://example.com/topic_name P.S.: Для нашего проекта мы позже всё же переделали сертификаты и добавили их в конфигурацию Kafka. Linux kernel, eBPF, network stack and protocols