diff --git a/README.md b/README.md index 35f014b..f4fcc19 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ - `haproxy/haproxy.cfg` — полный конфиг HAProxy (с Gitea, Zabbix, Synology, RDP, SMTP). - `docs/haproxy-kalinamall.cfg` — периметровый HAProxy kalinamall.ru (TCP+SNI `:443`, Exchange/RDS/ERP/SMTP) **и** Gitea `git.kalinamall.ru` → `192.168.160.129:443`, SSH `:2222`. - `docs/haproxy-kalinamall.md` — описание схемы kalinamall.ru, `git.kalinamall.ru`, DNS и `app.ini`. +- `docs/gitea-nginx-https.md` — nginx на сервере Gitea: TLS на **443**, прокси на контейнер **:3000** (для связки с периметровым HAProxy). +- `nginx/` — примеры `git.kalinamall.ru` и map для WebSocket. - `gitea/docker-compose.yml` — запуск Gitea в Docker. - `gitea/app.ini.example` — шаблон конфигурации Gitea. - `scripts/migrate-github-to-gitea.sh` — массовая миграция репозиториев GitHub в Gitea. @@ -41,7 +43,7 @@ - Внутренний доступ к Gitea: `192.168.128.100:3000`. - Git SSH: внешний `:2222` на HAProxy -> внутренний `192.168.128.100:2222`. -Отдельный контур **kalinamall.ru**: TLS на бэкендах (GlobalSign wildcard); HAProxy только маршрутизирует по SNI на `:443`. Подробнее — [`docs/haproxy-kalinamall.md`](docs/haproxy-kalinamall.md), конфиг — [`docs/haproxy-kalinamall.cfg`](docs/haproxy-kalinamall.cfg). На Gitea в `app.ini`: `ROOT_URL=https://git.kalinamall.ru/` и настройки SSH-домена/порта под внешний `:2222`. +Отдельный контур **kalinamall.ru**: TLS на бэкендах (GlobalSign wildcard); HAProxy только маршрутизирует по SNI на `:443`. Подробнее — [`docs/haproxy-kalinamall.md`](docs/haproxy-kalinamall.md), конфиг — [`docs/haproxy-kalinamall.cfg`](docs/haproxy-kalinamall.cfg). На узле Gitea поднимите **HTTPS на 443** (например **nginx** по [`docs/gitea-nginx-https.md`](docs/gitea-nginx-https.md)). В `app.ini`: `ROOT_URL=https://git.kalinamall.ru/` и настройки SSH-домена/порта под внешний `:2222`. ## 1) Установка Gitea diff --git a/docs/gitea-nginx-https.md b/docs/gitea-nginx-https.md new file mode 100644 index 0000000..6ebff6e --- /dev/null +++ b/docs/gitea-nginx-https.md @@ -0,0 +1,150 @@ +# 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/* +``` + +## 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** может занимать другой сервис — включайте только если не конфликтует. diff --git a/docs/haproxy-kalinamall.md b/docs/haproxy-kalinamall.md index b1001d0..2902e6b 100644 --- a/docs/haproxy-kalinamall.md +++ b/docs/haproxy-kalinamall.md @@ -40,7 +40,7 @@ - **`ROOT_URL=https://git.kalinamall.ru/`** - В настройках SSH для пользователей укажите домен **`git.kalinamall.ru`** и внешний порт **`2222`** (тот, что опубликован на HAProxy). -Убедитесь, что Gitea реально отдаёт **HTTPS на 443** на `192.168.160.129`, если в конфиге HAProxy указан именно этот порт. Если контейнер слушает только HTTP `:3000`, нужен отдельный TLS-фронт на этом хосте или изменение схемы публикации (см. комментарии в [`haproxy-kalinamall.cfg`](haproxy-kalinamall.cfg)). +Убедитесь, что на **`192.168.160.129`** на порту **443** что-то принимает TLS (периметровый HAProxy шлёт сюда TCP **443**). Контейнер Gitea сам по себе слушает только **HTTP :3000** — практичный вариант: **nginx** на том же сервере с wildcard-сертификатом. Пошаговая установка: **[`docs/gitea-nginx-https.md`](gitea-nginx-https.md)** и примеры в каталоге [`nginx/`](../nginx/). После правок перезапустите Gitea. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index ff4f691..28e5af4 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -253,3 +253,9 @@ docker compose version ```bash dpkg -l | grep -E 'docker.io|docker-ce|containerd|compose' ``` + +## 13) `Connection refused` на `https://git.…:443` (kalinamall / Gitea) + +Gitea в Docker обычно слушает только **HTTP :3000**; **:443** пустой, пока не настроен TLS-прокси на хосте. При схеме из [`docs/haproxy-kalinamall.cfg`](haproxy-kalinamall.cfg) на узле Gitea должен слушать кто‑то **HTTPS на 443** (чаще **nginx** с вашим wildcard). + +Пошаговая установка: **[`docs/gitea-nginx-https.md`](gitea-nginx-https.md)**. diff --git a/nginx/conf.d-map-websocket.conf.example b/nginx/conf.d-map-websocket.conf.example new file mode 100644 index 0000000..7463197 --- /dev/null +++ b/nginx/conf.d-map-websocket.conf.example @@ -0,0 +1,9 @@ +# Подключите один раз в контексте http {} (Ubuntu: скопируйте в /etc/nginx/conf.d/zz-map-websocket.conf +# или вставьте содержимое в /etc/nginx/nginx.conf внутрь блока http { ... }). +# +# Нужно для корректных WebSocket (веб-интерфейс Gitea) при proxy_set_header Connection $connection_upgrade; + +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} diff --git a/nginx/git.kalinamall.ru.conf.example b/nginx/git.kalinamall.ru.conf.example new file mode 100644 index 0000000..8bfdeb0 --- /dev/null +++ b/nginx/git.kalinamall.ru.conf.example @@ -0,0 +1,36 @@ +# Пример виртуального хоста: TLS на nginx, Gitea на HTTP 127.0.0.1:3000 (Docker). +# Установка: см. docs/gitea-nginx-https.md +# +# Разместите (после правки путей к сертификатам): +# sudo cp git.kalinamall.ru.conf.example /etc/nginx/sites-available/git.kalinamall.ru +# sudo ln -sf /etc/nginx/sites-available/git.kalinamall.ru /etc/nginx/sites-enabled/ +# sudo nginx -t && sudo systemctl reload nginx + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name git.kalinamall.ru; + + # Замените на реальные пути к fullchain и приватному ключу (wildcard GlobalSign *.kalinamall.ru). + ssl_certificate /etc/nginx/ssl/kalinamall/git.kalinamall.ru-fullchain.pem; + ssl_certificate_key /etc/nginx/ssl/kalinamall/git.kalinamall.ru.key; + + ssl_protocols TLSv1.2 TLSv1.3; + + # Большие push по HTTPS + client_max_body_size 0; + + location / { + proxy_pass http://127.0.0.1:3000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_redirect off; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } +}