HAProxy в pfSense - обратный прокси и балансировка
HAProxy (High Availability Proxy) - высокопроизводительное решение для проксирования и балансировки нагрузки TCP и HTTP-трафика. В pfSense HAProxy устанавливается как пакет и предоставляет функции обратного прокси-сервера, балансировщика нагрузки между несколькими серверами, SSL-терминатора для разгрузки шифрования с бэкенд-серверов и маршрутизатора HTTP-запросов на основе ACL-правил. HAProxy широко используется для публикации веб-приложений через единый внешний IP-адрес, обеспечения отказоустойчивости серверных пулов и распределения клиентских запросов между несколькими экземплярами приложения.
В контексте pfSense HAProxy работает совместно с файрволом, что позволяет объединить функции маршрутизации, фильтрации и проксирования на одном устройстве. Это упрощает архитектуру сети и сокращает количество точек отказа.
Установка HAProxy
Установка выполняется через менеджер пакетов:
- Перейти в System > Package Manager > Available Packages
- Найти haproxy в строке поиска (доступны две версии: haproxy и haproxy-devel)
- Нажать Install и подтвердить установку
- Дождаться завершения установки
После установки конфигурация доступна через Services > HAProxy.
Выбор версии
| Версия | Описание | Рекомендация |
|---|---|---|
| haproxy | Стабильная версия, отслеживает стабильную ветку FreeBSD-порта | Рабочие среды |
| haproxy-devel | Версия для разработки, содержит новые функции раньше | Тестовые среды |
Архитектура HAProxy
HAProxy оперирует двумя основными сущностями:
Клиент ──> Frontend (слушатель) ──> ACL (маршрутизация) ──> Backend (пул серверов)
├── Server 1
├── Server 2
└── Server 3| Компонент | Описание |
|---|---|
| Frontend | Точка входа для клиентских подключений (IP:порт), определяет протокол и ACL-правила |
| Backend | Пул бэкенд-серверов с настройками балансировки и проверок здоровья |
| Server | Отдельный бэкенд-сервер в пуле (IP, порт, вес) |
| ACL | Условие маршрутизации запросов между бэкендами |
Особенности реализации в pfSense
Веб-интерфейс pfSense отличается от стандартной конфигурации HAProxy. Вместо раздельных секций frontend/backend в конфигурационном файле, пакет pfSense генерирует секции listen, которые объединяют frontend и backend. Это упрощает базовую настройку, но ограничивает возможности продвинутых сценариев с множественными бэкендами.
Настройка Backend
Backend (бэкенд) определяет группу серверов, на которые HAProxy направляет клиентские запросы. Настройка выполняется через Services > HAProxy > Backend.
Создание Backend
- Перейти в Services > HAProxy > Backend
- Нажать Add
- Заполнить параметры
- Нажать Save и Apply Changes
Основные параметры Backend
| Параметр | Описание |
|---|---|
| Name | Уникальное имя бэкенда (без пробелов) |
| Server List | Список серверов пула |
| Balance | Алгоритм балансировки нагрузки |
| Connection Timeout | Таймаут подключения к серверу |
| Server Timeout | Таймаут ожидания ответа от сервера |
| Retries | Количество повторных попыток подключения |
Серверы в Backend
Для каждого сервера в пуле указываются:
| Поле | Описание | Обязательное |
|---|---|---|
| Name | Имя сервера для идентификации в логах | Да |
| Address | IP-адрес или FQDN бэкенд-сервера | Да |
| Port | Порт бэкенд-сервера | Да |
| SSL | Использование SSL при подключении к серверу | Нет |
| Weight | Вес сервера для взвешенной балансировки (1-256) | Нет |
| Cookie | Значение cookie для привязки сессий | Нет |
Алгоритмы балансировки
| Алгоритм | Описание | Применение |
|---|---|---|
| Round Robin | Последовательное распределение по серверам | Серверы с одинаковой производительностью |
| Least Connections | Направление на сервер с наименьшим количеством соединений | Запросы с разной длительностью обработки |
| Source | Привязка клиента к серверу на основе IP-адреса | Требуется постоянство сессии без cookie |
| URI | Маршрутизация по URI-запроса | Кэширующие серверы |
| First | Заполнение серверов последовательно до максимума | Минимизация количества активных серверов |
Для большинства веб-приложений рекомендуется Round Robin или Least Connections. Алгоритм Source подходит для приложений, не поддерживающих распределённые сессии.
Настройка Frontend
Frontend (фронтенд) определяет точку входа для клиентских подключений - IP-адрес, порт и протокол, на которых HAProxy принимает соединения. Настройка выполняется через Services > HAProxy > Frontend.
Создание Frontend
- Перейти в Services > HAProxy > Frontend
- Нажать Add
- Заполнить параметры
- Нажать Save и Apply Changes
Основные параметры Frontend
| Параметр | Описание |
|---|---|
| Name | Уникальное имя фронтенда |
| Status | Состояние: Active или Disabled |
| External Address | IP-адрес для прослушивания (WAN, VIP, localhost) |
| External Port | Порт для прослушивания |
| Max Connections | Максимальное количество одновременных соединений |
| Type | Тип: HTTP/HTTPS (Layer 7) или TCP (Layer 4) |
| Default Backend | Бэкенд по умолчанию для запросов без совпадений ACL |
Настройка HTTPS Frontend
Для приёма HTTPS-соединений необходимо:
- Установить Type в HTTP / HTTPS (offloading)
- В разделе SSL Offloading выбрать сертификат
- Указать External Port как 443
- Настроить Default Backend
При необходимости перенаправления HTTP на HTTPS создать дополнительный Frontend на порту 80 с действием http-request redirect или использовать ACL.
Привязка к Virtual IP
Для приёма соединений на определённом IP-адресе, отличном от основного WAN-адреса, используйте Virtual IP:
- Создать IP Alias или CARP VIP через Firewall > Virtual IPs
- В настройках Frontend выбрать созданный VIP в поле External Address
Это позволяет обслуживать несколько доменов на разных IP-адресах через один экземпляр HAProxy.
ACL - правила маршрутизации
ACL (Access Control Lists) определяют условия, по которым HAProxy направляет запросы на различные бэкенды. ACL анализируют параметры входящего запроса и применяют соответствующее действие.
Создание ACL
ACL настраиваются в секции Frontend:
- На странице редактирования Frontend перейти к разделу Access Control Lists
- Нажать Add ACL (стрелка вниз)
- Заполнить условие и действие
- Повторить для каждого правила маршрутизации
Типы условий ACL
| Условие | Описание | Пример |
|---|---|---|
| Host matches | Совпадение заголовка Host | app.example.com |
| Host starts with | Начало заголовка Host | api. |
| Host ends with | Окончание заголовка Host | .example.com |
| Host contains | Подстрока в заголовке Host | staging |
| Host regex | Регулярное выражение для Host | ^(www\.)?example\.com$ |
| Path starts with | Начало URI-пути | /api/ |
| Path ends with | Окончание URI-пути | .php |
| Path contains | Подстрока в URI-пути | /admin/ |
| Path regex | Регулярное выражение для пути | ^/v[0-9]+/ |
| Source IP matches | Совпадение IP-адреса клиента | 192.168.1.0/24 |
| SSL SNI matches | Совпадение SNI в TLS Client Hello | app.example.com |
| Custom ACL | Произвольное условие HAProxy | hdr(X-Custom) -i value |
Действия ACL
| Действие | Описание |
|---|---|
| Use Backend | Направить запрос на указанный бэкенд |
| http-request deny | Отклонить запрос с кодом ошибки |
| http-request redirect | Перенаправить запрос на другой URL |
| http-request set-header | Установить или изменить HTTP-заголовок |
Пример маршрутизации по доменам
Для публикации нескольких веб-приложений через один IP-адрес:
| ACL | Условие | Backend |
|---|---|---|
| ACL 1 | Host matches app1.example.com | backend_app1 |
| ACL 2 | Host matches app2.example.com | backend_app2 |
| ACL 3 | Host matches api.example.com | backend_api |
| Default | Все остальные запросы | backend_default |
Пример маршрутизации по путям
| ACL | Условие | Backend |
|---|---|---|
| ACL 1 | Path starts with /api/ | backend_api |
| ACL 2 | Path starts with /static/ | backend_static |
| Default | Все остальные запросы | backend_webapp |
SSL-терминация
SSL-терминация (SSL offloading) позволяет HAProxy принимать HTTPS-соединения от клиентов, расшифровывать трафик и пересылать его на бэкенд-серверы по HTTP. Это снимает нагрузку шифрования с бэкенд-серверов и упрощает управление сертификатами.
Импорт сертификата
Перед настройкой SSL необходимо импортировать сертификат в pfSense:
- Перейти в System > Certificates > Certificates
- Нажать Add/Sign
- Выбрать метод: Import an existing Certificate
- Вставить сертификат и приватный ключ
- Нажать Save
Для сертификатов Let’s Encrypt рекомендуется использовать пакет ACME для автоматического получения и обновления.
Настройка SSL Offloading в Frontend
- В настройках Frontend установить Type в HTTP / HTTPS (offloading)
- В разделе SSL Offloading выбрать сертификат
- При необходимости добавить дополнительные сертификаты через Additional Certificates (для нескольких доменов)
- Настроить минимальную версию TLS (рекомендуется TLS 1.2)
Параметры SSL
| Параметр | Описание | Рекомендация |
|---|---|---|
| Certificate | Основной SSL-сертификат | Обязательно |
| Additional Certificates | Сертификаты для дополнительных доменов | По необходимости |
| SSL/TLS Minimum Version | Минимальная версия протокола | TLS 1.2 |
| SSL/TLS Ciphers | Набор шифров | По умолчанию или Mozilla Modern |
| HSTS | HTTP Strict Transport Security | Включить для рабочих сред |
| OCSP Stapling | Привязка статуса OCSP | Включить для улучшения производительности |
SSL Pass-Through
Для случаев, когда SSL-терминация должна выполняться на бэкенд-сервере (например, клиентские сертификаты), используется режим SSL/HTTPS (TCP mode). HAProxy передаёт зашифрованный трафик без расшифровки, маршрутизируя по SNI.
Проверки здоровья
Проверки здоровья (health checks) позволяют HAProxy определять доступность бэкенд-серверов и автоматически исключать неработающие из балансировки.
Типы проверок
| Тип | Описание | Параметры |
|---|---|---|
| TCP Check | Проверка TCP-подключения к порту | Не требует настройки |
| HTTP Check | Отправка HTTP-запроса и проверка кода ответа | URI, метод, ожидаемый код |
| SSL Check | Проверка SSL-соединения | Аналогично TCP с SSL |
| LDAP Check | Проверка LDAP-сервера | LDAP-специфичные параметры |
| MySQL Check | Проверка MySQL-сервера | Учётные данные |
| PostgreSQL Check | Проверка PostgreSQL-сервера | Учётные данные |
| SMTP Check | Проверка SMTP-сервера | HELO-домен |
| ESMTP Check | Расширенная проверка SMTP | EHLO-домен |
Настройка HTTP-проверки
Для веб-приложений рекомендуется HTTP-проверка:
- В настройках Backend перейти к Health Checking
- Установить Health Check Method в HTTP
- Указать Check Frequency (интервал проверки, например 5 секунд)
- Указать Health Check URI (путь для проверки, например
/health) - Указать HTTP Check Method (GET)
- Указать ожидаемый код ответа (по умолчанию 200-399)
Параметры проверок
| Параметр | Описание | Значение по умолчанию |
|---|---|---|
| Check Frequency | Интервал между проверками | 5 секунд |
| Inter | Интервал проверки для здоровых серверов | 5000 мс |
| Down Inter | Интервал проверки для недоступных серверов | 1000 мс |
| Rise | Количество успешных проверок для возврата сервера | 2 |
| Fall | Количество неуспешных проверок для вывода сервера | 3 |
Привязка сессий
Привязка сессий (session persistence, sticky sessions) обеспечивает направление всех запросов одного клиента на один и тот же бэкенд-сервер. Это необходимо для приложений, хранящих состояние сессии локально на сервере.
Методы привязки
| Метод | Описание | Применение |
|---|---|---|
| Cookie-based | HAProxy вставляет cookie с идентификатором сервера | Веб-приложения с поддержкой cookie |
| Source IP | Привязка по IP-адресу клиента (алгоритм Source) | Приложения без cookie, API |
| SSL Session ID | Привязка по идентификатору TLS-сессии | HTTPS без cookie |
Настройка Cookie-based привязки
- В настройках Backend в разделе Cookie Persistence:
- Cookie Name - имя cookie (например,
SERVERID) - Cookie Mode - режим: Insert (HAProxy вставляет cookie), Prefix, Rewrite
- Cookie Options - дополнительные параметры (Indirect, NoCache, PostOnly)
- Cookie Name - имя cookie (например,
- Для каждого сервера в бэкенде указать уникальное значение в поле Cookie
Страница статистики
HAProxy предоставляет встроенную страницу статистики с информацией о состоянии фронтендов, бэкендов и отдельных серверов.
Включение статистики
Настройка выполняется через Services > HAProxy > Settings в разделе Stats:
| Параметр | Описание |
|---|---|
| Stats Enabled | Активация страницы статистики |
| Stats URI | URI для доступа (например, /haproxy-stats) |
| Stats Realm | Заголовок окна аутентификации |
| Stats Username | Имя пользователя |
| Stats Password | Пароль |
| Stats Admin | Разрешение на управление серверами через веб-интерфейс |
| Stats Node | Имя узла, отображаемое в статистике |
Информация на странице статистики
Страница статистики отображает:
- Состояние каждого фронтенда (UP/DOWN, текущие соединения)
- Состояние каждого бэкенда и его серверов (UP/DOWN, активные/неактивные)
- Количество запросов, байт, ошибок за текущую и предыдущую сессии
- Время ответа серверов (avg, max)
- Queue status (очередь запросов при перегрузке серверов)
- Вес серверов и коэффициент распределения
При включённом Stats Admin доступны действия: отключение/включение серверов, слив соединений (drain), установка веса.
Внимание:
Страница статистики содержит конфиденциальную информацию об инфраструктуре. Обязательно настройте аутентификацию и ограничьте доступ по IP-адресам через правила файрвола или ACL.
Типичные сценарии использования
Обратный прокси для веб-серверов
Публикация нескольких веб-приложений через один внешний IP-адрес с маршрутизацией по доменным именам:
- Создать Backend для каждого веб-приложения (backend_site1, backend_site2)
- Создать Frontend на порту 443 с SSL-терминацией
- Настроить ACL-правила маршрутизации по Host
- Создать Frontend на порту 80 с перенаправлением на HTTPS
- Настроить правила файрвола для пропуска трафика на порты 80 и 443
Балансировка нагрузки веб-приложения
Распределение запросов между несколькими экземплярами приложения:
- Создать Backend с несколькими серверами
- Выбрать алгоритм балансировки (Round Robin или Least Connections)
- Настроить HTTP-проверку здоровья на endpoint
/health - При необходимости настроить Cookie-based привязку сессий
- Создать Frontend с привязкой к VIP или WAN-адресу
Публикация API
Маршрутизация API-запросов с разделением по версиям:
- Создать Backend для каждой версии API
- Создать Frontend с ACL по путям:
/v1/- backend_v1,/v2/- backend_v2 - Настроить проверки здоровья для каждого бэкенда
- Добавить rate limiting через ACL при необходимости
Глобальные настройки
Общие параметры HAProxy настраиваются через Services > HAProxy > Settings.
| Параметр | Описание | Рекомендация |
|---|---|---|
| Enable HAProxy | Активация HAProxy | Включить |
| Maximum Connections | Глобальный лимит соединений | 1000-10000 (зависит от RAM) |
| Internal Connections Timeout | Таймаут клиентских соединений | 30000 мс |
| Connection Timeout | Таймаут подключения к бэкенду | 30000 мс |
| Server Timeout | Таймаут ответа бэкенда | 30000 мс |
| Tunnel Timeout | Таймаут для WebSocket и длительных соединений | 3600000 мс |
| DNS Resolvers | DNS-серверы для разрешения имён бэкендов | Указать при использовании FQDN |
Логирование
HAProxy записывает события в системный журнал pfSense (Status > System Logs > HAProxy).
Уровни логирования
| Уровень | Описание |
|---|---|
| Emergency | Система неработоспособна |
| Alert | Требуется немедленное вмешательство |
| Critical | Критические ошибки |
| Error | Ошибки подключения и обработки |
| Warning | Предупреждения (недоступность серверов) |
| Notice | Нормальные, но важные события |
| Info | Информационные сообщения о запросах |
| Debug | Детальная отладочная информация |
Формат логов HTTP
Каждая строка лога HTTP-запроса содержит:
- Клиентский IP и порт
- Время принятия соединения
- Имя фронтенда и бэкенда
- Код HTTP-ответа
- Длительность обработки (Tq/Tw/Tc/Tr/Tt)
- Переданный объём данных
- Заголовки запроса (при включении захвата)
Диагностика проблем
HAProxy не запускается
- Проверить конфигурацию: Services > HAProxy > Settings > Configuration Validity
- Просмотреть системные логи: Status > System Logs > HAProxy
- Убедиться, что порты фронтендов не заняты другими сервисами
- Проверить, что SSL-сертификаты корректны и не истекли
Бэкенд-сервер помечен как DOWN
- Проверить доступность сервера из pfSense: Diagnostics > Ping
- Убедиться, что порт бэкенд-сервера принимает соединения: Diagnostics > Test Port
- Проверить настройки health check - URI, метод, ожидаемый код ответа
- Просмотреть логи HAProxy для определения причины отказа
- Временно отключить health check для диагностики
502 Bad Gateway
- Бэкенд-сервер не отвечает или возвращает ошибку
- Проверить таймаут подключения к бэкенду (Connection Timeout)
- Убедиться, что бэкенд-сервер способен обработать запрос (не перегружен)
- При использовании SSL к бэкенду проверить корректность сертификата
503 Service Unavailable
- Все серверы в бэкенде помечены как DOWN
- Проверить проверки здоровья для каждого сервера
- Убедиться, что максимальное количество соединений не превышено
- Проверить очередь запросов на странице статистики
SSL-ошибки
- Проверить срок действия сертификата: System > Certificates
- Убедиться, что цепочка сертификатов полная (включая промежуточные CA)
- Проверить совпадение доменного имени в сертификате с запрашиваемым
- При использовании нескольких сертификатов убедиться, что SNI настроен корректно
- Проверить минимальную версию TLS - старые клиенты могут не поддерживать TLS 1.2+
Сессия не сохраняется между запросами
- Проверить настройки Cookie Persistence в бэкенде
- Убедиться, что каждый сервер имеет уникальное значение Cookie
- При использовании алгоритма Source убедиться, что клиенты подключаются с постоянного IP
- Проверить, не включён ли прозрачный прокси или CDN, изменяющий IP клиента
Связанные разделы
- Управление пакетами - установка и обновление пакетов pfSense
- Сертификаты pfSense - управление SSL-сертификатами для HAProxy
- Правила файрвола - настройка правил для пропуска трафика к HAProxy
- NAT в pfSense - альтернативный способ публикации сервисов через проброс портов