From 0c5d2537db7d4878c210c534e620075adfaebb71 Mon Sep 17 00:00:00 2001 From: PTah Date: Tue, 26 May 2026 21:15:38 +1000 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=BF=D0=BE=D0=B4=D1=80=D0=BE=D0=B1?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4?= =?UTF-8?q?=D1=81=D1=82=D0=B2=D0=BE=20=D0=BF=D0=BE=20=D0=BA=D0=BE=D0=BF?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8E=20wildcard=20T?= =?UTF-8?q?LS=20=D0=BD=D0=B0=20=D1=81=D0=B5=D1=80=D0=B2=D0=B5=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + deploy/nginx/sac.conf.tls.example | 2 +- docs/INDEX.md | 1 + docs/deployment.md | 2 +- docs/install-ubuntu-24.04-native.md | 44 +++-- docs/ssl-certificate.md | 240 ++++++++++++++++++++++++++++ 6 files changed, 264 insertions(+), 26 deletions(-) create mode 100644 docs/ssl-certificate.md diff --git a/README.md b/README.md index fa0d268..2337738 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ | [docs/roadmap.md](docs/roadmap.md) | Дорожная карта продуктовых фаз | | [docs/install-ubuntu-24.04-native.md](docs/install-ubuntu-24.04-native.md) | **Ubuntu 24.04 — native (основной)** | | [docs/install-ubuntu-24.04-docker.md](docs/install-ubuntu-24.04-docker.md) | Ubuntu 24.04 — Docker (альтернатива) | +| [docs/ssl-certificate.md](docs/ssl-certificate.md) | Wildcard TLS: куда копировать сертификат | | [docs/deployment.md](docs/deployment.md) | Развёртывание и эксплуатация | | [docs/workspace-three-repos.md](docs/workspace-three-repos.md) | Multi-root workspace для трёх репо | diff --git a/deploy/nginx/sac.conf.tls.example b/deploy/nginx/sac.conf.tls.example index 5e588b6..c6c5f45 100644 --- a/deploy/nginx/sac.conf.tls.example +++ b/deploy/nginx/sac.conf.tls.example @@ -3,7 +3,7 @@ # Покрывает sac.kalinamall.ru при CN/SAN *.kalinamall.ru или sac.kalinamall.ru # # Перед включением: -# 1) Положите fullchain и ключ (см. docs/install-ubuntu-24.04-native.md §9) +# 1) Положите fullchain и ключ в /etc/ssl/sac/ (см. docs/ssl-certificate.md) # 2) Подставьте пути в ssl_certificate / ssl_certificate_key ниже # 3) sudo nginx -t && sudo systemctl reload nginx diff --git a/docs/INDEX.md b/docs/INDEX.md index 4338845..7a3fc9f 100644 --- a/docs/INDEX.md +++ b/docs/INDEX.md @@ -12,6 +12,7 @@ | [install-ubuntu-24.04-native.md](install-ubuntu-24.04-native.md) | **Подготовка сервера (native)** | | [install-ubuntu-24.04-docker.md](install-ubuntu-24.04-docker.md) | Подготовка сервера (Docker, альтернатива) | | [install-ubuntu-24.04.md](install-ubuntu-24.04.md) | Указатель | +| [ssl-certificate.md](ssl-certificate.md) | Wildcard TLS: формат, scp, пути `/etc/ssl/sac/` | | [deployment.md](deployment.md) | Эксплуатация, backup, TLS | | [workspace-three-repos.md](workspace-three-repos.md) | Cursor multi-root | diff --git a/docs/deployment.md b/docs/deployment.md index f74450c..c225e65 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -74,7 +74,7 @@ curl -sS https://sac.kalinamall.ru/health ## 5. TLS -- **Production (KalinaMall):** корпоративный **wildcard** (VeriSign / DigiCert) — см. [install-ubuntu-24.04-native.md](install-ubuntu-24.04-native.md) §9, шаблон `deploy/nginx/sac.conf.tls.example` +- **Production (KalinaMall):** корпоративный **wildcard** (VeriSign) — [ssl-certificate.md](ssl-certificate.md) (копирование, форматы, `/etc/ssl/sac/`), [install-ubuntu-24.04-native.md](install-ubuntu-24.04-native.md) §9, `deploy/nginx/sac.conf.tls.example` - Альтернатива: **certbot** + Let's Encrypt (`deploy/nginx/sac.conf.example`) --- diff --git a/docs/install-ubuntu-24.04-native.md b/docs/install-ubuntu-24.04-native.md index 6e1b70d..0d72b98 100644 --- a/docs/install-ubuntu-24.04-native.md +++ b/docs/install-ubuntu-24.04-native.md @@ -192,44 +192,40 @@ journalctl -u sac-api -f ## 9. nginx и TLS -Для KalinaMall: **корпоративный wildcard** (VeriSign / DigiCert и т.п.), не Let's Encrypt. -Имя `sac.kalinamall.ru` должно попадать под сертификат (`*.kalinamall.ru` или явный SAN). +Для KalinaMall: **корпоративный wildcard VeriSign** (или DigiCert), не Let's Encrypt. +Хост `sac.kalinamall.ru` должен попадать под `*.kalinamall.ru`. -### 9.1. Установка файлов сертификата +**Подробно:** форматы, scp с Windows/Linux, `.pfx` → PEM, права — **[ssl-certificate.md](ssl-certificate.md)**. -Обычно от УЦ выдают: +### 9.1. Кратко: куда положить файлы -| Файл | Назначение | -|------|------------| -| Сертификат сервера | `sac.kalinamall.ru` или wildcard | -| Промежуточные CA | chain / intermediate | -| Закрытый ключ | `.key`, хранить только на сервере | +nginx ожидает **два PEM-файла**: -Соберите **fullchain** (сервер + промежуточные, в правильном порядке — как указано в инструкции УЦ): +| Файл на сервере | Содержимое | +|-----------------|------------| +| `/etc/ssl/sac/fullchain.pem` | Wildcard-сертификат + промежуточные CA | +| `/etc/ssl/sac/privkey.pem` | Закрытый ключ | ```bash -sudo mkdir -p /etc/ssl/sac -sudo chmod 750 /etc/ssl/sac +sudo mkdir -p /etc/ssl/sac && sudo chmod 750 /etc/ssl/sac +``` -# Пример: скопировать с рабочей станции (scp) или собрать на сервере -# sudo nano /etc/ssl/sac/fullchain.pem # PEM: сервер, затем intermediate(s) -# sudo nano /etc/ssl/sac/privkey.pem # закрытый ключ +Скопировать с рабочего ПК (пример): +```bash +# с вашего компьютера: +scp fullchain.pem privkey.pem papatramp@:/tmp/ + +# на сервере: +sudo mv /tmp/fullchain.pem /tmp/privkey.pem /etc/ssl/sac/ sudo chmod 644 /etc/ssl/sac/fullchain.pem sudo chmod 640 /etc/ssl/sac/privkey.pem sudo chown root:root /etc/ssl/sac/fullchain.pem sudo chown root:ssl-cert /etc/ssl/sac/privkey.pem +sudo -u www-data test -r /etc/ssl/sac/privkey.pem && echo OK ``` -Проверка PEM: - -```bash -sudo openssl x509 -in /etc/ssl/sac/fullchain.pem -noout -subject -dates -sudo openssl rsa -in /etc/ssl/sac/privkey.pem -check -noout 2>/dev/null || \ - sudo openssl pkey -in /etc/ssl/sac/privkey.pem -check -noout -``` - -Убедитесь, что в сертификате есть **`*.kalinamall.ru`** или **`sac.kalinamall.ru`**. +Если пришёл только **`.pfx`** — см. [ssl-certificate.md §4.3](ssl-certificate.md#43-распаковка-pfx--p12-на-сервере). ### 9.2. Конфиг nginx (HTTPS) diff --git a/docs/ssl-certificate.md b/docs/ssl-certificate.md new file mode 100644 index 0000000..5757d14 --- /dev/null +++ b/docs/ssl-certificate.md @@ -0,0 +1,240 @@ +# TLS-сертификат для SAC (wildcard VeriSign / DigiCert) + +Куда положить файлы, в каком формате, как скопировать на сервер `sac.kalinamall.ru`. + +Связано: [install-ubuntu-24.04-native.md](install-ubuntu-24.04-native.md) §9, шаблон `deploy/nginx/sac.conf.tls.example`. + +--- + +## 1. Что должно получиться на сервере + +nginx читает **два PEM-файла** (текст, начинается с `-----BEGIN ...-----`): + +| Путь на сервере | Содержимое | Кто читает | +|-----------------|------------|------------| +| `/etc/ssl/sac/fullchain.pem` | Сертификат сайта/wildcard **+** промежуточные CA (без корневого — обычно не нужен) | nginx | +| `/etc/ssl/sac/privkey.pem` | Закрытый ключ (RSA или EC) | nginx | + +Имена файлов можно другие, если пути совпадают с `ssl_certificate` / `ssl_certificate_key` в `/etc/nginx/sites-available/sac`. + +**Покрытие имени:** в сертификате должен быть CN или SAN вида `*.kalinamall.ru` (wildcard) или `sac.kalinamall.ru`. + +--- + +## 2. Что вам могут выдать (входные форматы) + +| От УЦ / админа | Расширения | Что делать | +|----------------|------------|------------| +| Готовый PEM | `.pem`, `.crt` + `.key` | Собрать fullchain, скопировать на сервер | +| PKCS#12 | `.pfx`, `.p12` | Распаковать в PEM (см. §4) | +| Отдельные файлы | `certificate.crt`, `ca-bundle.crt`, `private.key` | Склеить fullchain (см. §5) | +| Windows (MMC) | экспорт `.pfx` | Распаковать на ПК или сервере (§4) | + +nginx **не** понимает напрямую: `.pfx`, `.p12`, `.der` без конвертации. + +--- + +## 3. Каталог и права на сервере + +Выполнить **один раз** на SAC-сервере: + +```bash +sudo mkdir -p /etc/ssl/sac +sudo chmod 750 /etc/ssl/sac +``` + +После копирования файлов: + +```bash +sudo chmod 644 /etc/ssl/sac/fullchain.pem +sudo chmod 640 /etc/ssl/sac/privkey.pem +sudo chown root:root /etc/ssl/sac/fullchain.pem +sudo chown root:ssl-cert /etc/ssl/sac/privkey.pem +``` + +Группа `ssl-cert` на Ubuntu нужна, чтобы **nginx** (пользователь `www-data`) мог читать ключ. + +Проверка, что nginx видит файлы: + +```bash +sudo -u www-data test -r /etc/ssl/sac/fullchain.pem && echo "fullchain OK" +sudo -u www-data test -r /etc/ssl/sac/privkey.pem && echo "key OK" +``` + +--- + +## 4. Копирование на сервер + +Подставьте IP или hostname SAC-сервера вместо `SAC_SERVER`. + +### 4.1. С Linux / macOS (scp) + +Если уже есть `fullchain.pem` и `privkey.pem` на ПК: + +```bash +scp fullchain.pem privkey.pem papatramp@SAC_SERVER:/tmp/ +``` + +На сервере: + +```bash +sudo mv /tmp/fullchain.pem /tmp/privkey.pem /etc/ssl/sac/ +sudo chmod 644 /etc/ssl/sac/fullchain.pem +sudo chmod 640 /etc/ssl/sac/privkey.pem +sudo chown root:root /etc/ssl/sac/fullchain.pem +sudo chown root:ssl-cert /etc/ssl/sac/privkey.pem +sudo rm -f /tmp/fullchain.pem /tmp/privkey.pem +``` + +### 4.2. С Windows (PowerShell / pscp) + +Файлы, например, в `D:\Certs\kalinamall\`: + +```powershell +scp D:\Certs\kalinamall\fullchain.pem papatramp@SAC_SERVER:/tmp/ +scp D:\Certs\kalinamall\privkey.pem papatramp@SAC_SERVER:/tmp/ +``` + +Дальше на сервере — те же `sudo mv` и `chown`, что в §4.1. + +Если есть только **`wildcard.pfx`**: + +```powershell +scp D:\Certs\kalinamall\wildcard.pfx papatramp@SAC_SERVER:/tmp/ +``` + +Распаковка на **сервере** (§4.3). + +### 4.3. Распаковка `.pfx` / `.p12` на сервере + +```bash +# установить openssl, если нет +sudo apt install -y openssl + +cd /tmp +# замените имя файла и пароль от PFX +openssl pkcs12 -in wildcard.pfx -nocerts -nodes -out privkey.pem +openssl pkcs12 -in wildcard.pfx -clcerts -nokeys -out server.crt +openssl pkcs12 -in wildcard.pfx -cacerts -nokeys -out ca-chain.crt + +# fullchain = сервер + промежуточные (порядок важен) +cat server.crt ca-chain.crt | sudo tee /etc/ssl/sac/fullchain.pem > /dev/null +sudo mv privkey.pem /etc/ssl/sac/privkey.pem +sudo chmod 644 /etc/ssl/sac/fullchain.pem +sudo chmod 640 /etc/ssl/sac/privkey.pem +sudo chown root:root /etc/ssl/sac/fullchain.pem +sudo chown root:ssl-cert /etc/ssl/sac/privkey.pem + +# удалить временные файлы с /tmp +shred -u server.crt ca-chain.crt 2>/dev/null; rm -f wildcard.pfx +``` + +Пароль PFX вводится интерактивно. **Не** коммитьте PFX и ключ в git. + +--- + +## 5. Сборка fullchain из отдельных `.crt` + +Типичный набор от VeriSign / DigiCert: + +- `star_kalinamall_ru.crt` — ваш wildcard +- `DigiCertCA.crt` / `intermediate.crt` — промежуточный +- (иногда) `TrustedRoot.crt` — корневой **не** добавляйте в fullchain для nginx + +```bash +# на ПК или на сервере, в каталоге с исходниками: +cat star_kalinamall_ru.crt intermediate.crt > fullchain.pem +# ключ переименовать: +cp private.key privkey.pem +``` + +Проверка порядка (первая строка сертификата — ваш сайт): + +```bash +openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout | grep subject= +``` + +Скопировать `fullchain.pem` и `privkey.pem` на сервер (§4). + +--- + +## 6. Проверка сертификата + +На сервере: + +```bash +# кому выдан, срок действия +sudo openssl x509 -in /etc/ssl/sac/fullchain.pem -noout -subject -issuer -dates + +# wildcard / SAN +sudo openssl x509 -in /etc/ssl/sac/fullchain.pem -noout -ext subjectAltName + +# ключ соответствует сертификату +CERT_MD5=$(sudo openssl x509 -in /etc/ssl/sac/fullchain.pem -noout -modulus | openssl md5) +KEY_MD5=$(sudo openssl rsa -in /etc/ssl/sac/privkey.pem -noout -modulus 2>/dev/null | openssl md5) +# для EC-ключа: +# KEY_MD5=$(sudo openssl pkey -in /etc/ssl/sac/privkey.pem -noout -modulus | openssl md5) +echo "cert $CERT_MD5" +echo "key $KEY_MD5" +# хеши должны совпадать +``` + +--- + +## 7. Подключение в nginx + +```bash +sudo cp /opt/security-alert-center/deploy/nginx/sac.conf.tls.example \ + /etc/nginx/sites-available/sac +``` + +В файле должны быть (по умолчанию в шаблоне): + +```nginx +ssl_certificate /etc/ssl/sac/fullchain.pem; +ssl_certificate_key /etc/ssl/sac/privkey.pem; +``` + +```bash +sudo ln -sf /etc/nginx/sites-available/sac /etc/nginx/sites-enabled/sac +sudo nginx -t +sudo systemctl reload nginx +curl -sS https://sac.kalinamall.ru/health | jq . +``` + +В приложении SAC (`/opt/security-alert-center/config/sac-api.env`): + +```ini +SAC_PUBLIC_URL=https://sac.kalinamall.ru +``` + +--- + +## 8. Обновление сертификата (продление) + +1. Получить новые файлы от УЦ. +2. Заменить `/etc/ssl/sac/fullchain.pem` и при необходимости `privkey.pem`. +3. `sudo nginx -t && sudo systemctl reload nginx`. +4. Проверить срок: `openssl x509 -in /etc/ssl/sac/fullchain.pem -noout -dates`. + +Перезапуск `sac-api` **не** обязателен — TLS терминируется на nginx. + +--- + +## 9. Безопасность + +- Закрытый ключ только на сервере SAC, права `640`, группа `ssl-cert`. +- Не хранить PFX/ключ в репозитории, почте, мессенджерах. +- После распаковки PFX удалить `/tmp/*.pfx` и промежуточные копии. + +--- + +## 10. Устранение неполадок + +| Симптом | Решение | +|---------|---------| +| `nginx: PEM_read_bio_X509_AUX() failed` | Неверный PEM, проверьте `fullchain.pem` текстом, нет ли `.der` без конвертации | +| `key values mismatch` | Ключ не от этой пары сертификатов | +| `permission denied` на key | `chown root:ssl-cert`, `chmod 640`, `www-data` в группе `ssl-cert` | +| Браузер/агент не доверяет | Неполная цепочка — добавьте intermediate в fullchain | +| `certificate has expired` | Продлить у УЦ, заменить файлы |