Как стать автором
Обновить
51.68
HOSTKEY
IT-инфраструктура: сервера, VPS, GPU, коло

Несколько хостов FreeIPA за HTTP-proxy: настраиваем HAProxy 2+

Время на прочтение5 мин
Количество просмотров3.9K

Путь инженера в телекоме часто начинается со службы технической поддержки. Если вы хотите вырастить из новичков высококлассных специалистов, нужно дать им возможность работать над выходящими за рамки служебных обязанностей задачами. Мы стараемся помогать активным коллегам в развитии — это один из главных принципов HOSTKEY с момента основания компании. Публикуем заметку о реализации проксирования административной панели FreeIPA через HAProxy, написанную нашим инженером техподдержки Александром Тряпкиным.

(А здесь можно прочесть, как синхронизировать FreeIPA с Active Directory).

Проблема

У нас есть три хоста административной панели FreeIPA (freeipa01.inside.mydomain.ru, freeipa02.inside.mydomain.ru и freeipa03.inside.mydomain.ru). Необходимо обеспечить доступ к ним по одному доменному имени: freeipa.mydomain.ru. При кажущейся простоте задачи, для ее решения пришлось приложить некоторые усилия, поскольку в Интернете не нашлось готовых рецептов для HAProxy версии 2.0 и выше.  

Каждая инсталляция FreeIPA привязана к своему доменному имени, а значит нам потребуется править заголовки входящих и исходящих HTTP-запросов. Портал самообслуживания должен быть закрыт действующим сертификатом, при этом работающие в бэкенде хосты FreeIPA не должны изменяться, чтобы не затронуть взаимодействие между клиентами и серверами через API.

В старых версиях HAProxy (1+) для редактирования HTTP-заголовков использовался метод reqrep/rsprep. В сети есть инструкции по настройке HAProxy и FreeIPA с помощью этого метода, но в версии 2.0 он был помечен как deprecated, а в версии 2.1 полностью выведен из использования. Вместо rsprep мы будем использовать метод http-response.

Решение

Для начала отредактируем созданный по умолчанию конфигурационный файл HAProxy. В нем можно выделить четыре секции: global, defaults, frontend и backend. Первые две мы трогать не будем (достаточно стандартных значений), а вот frontend и backend опишем подробно:

#Секция frontend
frontend main 
    bind :80
    redirect scheme https code 301 if !{ ssl_fc } # редиректим на https
frontend main_ssl
    bind :443 ssl crt /etc/haproxy/ssl/ # используем сертификаты из директории 
    use_backend freeipa if { ssl_fc_sni freeipa.mydomain.ru  } # в случае если обращаются к freeipa.mydomain.ru используем backend FreeIPA
#Секция backend
backend freeipa
  mode http
  balance roundrobin # по очереди распределяем нагрузку по хостам
  cookie SERVERID insert indirect nocache httponly secure # добавляем cookie для направления трафика на основе него
#acl для request на основе добавленного cookei
  acl hdr_req_ipa01 req.hdr(Cookie) -m sub ipa01 
  acl hdr_req_ipa02 req.hdr(Cookie) -m sub ipa02 
  acl hdr_req_ipa03 req.hdr(Cookie) -m sub ipa03 
#--------------------------------------------------------------------------
#В зависимости от того, каким cookie помечен наш запрос, изменяем заголовки Host и Referer 
  http-request set-header Host freeipa01.inside.mydomain.ru if hdr_req_ipa01
  http-request replace-header Referer ^https?://freeipa\.mydomain\.ru(.*)$   https://freeipa01\.inside\.mydomain\.ru\1  if hdr_req_ipa01
  http-request set-header Host freeipa02.inside.mydomain.ru if hdr_req_ipa02
  http-request replace-header Referer ^https?://freeipa\.mydomain\.ru(.*)$ https://freeipa01\.inside\.mydomain\.ru\1 if hdr_req_ipa02
  http-request set-header Host freeipa03.inside.mydomain.ru if hdr_req_ipa03
  http-request replace-header Referer ^https?://freeipa\.mydomain\.ru(.*)$ https://freeipa01\.inside\.mydomain\.ru\1 if hdr_req_ipa03
#--------------------------------------------------------------------------
#acl для response на основе заголовка Location 
  acl hdr_ipa01 res.hdr(Location) -m sub freeipa01.inside.mydomain.ru
  acl hdr_ipa02 res.hdr(Location) -m sub freeipa02.inside.mydomain.ru
  acl hdr_ipa03 res.hdr(Location) -m sub freeipa03.inside.mydomain.ru
#--------------------------------------------------------------------------
#В зависимости от того с какого хоста пришел ответ редактируем заголовки Set-Cookie и Location Без редактирования заголовка Location мы столкнемся со следующей проблемой: пользователь при переходе по ссылке freeipa.mydomain.ru будет переброшен на один из хостов freeipa0x.inside.mydomain.ru (это важный момент пропущенный во всех найденных руководствах)
  http-response replace-header Set-Cookie ^Domain=freeipa01\.inside\.mydomain\.ru(.*) Domain=freeipa\.mydomain\.ru\1 if hdr_ipa01
  http-response replace-value Location ^https?://freeipa01\.inside\.mydomain\.ru(.*)$ https://freeipa\.mydomain\.ru\1 if hdr_ipa01
  http-response replace-header Set-Cookie ^Domain=freeipa02\.inside\.mydomain\.ru(.*) Domain=freeipa\.mydomain\.ru\1 if hdr_ipa02
  http-response replace-value Location ^https?://freeipa02\.inside\.mydomain\.ru(.*)$ https://freeipa\.mydomain\.ru\1 if hdr_ipa02
  http-response replace-header Set-Cookie ^Domain=freeipa03\.inside\.mydomain\.ru(.*) Domain=freeipa\.mydomain\.ru\1 if hdr_ipa03
  http-response replace-value Location ^https?://freeipa03\.inside\.mydomain\.ru(.*)$ https://freeipa\.mydomain\.ru\1 if hdr_ipa03
#--------------------------------------------------------------------------
#Здесь указываем наши хосты FreeIPA
    server ipa01 freeipa01.inside.mydomain.ru:443 check port 443 inter 5s rise 2 fall 5 cookie ipa01 weight 9 ssl verify none
    server ipa02 freeipa02.inside.mydomain.ru:443 check port 443 inter 5s rise 2 fall 5 cookie ipa02 weight 1 ssl verify none
    server ipa03 freeipa03.inside.mydomain.ru:443 check port 443 inter 5s rise 2 fall 5 cookie ipa03 weight 3 ssl verify none
#check port 443 - проверяем жив ли хост по 443 порту.
#inter 5s - проверяем доступность с интервалом 5 секунд. 
#rise 2 fall 5 - если 2 раза проверка скажет что хост недоступен он будет исключен из балансировки и возвращен после 5 успешных проверок
#cookie ipa0x - указывает какое cookie будет добавляться “cookie SERVERID insert”
#ssl verify none - терминация SSL-сертификата игнорируя ошибки
#weight 3 указываем приоритет распределения нагрузки

Также вы можете столкнуться с надоедливым окном базовой авторизации в браузерах Chrome, Edge, IE и некоторых других.

Появление этого окна описано в багрепорте и там же есть решение проблемы, но при помощи HAProxy ее можно обойти без изменения конфигурации хостов. Для этого добавим в секцию backend конфигурационного файла следующую строку:

http-response del-header www-authenticate

Она удалит из ответа хоста заголовок, ответственный за появление навязчивого окна.

Итоги

Сравнив решение задачи с помощью rsprep и через http-response, можно лучше разобраться в логике HAProxy и научиться работать с HTTP-запросами на более глубоком уровне.

_________

Как видите, поддерживать инициативу инженеров технической поддержки полезно для бизнеса. Мы не только помогаем специалистам развиваться и делать карьеру (что опять-таки выгодно работодателю), но и получаем полезные клиентам прикладные разработки, а также интересные заметки для корпоративного блога. Надеемся, наше решение пригодится читателям.

А специальный промокод «Я С ХАБРА» тоже может пригодиться: назовите его консультанту на сайте при размещении заказа, чтобы получить дополнительную скидку. Платить можно как всегда в рублях с НДС российской компании или в евро — компании в Нидерландах.

Теги:
Хабы:
Всего голосов 4: ↑3 и ↓1+2
Комментарии0

Публикации

Информация

Сайт
www.hostkey.ru
Дата регистрации
Дата основания
Численность
31–50 человек
Местоположение
Россия