Files
owngit/docs/gitea-nginx-https.md
T
PTah 46577f8b76 docs: scp PFX from NAS path example
Made-with: Cursor
2026-04-22 14:38:24 +10:00

184 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Nginx и HTTPS на сервере с Gitea (kalinamall.ru)
В схеме **[`docs/haproxy-kalinamall.cfg`](haproxy-kalinamall.cfg)** и **[`docs/haproxy-kalinamall.md`](haproxy-kalinamall.md)** периметровый HAProxy пересылает TCP **`:443`** на узел Gitea (**`192.168.160.129:443`**). Контейнер Gitea по умолчанию слушает только **HTTP `:3000`**, поэтому на самом сервере нужен **TLS-терминатор на `:443`** — здесь описан **nginx** перед контейнером.
Цепочка:
```text
Клиент → (опционально HAProxy TCP+SNI) → nginx :443 (TLS, wildcard) → HTTP → 127.0.0.1:3000 → Gitea
```
## 1. Предварительные условия
- Gitea в Docker уже слушает **`127.0.0.1:3000`** (или `0.0.0.0:3000`).
- Есть файлы сертификата **wildcard `*.kalinamall.ru`** (цепочка + ключ), выданные GlobalSign или экспортированные в PEM.
На Ubuntu 24.04:
```bash
sudo apt-get update
sudo apt-get install -y nginx
```
## 2. Каталог для сертификатов и права
Создайте каталог и положите туда **fullchain** (или сертификат + цепочка в одном PEM) и **приватный ключ**. Имена файлов могут быть любыми — ниже они должны совпасть с путями в конфиге nginx.
Пример:
```bash
sudo mkdir -p /etc/nginx/ssl/kalinamall
sudo install -m 0644 /путь/к/fullchain.pem /etc/nginx/ssl/kalinamall/git.kalinamall.ru-fullchain.pem
sudo install -m 0600 /путь/к/privkey.pem /etc/nginx/ssl/kalinamall/git.kalinamall.ru.key
sudo chown root:root /etc/nginx/ssl/kalinamall/*
```
### Сертификат в формате PFX (`.pfx` / `.p12`)
Файл можно скопировать с другого узла по **SCP** (пример: Synology NAS `192.168.160.185`, путь в DSM как `volume1\SOFT\...` на SSH задаётся слэшами от `/volume1`):
```bash
scp USER@192.168.160.185:/volume1/SOFT/Certs/2026/Export/pfx-pem/wildcard_kalinamall_ru.pfx /tmp/
```
Подставьте **`USER`** и при необходимости проверьте путь на NAS: `ssh USER@192.168.160.185 'ls /volume1/SOFT/Certs/2026/Export/pfx-pem/'`. На Synology должен быть включён **SSH**.
Nginx **не** читает PFX напрямую в `ssl_certificate` / `ssl_certificate_key` — нужны **PEM**: отдельно **цепочка** (сервер + промежуточные CA) и **закрытый ключ**. PFX — контейнер, из него извлекают OpenSSL (пароль к PFX введёте по запросу):
```bash
# Закрытый ключ (права только root)
openssl pkcs12 -in wildcard.pfx -nocerts -nodes -out git.kalinamall.ru.key
# Сертификаты из контейнера (серверный + при необходимости цепочку соберите в один fullchain ниже)
openssl pkcs12 -in wildcard.pfx -clcerts -nokeys -out cert.pem
openssl pkcs12 -in wildcard.pfx -cacerts -nokeys -out chain.pem 2>/dev/null || true
```
Часто для **`ssl_certificate`** нужен один файл «сервер + промежуточные»:
```bash
cat cert.pem chain.pem > git.kalinamall.ru-fullchain.pem
sudo chmod 0600 git.kalinamall.ru.key
sudo chmod 0644 git.kalinamall.ru-fullchain.pem
```
На OpenSSL 3 старые PFX иногда требуют флаг **`-legacy`** к `pkcs12`. При ошибках расшифровки проверьте пароль и точное имя алиаса в PFX (`openssl pkcs12 -in wildcard.pfx -info -noout`).
Пути к получившимся **`…-fullchain.pem`** и **`…key`** подставьте в конфиг nginx.
## 3. Map для WebSocket
Gitea в браузере использует WebSocket. Директива **`map`** должна быть в контексте **`http {}`** один раз на весь nginx.
Скопируйте пример из репозитория:
- [`nginx/conf.d-map-websocket.conf.example`](../nginx/conf.d-map-websocket.conf.example)
```bash
sudo cp /opt/owngit/nginx/conf.d-map-websocket.conf.example /etc/nginx/conf.d/zz-map-websocket.conf
```
(Путь `/opt/owngit` замените на каталог вашего клона `owngit`.)
Либо вставьте содержимое файла вручную в `/etc/nginx/nginx.conf` внутрь блока `http { … }`.
## 4. Виртуальный хост
Скопируйте и отредактируйте пути к PEM:
- [`nginx/git.kalinamall.ru.conf.example`](../nginx/git.kalinamall.ru.conf.example)
```bash
sudo cp /opt/owngit/nginx/git.kalinamall.ru.conf.example /etc/nginx/sites-available/git.kalinamall.ru
sudo nano /etc/nginx/sites-available/git.kalinamall.ru # ssl_certificate / ssl_certificate_key
sudo ln -sf /etc/nginx/sites-available/git.kalinamall.ru /etc/nginx/sites-enabled/
```
Уберите или отключите дефолтный сайт, если он мешает:
```bash
sudo rm -f /etc/nginx/sites-enabled/default
```
Проверка и перезагрузка:
```bash
sudo nginx -t
sudo systemctl reload nginx
sudo ss -tlnp | grep ':443'
```
Должен появиться **`LISTEN`** на **`0.0.0.0:443`** (nginx).
## 5. Фаервол
При использовании UFW:
```bash
sudo ufw allow 443/tcp comment 'nginx Gitea HTTPS'
sudo ufw status verbose
```
(Порт **2222** для Git по SSH открывайте по вашей политике — на периметре его обычно публикует HAProxy.)
## 6. Gitea: `app.ini`
Контейнер по-прежнему отдаёт **HTTP** на `:3000`. Снаружи пользователи ходят по **HTTPS**, поэтому:
```ini
[server]
ROOT_URL = https://git.kalinamall.ru/
PROTOCOL = http
DOMAIN = git.kalinamall.ru
```
Убедитесь, что в **`[server]`** не задан лишний порт в URL, если публикуете стандартный **443**. После правок:
```bash
cd /opt/gitea && sudo docker compose restart gitea
```
Подробнее про секреты — в [README](../README.md) и в `gitea/app.ini.example`.
## 7. Проверки
На сервере Gitea:
```bash
curl -sS -o /dev/null -w "%{http_code}\n" https://git.kalinamall.ru/api/healthz
```
Ожидается **200**. Локально без nginx (только контейнер):
```bash
curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:3000/api/healthz
```
С другой машины в LAN (DNS на **192.168.160.129** или через HAProxy):
```bash
curl -v https://git.kalinamall.ru/api/healthz
```
## 8. Связка с периметровым HAProxy
- DNS **`git.kalinamall.ru`** снаружи → публичный IP **HAProxy**; HAProxy по SNI шлёт TCP на **`192.168.160.129:443`** → **nginx** завершает TLS и шлёт HTTP на **3000**.
- Внутри LAN можно использовать **Split DNS**: то же имя → **192.168.160.129** или → LAN IP HAProxy — согласуйте с тем, где должен приниматься первый TLS-hop.
Если nginx и Gitea стоят корректно, ошибка **`connection refused` на :443** до nginx исчезнет.
## 9. Опционально: редирект HTTP → HTTPS
Если нужен отдельный сервер на порту **80** только для редиректа:
```nginx
server {
listen 80;
listen [::]:80;
server_name git.kalinamall.ru;
return 301 https://$host$request_uri;
}
```
На периметре **80** может занимать другой сервис — включайте только если не конфликтует.