# 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` | Продлить у УЦ, заменить файлы |