reverse proxy on pfSense + HAProxy + Let’s Encrypt

Ранее, для реализации реверс прокси я использовал nginx.
сначала это был дополнительный pkg, затем нгинкс встроили в систему и запускал я его через кастомный конфиг + команду /usr/local/etc/rc.d/nginx onestart, и да, приходилось настраивать NAT Port Forward, тк nginx не умеет забирать системно важные порты. В общем связка работает хорошо, но не очень удобно, когда надо делать бекап системы стандартными способами — /usr/local/etc/ не попадает в бекап.

Позже, я прикрутил acme. И… тоже все было хорошо, кроме удобства переноса конфигов при обновлении или замене железок.

И про HAProxy я не думал, тк он изначально не имел фичи, именуемой SNI. Поэтому просто использовал nginx + acme из сторонних пакетов.

И как то раз, исследуя фриланс биржу, наткнулся на проект, где требовалось настроить балансировщик HAProxy и SSL, и перед тем как написать ответ — полез читать, не изменилось ли чего. Ура! Изменилось!

В HAProxy появилась поддержка SNI, а значит, что на гейте под pfSense есть надежда перевести все на системные утилиты и настройки.

И так, далее о том, как настроить pfSense так, чтобы работал HAProxy как reverse proxy + acme для выдачи SSL сертификатов и все это было реализовано стандартными утилитами.

1. Устанавливаем нужные пакеты:
* haproxy
* acme

2. В фаерволе открываем порты:
* 80
* 443

3. Теперь настраиваем HAProxy:
3.1 сначала backend, тк затем оно будет подставлять значения во frontend:

acme — для генерации ssl сертификатов, redmine и scm — сервисы.

Чуть подробнее:

3.1.1 acme.
основная настройка. Тут указывается сервер localhost, а порт 10003. его можно выбрать и любой другой, важно, чтобы это значение совпадало со значением у сервиса acme. Позже о нем повторю.  

И

.

Проверку следует выключить, тк основное время демон выключен и на 10003 порту никто не слушает.

Все другие настройки не трогаем.

3.1.2 Redmine и scm.

 

Тут, как видно, меняется только адрес в локальной сети. Те сервисы redmine и scm подняты на машине 192.168.140.224, и отвечает там nginx на порту 80.

Мониторинг basic. Это просто проверка, что порт открыт. Можно сделать и более навороченную проверку, но смысла для нас нет, тк важно знать что порт работает или нет. Для тотальной экономии ресурсов можно выключить проверку.

3.2 Frontend

Общий вид будет такой:

детальнее:

Тут определили на каких адресах и портах будет слушать HAProxy.


Тут началось интересное. Как раз тут и прописываем правила, по которым HAProxy раскидывает соединения.
Для acme нам важно перехватывать все домены, но только путь /.well-known/acme-challenge/ важно пропускать в демон Acme. А redmine и scm разруливаются по именам. Порядок важен! Первым сработает правило, которое подходит раньше и описано выше других!


тут прописано следующее:
* прописывать реальный IP адрес пользователя в заголовке X-Real-IP,
* пропускать «неправильные» запросы (нужно для WebDAV),
* перенаправлять все запросы с http на https.
Последнее важно, чтобы обеспечить дополнительную безопасность.

Для быстрой копипасты:

option accept-invalid-http-request
option forwardfor header X-Real-IP
reqadd X-Forwarded-Proto:\ https if { ssl_fc }
redirect scheme https code 301 if !{ ssl_fc }


тут просто указываем сертификаты, которые будем использовать.
В нижней части в списке появляются сертификаты после прогона сервиса Acme.

И все! HAProxy настроен, можно уже проверять, что оно как то работает без валидного сертификата.

4. Acme

Тут все проще.

Подробнее:


Вот тут как раз и важно прописать такой же порт, о чем предупреждал ранее!
а в остальном — standalone режим как раз запускает демона на прослушивание 10003 порту.
Если ваш ДНС хостер имеет АПИ, и он есть в списке поддерживаемых — то лучше использовать его. В этом случае можно не настраивать HAProxy на обработку запросов acme.