# Порт 80 и Let's Encrypt / ACME Сейчас в `haproxy.cfg` **порт 80 не используется**. Ниже — что иметь в виду, если появится, например, **Ubuntu** во внутренней сети, на которую нужно выпускать сертификаты **Let's Encrypt** с автообновлением. ## Нужен ли для ACME именно порт 80? **Не всегда.** У Let's Encrypt (протокол **ACME**) есть несколько типов проверки владения доменом: | Тип | Порт | Комментарий | |-----|------|-------------| | **HTTP-01** | **80** (HTTP) | Центр сертификации делает запрос вида `http://ваш-домен/.well-known/acme-challenge/...`. С **интернета** до отвечающего хоста порт **80** должен быть **доступен** (напрямую или через проброс на HAProxy). | | **DNS-01** | не нужен 80/443 | Запись в DNS; удобно, когда **80 снаружи открывать нельзя** или сертификат для внутреннего имени. | | **TLS-ALPN-01** | **443** | Проверка по TLS; порт 80 не обязателен. | Итого: при классическом **Certbot + webroot/standalone** с проверкой **HTTP-01** порт **80** действительно участвует. При **DNS-01** отдельный HTTP на 80 для выпуска не нужен. Автообновление обычно делают **`certbot renew`** по **systemd timer** или cron — это на стороне машины с Certbot, не в HAProxy. ## Если понадобится HTTP на 80 через этот HAProxy (например, HTTP-01) 1. На **пограничном роутере** разрешить с интернета **TCP 80** на IP хоста с HAProxy (или на тот хост, где будет отвечать ACME). 2. В **`haproxy.cfg`** добавить отдельный **HTTP**-фронтенд на **80** и отправлять только путь проверки на бэкенд с ответом ACME (остальное — редирект на HTTPS, пустой ответ или отказ — по политике). ## Пример: два Ubuntu в LAN и HTTP-01 через один периметровый HAProxy Допустим, во внутренней сети два сервера **Ubuntu**, для обоих нужны публичные имена и периодическое обновление сертификатов Let's Encrypt по **HTTP-01**: | Имя (снаружи) | Внутренний IP | |----------------|-----------------| | **ubuntu1.kalinamall.ru** | **192.168.160.90** | | **ubuntu2.kalinamall.ru** | **192.168.160.60** | **DNS:** записи **A** для `ubuntu1.kalinamall.ru` и `ubuntu2.kalinamall.ru` должны указывать на **тот же публичный IP**, что и для остальных сервисов за HAProxy (чтобы запросы Let's Encrypt пришли на **порт 80** этого хоста). **На каждой Ubuntu:** нужен **HTTP на порту 80** и каталог под **webroot** Certbot (`/.well-known/acme-challenge/…`). Ниже — пошагово для **nginx** (типичный вариант); в конце — кратко про **Apache**. Если открывать 80 не хотите, используйте **DNS-01** на той же машине (без этого блока). ### Пошагово: nginx + Certbot webroot на Ubuntu Выполняйте **на каждой** Ubuntu отдельно; подставляйте своё имя (`ubuntu1.kalinamall.ru` или `ubuntu2.kalinamall.ru`). 1. **Установите nginx и certbot** ```bash sudo apt update sudo apt install -y nginx certbot ``` 2. **Каталог для challenge** (Certbot будет писать сюда файлы, nginx — отдавать): ```bash sudo mkdir -p /var/www/certbot/.well-known/acme-challenge sudo chown -R www-data:www-data /var/www/certbot ``` 3. **Виртуальный хост только под ACME и имя сервера** Создайте файл, например `/etc/nginx/sites-available/acme-le.conf` (на одной машине в `server_name` — `ubuntu1.kalinamall.ru`, на другой — `ubuntu2.kalinamall.ru`): ```nginx server { listen 80 default_server; listen [::]:80 default_server; server_name ubuntu1.kalinamall.ru; location ^~ /.well-known/acme-challenge/ { root /var/www/certbot; default_type "text/plain"; } location / { return 404; } } ``` 4. **Включите сайт и перезапустите nginx** ```bash sudo ln -sf /etc/nginx/sites-available/acme-le.conf /etc/nginx/sites-enabled/ sudo rm -f /etc/nginx/sites-enabled/default sudo nginx -t && sudo systemctl reload nginx ``` Убедитесь, что снаружи (через HAProxy и открытый WAN **80**) до этой машины доходит запрос с правильным **Host** — иначе Let's Encrypt не пройдёт проверку. 5. **Первый выпуск сертификата (webroot)** Подставьте свой домен и e-mail: ```bash sudo certbot certonly --webroot -w /var/www/certbot \ -d ubuntu1.kalinamall.ru \ --email admin@example.com --agree-tos --non-interactive ``` При первом запуске можно убрать `--non-interactive`, чтобы согласиться с условиями в диалоге. **Где лежат файлы и что с ними делать (HTTPS в nginx)** После успешного `certbot certonly` каталог (симлинки) будет таким: - **`/etc/letsencrypt/live/ubuntu1.kalinamall.ru/`** — имя совпадает с **первым** `-d` в команде certbot (на второй машине — `ubuntu2...`). - **`fullchain.pem`** — ваш сертификат **и** цепочка до Let's Encrypt; его указывают в **`ssl_certificate`** (так браузеры доверяют сайту). - **`privkey.pem`** — закрытый ключ; в **`ssl_certificate_key`**. Файлы в `archive/`, в `live/` — только ссылки; при **`certbot renew`** обновляются именно они, пути в nginx **менять не нужно**. Добавьте **второй** `server` для **HTTPS** (отдельный файл или тот же `acme-le.conf` ниже блока `:80`), подставив своё имя и корень сайта: ```nginx server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name ubuntu1.kalinamall.ru; ssl_certificate /etc/letsencrypt/live/ubuntu1.kalinamall.ru/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ubuntu1.kalinamall.ru/privkey.pem; # Рекомендуемые параметры TLS (если пакет certbot их положил): # include /etc/letsencrypt/options-ssl-nginx.conf; # ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; root /var/www/html; index index.html; location / { try_files $uri $uri/ =404; } } ``` Проверка и применение: ```bash sudo nginx -t && sudo systemctl reload nginx ``` Если **443** с интернета идёт **на эту же** Ubuntu (напрямую или отдельным пробросом с маршрутизатора), снаружи откройте **TCP 443** до неё. Если HTTPS терминирует только **HAProxy**, а до Ubuntu — снова прокси, то сертификат Let's Encrypt на Ubuntu нужен **той службе**, которая реально открывает **TLS** на этой машине (или выпускайте сертификат на том узле, где крутится HTTPS). **Редирект HTTP → HTTPS на :80 (по желанию, после того как HTTPS завёлся):** в блоке `server` на **порту 80** оставьте **`location ^~ /.well-known/acme-challenge/`** как есть, а вместо `return 404` для **`location /`** поставьте **`return 301 https://$host$request_uri;`** — обновление сертификата по-прежнему идёт по **HTTP** на путь **`.well-known`**, остальное уходит на **https://**. 6. **Проверка автообновления** ```bash sudo systemctl enable --now certbot.timer sudo certbot renew --dry-run ``` 7. **Перезагрузка nginx после успешного renew** Создайте скрипт и сделайте его исполняемым: ```bash sudo install -d /etc/letsencrypt/renewal-hooks/deploy echo 'systemctl reload nginx' | sudo tee /etc/letsencrypt/renewal-hooks/deploy/01-reload-nginx.sh sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/01-reload-nginx.sh ``` Таймер **`certbot.timer`** по расписанию вызывает `certbot renew`; при обновлении сертификата выполняются hook'и из `renewal-hooks/deploy`. ### Кратко: Apache вместо nginx 1. `sudo apt install -y apache2 certbot python3-certbot-apache` (или только `certbot` и webroot без плагина apache). 2. Корень для challenge: например `sudo mkdir -p /var/www/certbot/.well-known/acme-challenge` и в виртуальном хосте на **:80** для вашего `ServerName` — `Alias /.well-known/acme-challenge /var/www/certbot/.well-known/acme-challenge` и доступ `Require all granted` для этого каталога. 3. `sudo apachectl configtest && sudo systemctl reload apache2` 4. `sudo certbot certonly --webroot -w /var/www/certbot -d ubuntu1.kalinamall.ru` (и аналогично для второго имени на второй машине). 5. Таймер **`certbot.timer`** и при необходимости hook с `systemctl reload apache2`. ## Конфигурация HAProxy для маршрутизации ACME На HAProxy — один фронтенд на **80**, маршрутизация по заголовку **Host** + путь ACME на разные бэкенды: ```text frontend fe_http bind *:80 mode http option httplog acl path_acme path_beg /.well-known/acme-challenge/ acl host_u1 hdr(host) -i ubuntu1.kalinamall.ru acl host_u2 hdr(host) -i ubuntu2.kalinamall.ru use_backend be_acme_u1 if path_acme host_u1 use_backend be_acme_u2 if path_acme host_u2 http-request deny if !path_acme backend be_acme_u1 mode http server u1 192.168.160.90:80 check backend be_acme_u2 mode http server u2 192.168.160.60:80 check ``` Let's Encrypt при проверке обращается к **`http://ubuntu1.kalinamall.ru/.well-known/...`** или **`http://ubuntu2...`** — HAProxy по **Host** пересылает запрос на нужный внутренний **:80**, где локальный веб-сервер отдаёт файлы challenge. Варианты без проброса HTTP на две машины: на каждой Ubuntu **DNS-01** (порт 80 на периметре тогда не обязателен для этих сертификатов); либо **TLS-ALPN-01** по **443** (потребуется уже другая схема на HAProxy, не этот пример). После добавления `bind :80` откройте **TCP 80** на фаерволе (см. [haproxy-install.md](haproxy-install.md)) и выполните `sudo haproxy -c -f /etc/haproxy/haproxy.cfg`.