README: сократить до заголовка и таблицы, вынести инструкции в docs/
Убраны упоминания GitHub; ссылка только на git.kalinamall.ru. Добавлены docs/git.md, docs/haproxy-install.md, docs/letsencrypt-acme.md.
This commit is contained in:
@@ -4,133 +4,7 @@
|
|||||||
|
|
||||||
TLS: на целевых серверах в основном **wildcard-сертификаты GlobalSign**; **Git** (`git.kalinamall.ru`) использует **свой** сертификат на **192.168.160.129**. HAProxy на **443** работает в режиме **TCP + SNI** и **не терминирует** TLS — сертификаты остаются на бэкендах.
|
TLS: на целевых серверах в основном **wildcard-сертификаты GlobalSign**; **Git** (`git.kalinamall.ru`) использует **свой** сертификат на **192.168.160.129**. HAProxy на **443** работает в режиме **TCP + SNI** и **не терминирует** TLS — сертификаты остаются на бэкендах.
|
||||||
|
|
||||||
Репозиторий: [https://github.com/PTah/reverse-proxy](https://github.com/PTah/reverse-proxy)
|
Репозиторий: [https://git.kalinamall.ru/PapaTramp/reverse-proxy](https://git.kalinamall.ru/PapaTramp/reverse-proxy)
|
||||||
|
|
||||||
## Клонирование на Ubuntu, обновление и доступ без постоянного ввода пароля
|
|
||||||
|
|
||||||
### Установка Git
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y git
|
|
||||||
```
|
|
||||||
|
|
||||||
### Первое клонирование
|
|
||||||
|
|
||||||
**Публичный** репозиторий можно клонировать **без логина и пароля**:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ~
|
|
||||||
git clone https://github.com/PTah/reverse-proxy.git
|
|
||||||
cd reverse-proxy
|
|
||||||
```
|
|
||||||
|
|
||||||
Если репозиторий станет **приватным** или понадобятся **push**-правки с сервера, используйте один из способов ниже.
|
|
||||||
|
|
||||||
### Обновление локальной копии
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ~/reverse-proxy
|
|
||||||
git pull origin main
|
|
||||||
```
|
|
||||||
|
|
||||||
После `git pull` снова скопируйте при необходимости файлы в `/etc/haproxy/` (см. раздел «Установка конфигурации»).
|
|
||||||
|
|
||||||
### Как не вводить логин и пароль при каждом `git pull` / `git push`
|
|
||||||
|
|
||||||
#### Способ 1: SSH-ключ (предпочтительно)
|
|
||||||
|
|
||||||
1. Создайте ключ (имя файла можно своё):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ssh-keygen -t ed25519 -C "ubuntu-haproxy" -f ~/.ssh/id_ed25519_github
|
|
||||||
```
|
|
||||||
|
|
||||||
Парольную фразу можно задать или оставить пустой (на сервере оцените риски).
|
|
||||||
|
|
||||||
2. Покажите **публичный** ключ и добавьте его в GitHub: **Settings → SSH and GPG keys → New SSH key**.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cat ~/.ssh/id_ed25519_github.pub
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Проверьте доступ:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ssh -T git@github.com
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Клонируйте по **SSH** (или смените URL у уже существующего клона):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone git@github.com:PTah/reverse-proxy.git
|
|
||||||
# уже склонировано по HTTPS — переключение:
|
|
||||||
# git remote set-url origin git@github.com:PTah/reverse-proxy.git
|
|
||||||
```
|
|
||||||
|
|
||||||
Дальше `git pull` / `git push` идут по SSH **без пароля GitHub** (при необходимости один раз вводится только passphrase ключа, если вы её задали; её можно кешировать через `ssh-agent`).
|
|
||||||
|
|
||||||
#### Способ 2: HTTPS + Personal Access Token (PAT)
|
|
||||||
|
|
||||||
GitHub **не принимает** обычный пароль от аккаунта для операций `git clone` / `git pull` / `git push` по **HTTPS**. Вместо пароля нужно создать **Personal Access Token (PAT)** и вводить его там, где Git спрашивает пароль.
|
|
||||||
|
|
||||||
##### Создание классического токена (Tokens classic) — проще всего для Git
|
|
||||||
|
|
||||||
1. Войдите на **github.com** под нужным аккаунтом.
|
|
||||||
2. В правом верхнем углу откройте меню **аватара** → **Settings** (Настройки).
|
|
||||||
3. В **левой колонке** прокрутите вниз до раздела **Developer settings** (Параметры разработчика) и откройте его.
|
|
||||||
4. Выберите **Personal access tokens** → **Tokens (classic)**.
|
|
||||||
5. Нажмите **Generate new token** → **Generate new token (classic)**.
|
|
||||||
6. Заполните поля:
|
|
||||||
- **Note** — произвольное имя (например `ubuntu-haproxy-pull`), чтобы потом понимать, зачем токен.
|
|
||||||
- **Expiration** — срок действия (чем короче, тем безопаснее; для сервера часто выбирают ограниченный срок и потом перевыпускают).
|
|
||||||
- **Select scopes** — для **приватного** репозитория и `pull`/`push` включите минимум **`repo`** (полный доступ к репозиториям). Если нужен только **чтение** приватного репо, в классических токенах по-прежнему часто отмечают **`repo`**, т.к. узкого «только read» в classic нет; для **только pull** удобнее **fine-grained** (ниже).
|
|
||||||
7. Нажмите **Generate token** внизу страницы.
|
|
||||||
8. **Сразу скопируйте** строку токена (начинается часто с `ghp_…`). GitHub покажет её **один раз**; после ухода со страницы повторно не отобразит.
|
|
||||||
|
|
||||||
##### Fine-grained token (по желанию, гибче по правам)
|
|
||||||
|
|
||||||
1. Те же **Settings** → **Developer settings** → **Personal access tokens** → **Fine-grained tokens**.
|
|
||||||
2. **Generate new token**.
|
|
||||||
3. Укажите **имя**, **срок**, в блоке **Repository access** выберите «только выбранный репозиторий» **reverse-proxy** (или «все» — по политике безопасности).
|
|
||||||
4. В **Permissions** для чтения/обновления кода задайте **Contents**: Read-only или Read and write, при необходимости **Metadata**: Read.
|
|
||||||
5. Создайте токен и **скопируйте** его (формат обычно `github_pat_…`).
|
|
||||||
|
|
||||||
##### Использование PAT в Git на Ubuntu
|
|
||||||
|
|
||||||
- **Username** (логин): ваш **логин GitHub** (короткое имя пользователя), не e-mail, если Git явно просит username.
|
|
||||||
- **Password**: вставьте **целиком PAT** (не пароль от сайта).
|
|
||||||
|
|
||||||
Пример первого клонирования по HTTPS:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/PTah/reverse-proxy.git
|
|
||||||
# при запросе: Username = ваш_логин_github
|
|
||||||
# Password = вставить PAT
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Чтобы не вводить PAT каждый раз
|
|
||||||
|
|
||||||
Токен хранится **в открытом виде** в `~/.git-credentials` — используйте только на **доверенных** машинах:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git config --global credential.helper store
|
|
||||||
cd ~/reverse-proxy
|
|
||||||
git pull origin main
|
|
||||||
# один раз ввести Username + PAT — дальше подставятся из файла
|
|
||||||
```
|
|
||||||
|
|
||||||
Кеш в памяти на заданное время (секунды), без постоянной записи в файл:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git config --global credential.helper 'cache --timeout=28800'
|
|
||||||
```
|
|
||||||
|
|
||||||
После истечения срока кеша или срока действия токена на GitHub снова создайте новый PAT и при необходимости обновите сохранённые учётные данные (удалите строчку с `github.com` из `~/.git-credentials` или снова выполните `git pull` и введите новый токен).
|
|
||||||
|
|
||||||
#### Способ 3: только чтение, репозиторий публичный
|
|
||||||
|
|
||||||
Для **публичного** репозитория `git clone` и `git pull` по HTTPS **учётные данные не нужны** — отдельная настройка не требуется.
|
|
||||||
|
|
||||||
## Соответствие имён и адресов
|
## Соответствие имён и адресов
|
||||||
|
|
||||||
@@ -142,256 +16,15 @@ git config --global credential.helper 'cache --timeout=28800'
|
|||||||
| 1С | `erp.kalinamall.ru` | hp-serv.b26.kalinamall.ru — **192.168.160.150** | 443 |
|
| 1С | `erp.kalinamall.ru` | hp-serv.b26.kalinamall.ru — **192.168.160.150** | 443 |
|
||||||
| Git (HTTPS) | `git.kalinamall.ru` | git.kalinamall.ru — **192.168.160.129** (свой TLS-сертификат; снаружи HAProxy пускает только **5.100.81.121**) | 443 (TCP/SNI) |
|
| Git (HTTPS) | `git.kalinamall.ru` | git.kalinamall.ru — **192.168.160.129** (свой TLS-сертификат; снаружи HAProxy пускает только **5.100.81.121**) | 443 (TCP/SNI) |
|
||||||
| Почтовый шлюз (KSMG) | `ksmg.kalinamall.ru` | ksmg.kalinamall.ru — **192.168.160.57** | 25 |
|
| Почтовый шлюз (KSMG) | `ksmg.kalinamall.ru` | ksmg.kalinamall.ru — **192.168.160.57** | 25 |
|
||||||
|
|
||||||
DNS: записи **A** для `ext`, **`autodiscover`**, `rds`, `erp`, **`git`**, `ksmg` должны указывать на **публичный IP** хоста с HAProxy. Имя `autodiscover.kalinamall.ru` должно быть в **SAN** wildcard `*.kalinamall.ru` или отдельно в сертификате на Exchange.
|
DNS: записи **A** для `ext`, **`autodiscover`**, `rds`, `erp`, **`git`**, `ksmg` должны указывать на **публичный IP** хоста с HAProxy. Имя `autodiscover.kalinamall.ru` должно быть в **SAN** wildcard `*.kalinamall.ru` или отдельно в сертификате на Exchange.
|
||||||
|
|
||||||
Доступ по **SSH** к внутренним хостам (например Ubuntu **192.168.160.85**) в этом репозитории **не** настраивается через HAProxy — организуйте отдельно (прямой проброс, VPN, бастион и т.д.).
|
Доступ по **SSH** к внутренним хостам (например Ubuntu **192.168.160.85**) в этом репозитории **не** настраивается через HAProxy — организуйте отдельно (прямой проброс, VPN, бастион и т.д.).
|
||||||
|
|
||||||
В режиме **TCP + SNI** отдельные строки в HAProxy для путей вроде `/owa` **не нужны**: после согласования TLS клиент шлёт HTTP внутри шифрования, разбор путей делает **IIS/Exchange** на `192.168.160.42`.
|
В режиме **TCP + SNI** отдельные строки в HAProxy для путей вроде `/owa` **не нужны**: после согласования TLS клиент шлёт HTTP внутри шифрования, разбор путей делает **IIS/Exchange** на `192.168.160.42`.
|
||||||
|
|
||||||
## Установка HAProxy на Ubuntu 24.04 (Noble)
|
## Документация
|
||||||
|
|
||||||
Для этого репозитория нужен HAProxy **не ниже 2.4**. Конструкции `req_ssl_sni` и `tcp-request content accept` (разбор ClientHello для SNI в TCP-режиме) входят в штатные сборки **2.8.x** из Ubuntu 24.04 и во все актуальные ветки **3.x**.
|
- [Установка HAProxy и развёртывание конфигурации](docs/haproxy-install.md)
|
||||||
|
- [Работа с Git: clone, pull, push, ключи и PAT](docs/git.md)
|
||||||
### Вариант 1: пакет из репозитория Ubuntu (HAProxy 2.8.x)
|
- [Let's Encrypt / ACME через HAProxy (порт 80)](docs/letsencrypt-acme.md)
|
||||||
|
|
||||||
Обычно этого достаточно для данного конфига:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y haproxy
|
|
||||||
haproxy -v
|
|
||||||
```
|
|
||||||
|
|
||||||
Проверьте, что версия **2.4+** (на Noble обычно **2.8.x**).
|
|
||||||
|
|
||||||
### Вариант 2: последняя ветка 3.x (PPA Vincent Bernat)
|
|
||||||
|
|
||||||
Актуальные пакеты **HAProxy 3.3.x** для Noble публикуются в PPA [vbernat/haproxy-3.3](https://launchpad.net/~vbernat/+archive/ubuntu/haproxy-3.3) (номер микроверсии может обновляться; см. страницу PPA). Не подключайте одновременно несколько PPA с разными ветками HAProxy.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y software-properties-common
|
|
||||||
sudo add-apt-repository -y ppa:vbernat/haproxy-3.3
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y haproxy
|
|
||||||
haproxy -v
|
|
||||||
sudo systemctl enable --now haproxy
|
|
||||||
```
|
|
||||||
|
|
||||||
Другие ветки того же автора (при необходимости): [haproxy-3.2](https://launchpad.net/~vbernat/+archive/ubuntu/haproxy-3.2), [haproxy-3.1](https://launchpad.net/~vbernat/+archive/ubuntu/haproxy-3.1), [haproxy-3.0](https://launchpad.net/~vbernat/+archive/ubuntu/haproxy-3.0), а также [haproxy-2.8](https://launchpad.net/~vbernat/+archive/ubuntu/haproxy-2.8) — всегда выбирайте **одну** строку версии.
|
|
||||||
|
|
||||||
### Проверка синтаксиса конфига
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
|
|
||||||
```
|
|
||||||
|
|
||||||
## Установка конфигурации из репозитория
|
|
||||||
|
|
||||||
1. Убедитесь, что установлен HAProxy **2.4+** (см. раздел выше).
|
|
||||||
|
|
||||||
2. Скопируйте `haproxy.cfg` в `/etc/haproxy/haproxy.cfg`. Пример, если репозиторий лежит в домашнем каталоге:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo cp ~/reverse-proxy/haproxy.cfg /etc/haproxy/haproxy.cfg
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Проверка и перезапуск:
|
|
||||||
```bash
|
|
||||||
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
|
|
||||||
sudo systemctl reload haproxy
|
|
||||||
```
|
|
||||||
|
|
||||||
## Проверка `ssl verify none` на бэкендах
|
|
||||||
|
|
||||||
В `backend` для 443 указано `ssl verify none`, чтобы health-check и при необходимости установка соединения не ломались на внутренних именах/SAN. Если вы выпустите внутренние доверенные CA и зададите их в системе, можно включить проверку (`verify required` + `ca-file`).
|
|
||||||
|
|
||||||
## Порты на фаерволе
|
|
||||||
|
|
||||||
На хосте с HAProxy с интернета обычно открывают только то, что слушает конфиг: **25**, **443** (и при использовании — **8404** для stats). Остальной трафик — по политике безопасности.
|
|
||||||
|
|
||||||
## Порт 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:** один фронтенд на **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` допишите в раздел **«Порты на фаерволе»** выше порт **80** и выполните `sudo haproxy -c -f /etc/haproxy/haproxy.cfg`.
|
|
||||||
|
|
||||||
## Лицензия
|
|
||||||
|
|
||||||
Конфигурация поставляется как есть, без гарантий. Используйте на свой риск.
|
|
||||||
|
|||||||
+109
@@ -0,0 +1,109 @@
|
|||||||
|
# Работа с Git на Ubuntu
|
||||||
|
|
||||||
|
Репозиторий: [https://git.kalinamall.ru/PapaTramp/reverse-proxy](https://git.kalinamall.ru/PapaTramp/reverse-proxy)
|
||||||
|
|
||||||
|
## Установка Git
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y git
|
||||||
|
```
|
||||||
|
|
||||||
|
## Первое клонирование
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~
|
||||||
|
git clone https://git.kalinamall.ru/PapaTramp/reverse-proxy.git
|
||||||
|
cd reverse-proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
Для **push** с сервера настройте SSH-ключ или PAT (см. ниже).
|
||||||
|
|
||||||
|
## Обновление локальной копии
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/reverse-proxy
|
||||||
|
git pull origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
После `git pull` снова скопируйте при необходимости файлы в `/etc/haproxy/` (см. [haproxy-install.md](haproxy-install.md)).
|
||||||
|
|
||||||
|
## Как не вводить логин и пароль при каждом `git pull` / `git push`
|
||||||
|
|
||||||
|
### Способ 1: SSH-ключ (предпочтительно)
|
||||||
|
|
||||||
|
1. Создайте ключ (имя файла можно своё):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh-keygen -t ed25519 -C "ubuntu-haproxy" -f ~/.ssh/id_ed25519_kalinamall
|
||||||
|
```
|
||||||
|
|
||||||
|
Парольную фразу можно задать или оставить пустой (на сервере оцените риски).
|
||||||
|
|
||||||
|
2. Покажите **публичный** ключ и добавьте его на **git.kalinamall.ru**: профиль → **Settings** → **SSH / GPG Keys** → **Add Key**.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat ~/.ssh/id_ed25519_kalinamall.pub
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Проверьте доступ:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh -T git@git.kalinamall.ru
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Клонируйте по **SSH** (или смените URL у уже существующего клона):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone git@git.kalinamall.ru:PapaTramp/reverse-proxy.git
|
||||||
|
# уже склонировано по HTTPS — переключение:
|
||||||
|
# git remote set-url origin git@git.kalinamall.ru:PapaTramp/reverse-proxy.git
|
||||||
|
```
|
||||||
|
|
||||||
|
Дальше `git pull` / `git push` идут по SSH **без пароля** (при необходимости один раз вводится только passphrase ключа, если вы её задали; её можно кешировать через `ssh-agent`).
|
||||||
|
|
||||||
|
### Способ 2: HTTPS + Personal Access Token (PAT)
|
||||||
|
|
||||||
|
**git.kalinamall.ru** не принимает обычный пароль от аккаунта для операций `git clone` / `git pull` / `git push` по **HTTPS**. Вместо пароля нужно создать **Personal Access Token (PAT)** и вводить его там, где Git спрашивает пароль.
|
||||||
|
|
||||||
|
#### Создание токена
|
||||||
|
|
||||||
|
1. Войдите на **git.kalinamall.ru** под нужным аккаунтом.
|
||||||
|
2. Откройте **Settings** (Настройки) → **Applications** (или **Access Tokens**).
|
||||||
|
3. Создайте новый токен:
|
||||||
|
- **Name** — произвольное имя (например `ubuntu-haproxy-pull`), чтобы потом понимать, зачем токен.
|
||||||
|
- **Expiration** — срок действия (чем короче, тем безопаснее; для сервера часто выбирают ограниченный срок и потом перевыпускают).
|
||||||
|
- **Scopes** — для `pull`/`push` включите минимум **`read:repository`** и **`write:repository`** (или эквивалентные права на репозиторий).
|
||||||
|
4. **Сразу скопируйте** строку токена — сервер покажет её **один раз**; после ухода со страницы повторно не отобразит.
|
||||||
|
|
||||||
|
#### Использование PAT в Git на Ubuntu
|
||||||
|
|
||||||
|
- **Username** (логин): ваш **логин** на git.kalinamall.ru, не e-mail, если Git явно просит username.
|
||||||
|
- **Password**: вставьте **целиком PAT** (не пароль от сайта).
|
||||||
|
|
||||||
|
Пример первого клонирования по HTTPS:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.kalinamall.ru/PapaTramp/reverse-proxy.git
|
||||||
|
# при запросе: Username = ваш_логин
|
||||||
|
# Password = вставить PAT
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Чтобы не вводить PAT каждый раз
|
||||||
|
|
||||||
|
Токен хранится **в открытом виде** в `~/.git-credentials` — используйте только на **доверенных** машинах:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git config --global credential.helper store
|
||||||
|
cd ~/reverse-proxy
|
||||||
|
git pull origin main
|
||||||
|
# один раз ввести Username + PAT — дальше подставятся из файла
|
||||||
|
```
|
||||||
|
|
||||||
|
Кеш в памяти на заданное время (секунды), без постоянной записи в файл:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git config --global credential.helper 'cache --timeout=28800'
|
||||||
|
```
|
||||||
|
|
||||||
|
После истечения срока кеша или срока действия токена снова создайте новый PAT и при необходимости обновите сохранённые учётные данные (удалите строчку с `git.kalinamall.ru` из `~/.git-credentials` или снова выполните `git pull` и введите новый токен).
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
# Установка HAProxy и развёртывание конфигурации
|
||||||
|
|
||||||
|
Для этого репозитория нужен HAProxy **не ниже 2.4**. Конструкции `req_ssl_sni` и `tcp-request content accept` (разбор ClientHello для SNI в TCP-режиме) входят в штатные сборки **2.8.x** из Ubuntu 24.04 и во все актуальные ветки **3.x**.
|
||||||
|
|
||||||
|
## Вариант 1: пакет из репозитория Ubuntu (HAProxy 2.8.x)
|
||||||
|
|
||||||
|
Обычно этого достаточно для данного конфига:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y haproxy
|
||||||
|
haproxy -v
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверьте, что версия **2.4+** (на Noble обычно **2.8.x**).
|
||||||
|
|
||||||
|
## Вариант 2: последняя ветка 3.x (PPA Vincent Bernat)
|
||||||
|
|
||||||
|
Актуальные пакеты **HAProxy 3.3.x** для Noble публикуются в PPA [vbernat/haproxy-3.3](https://launchpad.net/~vbernat/+archive/ubuntu/haproxy-3.3) (номер микроверсии может обновляться; см. страницу PPA). Не подключайте одновременно несколько PPA с разными ветками HAProxy.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y software-properties-common
|
||||||
|
sudo add-apt-repository -y ppa:vbernat/haproxy-3.3
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y haproxy
|
||||||
|
haproxy -v
|
||||||
|
sudo systemctl enable --now haproxy
|
||||||
|
```
|
||||||
|
|
||||||
|
Другие ветки того же автора (при необходимости): [haproxy-3.2](https://launchpad.net/~vbernat/+archive/ubuntu/haproxy-3.2), [haproxy-3.1](https://launchpad.net/~vbernat/+archive/ubuntu/haproxy-3.1), [haproxy-3.0](https://launchpad.net/~vbernat/+archive/ubuntu/haproxy-3.0), а также [haproxy-2.8](https://launchpad.net/~vbernat/+archive/ubuntu/haproxy-2.8) — всегда выбирайте **одну** строку версии.
|
||||||
|
|
||||||
|
## Проверка синтаксиса конфига
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
|
||||||
|
```
|
||||||
|
|
||||||
|
## Установка конфигурации из репозитория
|
||||||
|
|
||||||
|
1. Убедитесь, что установлен HAProxy **2.4+** (см. разделы выше).
|
||||||
|
|
||||||
|
2. Скопируйте `haproxy.cfg` в `/etc/haproxy/haproxy.cfg`. Пример, если репозиторий лежит в домашнем каталоге:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo cp ~/reverse-proxy/haproxy.cfg /etc/haproxy/haproxy.cfg
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Проверка и перезапуск:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
|
||||||
|
sudo systemctl reload haproxy
|
||||||
|
```
|
||||||
|
|
||||||
|
## Проверка `ssl verify none` на бэкендах
|
||||||
|
|
||||||
|
В `backend` для 443 указано `ssl verify none`, чтобы health-check и при необходимости установка соединения не ломались на внутренних именах/SAN. Если вы выпустите внутренние доверенные CA и зададите их в системе, можно включить проверку (`verify required` + `ca-file`).
|
||||||
|
|
||||||
|
## Порты на фаерволе
|
||||||
|
|
||||||
|
На хосте с HAProxy с интернета обычно открывают только то, что слушает конфиг: **25**, **443** (и при использовании — **8404** для stats). Остальной трафик — по политике безопасности.
|
||||||
|
|
||||||
|
Если позже добавите фронтенд на **80** для ACME (см. [letsencrypt-acme.md](letsencrypt-acme.md)), откройте и **TCP 80**.
|
||||||
@@ -0,0 +1,192 @@
|
|||||||
|
# Порт 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`.
|
||||||
Reference in New Issue
Block a user