HAProxy + LetsEncrypt балансировка на два веб-сервера

Автор George, Сен. 09, 2022, 08:53

« назад - далее »

George

Предисловие

Дано 3 сервера, необходимо настроить балансировку и первичную установку сертификата.

Ubuntu 18.04 - (Loadbalancing HAProxy:443)
web1 - CentOS7 (nginx:80)
web2 - CentOS7 (nginx:80)

У меня прекрасно отработала эта инструкция на ubuntu 20.04 lts и в качестве web - ispconfig на том же ubuntu

1) Когда мы запрашиваем новый сертификат, LetsEncrypt запрашивает файл авторизации (подобный URI /.well-known/acme-challenge/random-hash-here). Этот запрос будет выполняться через порт 80, так как пока нет установки сертификата. Итак, когда мы создаем новый сертификат, нам нужно, чтобы HAProxy слушал только порт 80 .

В конфиге должно быть пока вот это.

frontend my_haproxy
bind *:80
default_backend my_httpd_backend

########ACL for LE request##############
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt-backend if letsencrypt-acl

# LE Backend
backend letsencrypt-backend
server letsencrypt 127.0.0.1:8888

backend my_httpd_backend
balance roundrobin
server web1 10.164.0.3:80 #внутр инт
server web2 10.156.0.2:80  #внутр инт

=====================================================================
2)получение сертификата через certbot
certbot certonly --standalone -d web.site.kz --non-interactive --agree-tos --email nurlan@sysadm.kz --http-01-port=8888

--standalone - создать автономный веб-сервер для прослушивания HTTP-запроса авторизации сертификата

-d web.site.kz - Домен, для которого мы создаем сертификат. Вы можете использовать несколько -dфлагов для нескольких доменов для одного сертификата. Домен (ы) должен быть отправлен на сервер, на котором мы создаем сертификат (для этого необходимо настроить DNS для домена).

--non-interactive --agree-tos --email admin@example.com - Сделайте это неинтерактивным, произнеся столько же, соглашаясь с TOS, и сообщите LetsEncrypt электронной почты, чтобы использовать для отправки уведомлений «YOUR CERT IS EXIRINGING».

--http-01-port=8888. Это говорит автономному серверу прослушивать порт 8888. Обратите внимание, что LetsEncrypt по- прежнему будет отправлять HTTP-запрос авторизации через порт 80. Однако слушатель ожидает прокси (например, нашего HAProxy-сервера) для маршрутизации запроса к нему через порт 8888 . Флаг http-01 потому, что он ожидает HTTPзапроса, а не HTTPSзапроса.
=====================================================================
3) т.к Haproxy видит сертификат только как единый файл, нам необходимо всё сконвертировать.

cat /etc/letsencrypt/live/web.site.kz/fullchain.pem /etc/letsencrypt/live/web.site.kz/privkey.pem | sudo tee /etc/ssl/web.site/web.site.pem


=====================================================================
4) В haproxy.cfg добавляем наш конфиг для лоадбалансинга на два веб-сервера.

frontend my_haproxy
bind *:80
default_backend my_httpd_backend
bind *:443 ssl crt /etc/ssl/web.site.kz/web.site.pem

########ACL for LE request##############
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt-backend if letsencrypt-acl

# LE Backend
backend letsencrypt-backend
server letsencrypt 127.0.0.1:8888

backend my_httpd_backend
balance roundrobin
server web1 10.164.0.3:80 #внутр инт
server web2 10.156.0.2:80  #внутр инт
#============================================================

6) Также добавляем статистику для Haproxy, в haproxy.cfg в конец добавляем.
Статистика будет доступна в браузере: http://yourhost.kz:8000/haproxy_stats

listen stats # Define a listen section called "stats"
  bind :8000 # Listen on localhost:9000
  mode http
  stats enable  # Enable stats page
  stats hide-version  # Hide HAProxy version
  stats realm Haproxy\ Statistics  # Title text for popup window
  stats uri /haproxy_stats  # Stats URI
  stats auth admin:password  # Authentication credentials

7) Скрипт для автообновления в крон.

#!/usr/bin/env bash

# Renew the certificate
certbot renew --force-renewal --tls-sni-01-port=8888

#
bash -c "cat /etc/letsencrypt/live/web.site.kz/fullchain.pem /etc/letsencrypt/live/web.site.kz/privkey.pem > /etc/ssl/web.site.kz/web.site.kz.pem"

# Reload  HAProxy
service haproxy reload
  •  

George

ледующая строка в разделе интерфейса выполнит эту перезапись и перенаправление.

Для наглядности все это должно отображаться в одной строке вашей конфигурации:

Код: bash
http-request redirect 
        code 301 
        location https://blog.example.com%[capture.req.uri,regsub(^/blog,)]  
        if { hdr(host) -i www.example.com } { path_beg /blog }
Если заголовок узла совпадает www.example.com и путь начинается с blog, перенаправляет на местоположение, начинающееся с литеральной строкиhttps://blog.example.com, затем объединяет значение, полученное путем использования URI запроса (путь + строка запроса) и использования подстановки регулярных выражений для удаления /blogс самого начала.

Проверка:

Код: bash
$ curl -v 'http://www.example.com/blog/posts?which=this&that=1'
* Hostname was NOT found in DNS cache
*  Trying 127.0.0.1...
* Connected to www.example.com (127.0.0.1) port 80 (#0)
> GET /blog/posts?which=this&that=1 HTTP/1.1
> User-Agent: curl/7.35.0
> Host: www.example.com
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Content-length: 0
< Location: https://blog.example.com/posts?which=this&that=1
Расположение перенаправления кажется правильным.

Если вы хотите перенаправить http и https отдельно, вам понадобятся две строки, каждая из которых проверяет дополнительное условие, чтобы определить, был ли исходный запрос через http или https.
  •  

George

Для обеспечения нормальной работы форумов smf и других сайтов, у которых работает "сессия" обмена данными с конечным пользователем, необходимо добавить в бэкэнд куки:

 
Код: bash
cookie SERVERID insert indirect nocache
  •  

🡱 🡳

Отметьте интересные вам фрагменты текста и они станут доступны по уникальной ссылке в адресной строке браузера.