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

8.0 KiB
Raw Blame History

Nginx и HTTPS на сервере с Gitea (kalinamall.ru)

В схеме docs/haproxy-kalinamall.cfg и docs/haproxy-kalinamall.md периметровый HAProxy пересылает TCP :443 на узел Gitea (192.168.160.129:443). Контейнер Gitea по умолчанию слушает только HTTP :3000, поэтому на самом сервере нужен TLS-терминатор на :443 — здесь описан nginx перед контейнером.

Цепочка:

Клиент → (опционально 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:

sudo apt-get update
sudo apt-get install -y nginx

2. Каталог для сертификатов и права

Создайте каталог и положите туда fullchain (или сертификат + цепочка в одном PEM) и приватный ключ. Имена файлов могут быть любыми — ниже они должны совпасть с путями в конфиге nginx.

Пример:

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):

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 введёте по запросу):

# Закрытый ключ (права только 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 нужен один файл «сервер + промежуточные»:

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.

Скопируйте пример из репозитория:

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:

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/

Уберите или отключите дефолтный сайт, если он мешает:

sudo rm -f /etc/nginx/sites-enabled/default

Проверка и перезагрузка:

sudo nginx -t
sudo systemctl reload nginx
sudo ss -tlnp | grep ':443'

Должен появиться LISTEN на 0.0.0.0:443 (nginx).

5. Фаервол

При использовании UFW:

sudo ufw allow 443/tcp comment 'nginx Gitea HTTPS'
sudo ufw status verbose

(Порт 2222 для Git по SSH открывайте по вашей политике — на периметре его обычно публикует HAProxy.)

6. Gitea: app.ini

Контейнер по-прежнему отдаёт HTTP на :3000. Снаружи пользователи ходят по HTTPS, поэтому:

[server]
ROOT_URL         = https://git.kalinamall.ru/
PROTOCOL         = http
DOMAIN           = git.kalinamall.ru

Убедитесь, что в [server] не задан лишний порт в URL, если публикуете стандартный 443. После правок:

cd /opt/gitea && sudo docker compose restart gitea

Подробнее про секреты — в README и в gitea/app.ini.example.

7. Проверки

На сервере Gitea:

curl -sS -o /dev/null -w "%{http_code}\n" https://git.kalinamall.ru/api/healthz

Ожидается 200. Локально без nginx (только контейнер):

curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:3000/api/healthz

С другой машины в LAN (DNS на 192.168.160.129 или через HAProxy):

curl -v https://git.kalinamall.ru/api/healthz

8. Связка с периметровым HAProxy

  • DNS git.kalinamall.ru снаружи → публичный IP HAProxy; HAProxy по SNI шлёт TCP на 192.168.160.129:443nginx завершает 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 только для редиректа:

server {
    listen 80;
    listen [::]:80;
    server_name git.kalinamall.ru;
    return 301 https://$host$request_uri;
}

На периметре 80 может занимать другой сервис — включайте только если не конфликтует.