Home » Как создать самоподписанный SSL-сертификат для Nginx на Ubuntu 24
Как создать самоподписанный SSL-сертификат для Nginx на Ubuntu 24

Как создать самоподписанный SSL-сертификат для Nginx на Ubuntu 24

Если вы когда-нибудь настраивали веб-сервер, то наверняка сталкивались с необходимостью обеспечить HTTPS-соединение. Да, Let’s Encrypt круто, но иногда нужно что-то быстрое для тестирования, внутренних проектов или когда внешние CA недоступны. Самоподписанный SSL-сертификат — это именно то, что доктор прописал для таких случаев.

В этой статье мы разберём, как создать самоподписанный SSL-сертификат для Nginx на Ubuntu 24, настроить его правильно и избежать типичных граблей. Вы получите готовое решение, которое можно развернуть за 10 минут, плюс бонусом — несколько полезных трюков для автоматизации.

Зачем нужен самоподписанный сертификат?

Самоподписанный сертификат — это как печать на документе, которую вы сделали сами. Браузеры будут ворчать, что “соединение небезопасно”, но шифрование работает на все 100%. Основные сценарии использования:

  • Разработка и тестирование — не нужно каждый раз получать сертификат для dev-окружения
  • Внутренние сервисы — админки, API, мониторинг внутри корпоративной сети
  • Экстренные ситуации — когда основной сертификат истёк, а новый ещё не готов
  • Изучение SSL/TLS — отличный способ понять, как всё работает под капотом

Как это работает изнутри?

SSL-сертификат содержит открытый ключ и информацию о владельце, подписанную закрытым ключом. В случае с самоподписанным сертификатом, мы сами себе и Certificate Authority (CA). Цепочка доверия начинается и заканчивается на нашем сертификате.

Процесс создания выглядит так:

  • Генерируем пару ключей (открытый/закрытый)
  • Создаём запрос на сертификат (CSR)
  • Подписываем CSR своим же закрытым ключом
  • Получаем готовый сертификат

Подготовка системы

Для начала убедимся, что у нас есть всё необходимое. На Ubuntu 24 OpenSSL уже установлен, но проверим:

sudo apt update
sudo apt install openssl nginx
systemctl status nginx

Если нужен мощный сервер для продакшена, рекомендую взглянуть на VPS или выделенный сервер.

Создание самоподписанного сертификата

Теперь переходим к главному — генерации сертификата. Создадим отдельную папку для наших SSL-материалов:

sudo mkdir -p /etc/nginx/ssl
cd /etc/nginx/ssl

Есть несколько способов создать сертификат. Начнём с самого простого — в одну команду:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/nginx/ssl/server.key \
  -out /etc/nginx/ssl/server.crt \
  -subj "/C=US/ST=State/L=City/O=Organization/CN=yourdomain.com"

Но лучше делать это пошагово, чтобы больше контролировать процесс:

# Генерируем закрытый ключ
sudo openssl genrsa -out server.key 2048

# Создаём запрос на сертификат
sudo openssl req -new -key server.key -out server.csr

# Подписываем сертификат
sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

# Удаляем CSR (он больше не нужен)
sudo rm server.csr

Продвинутый способ с конфигурационным файлом

Для более гибкой настройки создадим конфигурационный файл OpenSSL:

sudo tee /etc/nginx/ssl/server.conf > /dev/null <

Теперь создаём сертификат с использованием этого конфига:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/nginx/ssl/server.key \
  -out /etc/nginx/ssl/server.crt \
  -config /etc/nginx/ssl/server.conf \
  -extensions v3_req

Настройка Nginx

Теперь настроим Nginx для использования нашего сертификата. Создадим конфигурацию виртуального хоста:

sudo tee /etc/nginx/sites-available/ssl-site > /dev/null <

Активируем сайт и перезапускаем Nginx:

sudo ln -s /etc/nginx/sites-available/ssl-site /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Проверка и тестирование

Проверим, что сертификат создан правильно:

# Проверяем информацию о сертификате
sudo openssl x509 -in /etc/nginx/ssl/server.crt -text -noout

# Проверяем совпадение ключа и сертификата
sudo openssl x509 -noout -modulus -in /etc/nginx/ssl/server.crt | openssl md5
sudo openssl rsa -noout -modulus -in /etc/nginx/ssl/server.key | openssl md5

# Тестируем SSL-соединение
openssl s_client -connect localhost:443 -servername yourdomain.com

Для более детального анализа SSL-конфигурации можно использовать:

curl -I https://yourdomain.com
curl -k -v https://yourdomain.com

Автоматизация через скрипт

Создадим скрипт для автоматического создания самоподписанных сертификатов:

sudo tee /usr/local/bin/create-ssl-cert.sh > /dev/null <<'EOF'
#!/bin/bash

DOMAIN=${1:-localhost}
SSL_DIR="/etc/nginx/ssl"
DAYS=${2:-365}

echo "Создаём SSL-сертификат для домена: $DOMAIN"
echo "Срок действия: $DAYS дней"

# Создаём директорию
mkdir -p $SSL_DIR

# Генерируем сертификат
openssl req -x509 -nodes -days $DAYS -newkey rsa:2048 \
    -keyout $SSL_DIR/${DOMAIN}.key \
    -out $SSL_DIR/${DOMAIN}.crt \
    -subj "/C=US/ST=State/L=City/O=Organization/CN=$DOMAIN"

# Устанавливаем права
chmod 600 $SSL_DIR/${DOMAIN}.key
chmod 644 $SSL_DIR/${DOMAIN}.crt

echo "Сертификат создан:"
echo "Ключ: $SSL_DIR/${DOMAIN}.key"
echo "Сертификат: $SSL_DIR/${DOMAIN}.crt"
echo "Срок действия до: $(openssl x509 -enddate -noout -in $SSL_DIR/${DOMAIN}.crt | cut -d= -f2)"
EOF

sudo chmod +x /usr/local/bin/create-ssl-cert.sh

Использование скрипта:

sudo create-ssl-cert.sh mysite.local 730

Сравнение методов создания сертификатов

Метод Скорость Гибкость Безопасность Подходит для
Одна команда OpenSSL Очень быстро Низкая Базовая Быстрое тестирование
Пошаговый процесс Средне Средняя Хорошая Изучение процесса
С конфигурационным файлом Средне Высокая Отличная Продакшен-окружение
Автоматизированный скрипт Очень быстро Настраиваемая Хорошая Массовое развёртывание

Альтернативные инструменты

Кроме OpenSSL, есть и другие инструменты для работы с сертификатами:

  • mkcerthttps://github.com/FiloSottile/mkcert — создаёт локальные CA и сертификаты
  • easy-rsa — пакет для создания собственного Certificate Authority
  • step-cahttps://github.com/smallstep/certificates — современный CA сервер
  • certbot — для Let’s Encrypt, но может работать и с собственными CA

Пример использования mkcert:

# Установка mkcert
sudo snap install mkcert

# Создание локального CA
mkcert -install

# Создание сертификата
mkcert yourdomain.com localhost 127.0.0.1

Типичные ошибки и их решения

Ошибка: “nginx: [emerg] SSL_CTX_use_certificate_chain_file() failed”

Проблема с форматом сертификата. Проверьте, что файл содержит правильные заголовки:

head -1 /etc/nginx/ssl/server.crt
# Должно быть: -----BEGIN CERTIFICATE-----

Ошибка: “SSL_CTX_use_PrivateKey_file() failed”

Несовпадение ключа и сертификата. Проверьте MD5-хеши:

sudo openssl x509 -noout -modulus -in /etc/nginx/ssl/server.crt | openssl md5
sudo openssl rsa -noout -modulus -in /etc/nginx/ssl/server.key | openssl md5

Проблема: “This site can’t provide a secure connection”

Скорее всего, неправильно указан Common Name или отсутствует Subject Alternative Name. Пересоздайте сертификат с правильным CN.

Интеграция с Docker

Для контейнеризированных приложений можно создать Dockerfile с автоматической генерацией сертификатов:

FROM nginx:alpine

# Установка OpenSSL
RUN apk add --no-cache openssl

# Скрипт для создания сертификата
COPY create-ssl.sh /docker-entrypoint.d/10-create-ssl.sh
RUN chmod +x /docker-entrypoint.d/10-create-ssl.sh

# Nginx конфигурация
COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80 443

Мониторинг и обновление сертификатов

Создадим скрипт для проверки срока действия сертификатов:

sudo tee /usr/local/bin/check-ssl-expiry.sh > /dev/null <<'EOF'
#!/bin/bash

SSL_DIR="/etc/nginx/ssl"

for cert in $SSL_DIR/*.crt; do
    if [ -f "$cert" ]; then
        echo "Проверяем: $cert"
        expiry_date=$(openssl x509 -enddate -noout -in "$cert" | cut -d= -f2)
        echo "Действует до: $expiry_date"
        
        # Проверяем, истекает ли через 30 дней
        if openssl x509 -checkend 2592000 -noout -in "$cert"; then
            echo "✓ Сертификат действителен"
        else
            echo "⚠ Сертификат скоро истечёт!"
        fi
        echo "---"
    fi
done
EOF

sudo chmod +x /usr/local/bin/check-ssl-expiry.sh

Добавим в cron автоматическую проверку:

sudo crontab -e
# Добавляем строку:
0 9 * * 1 /usr/local/bin/check-ssl-expiry.sh | mail -s "SSL Certificate Check" admin@yourdomain.com

Интересные факты и нестандартные применения

Wildcard сертификаты

Можно создать wildcard сертификат для всех поддоменов:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/nginx/ssl/wildcard.key \
  -out /etc/nginx/ssl/wildcard.crt \
  -subj "/C=US/ST=State/L=City/O=Organization/CN=*.yourdomain.com"

Использование ECC ключей

Эллиптические кривые обеспечивают лучшую производительность:

sudo openssl ecparam -genkey -name secp384r1 -out /etc/nginx/ssl/server-ecc.key
sudo openssl req -new -x509 -key /etc/nginx/ssl/server-ecc.key -out /etc/nginx/ssl/server-ecc.crt -days 365

Создание собственного CA

Для корпоративных нужд можно создать собственный Certificate Authority:

# Создаём ключ для CA
sudo openssl genrsa -out ca.key 4096

# Создаём корневой сертификат
sudo openssl req -new -x509 -days 3650 -key ca.key -out ca.crt \
  -subj "/C=US/ST=State/L=City/O=Organization/CN=Internal CA"

# Теперь можем подписывать сертификаты этим CA
sudo openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt

Автоматизация для DevOps

Интеграция с Ansible для массового развёртывания:

- name: Create SSL certificate
  shell: |
    openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
      -keyout /etc/nginx/ssl/{{ ansible_hostname }}.key \
      -out /etc/nginx/ssl/{{ ansible_hostname }}.crt \
      -subj "/C=US/ST=State/L=City/O=Organization/CN={{ ansible_hostname }}"
  args:
    creates: /etc/nginx/ssl/{{ ansible_hostname }}.crt

Terraform провайдер для автоматического создания сертификатов:

resource "tls_private_key" "server" {
  algorithm = "RSA"
  rsa_bits  = 2048
}

resource "tls_self_signed_cert" "server" {
  private_key_pem = tls_private_key.server.private_key_pem

  subject {
    common_name  = "yourdomain.com"
    organization = "Your Organization"
  }

  validity_period_hours = 8760 # 1 год

  allowed_uses = [
    "key_encipherment",
    "digital_signature",
    "server_auth",
  ]
}

Статистика и производительность

Сравнение размеров ключей и производительности:

Тип ключа Размер Скорость генерации Скорость рукопожатия Безопасность
RSA 2048 Средний Быстро Средняя Хорошая
RSA 4096 Большой Медленно Медленная Очень хорошая
ECC P-256 Малый Очень быстро Быстрая Отличная
ECC P-384 Малый Быстро Быстрая Превосходная

Тестирование производительности SSL:

# Тест скорости SSL-рукопожатий
openssl s_time -connect localhost:443 -www / -new -time 30

# Бенчмарк алгоритмов
openssl speed rsa2048 rsa4096 ecdsap256 ecdsap384

Заключение и рекомендации

Самоподписанные SSL-сертификаты — это мощный инструмент для разработки, тестирования и внутренних проектов. Главное помнить:

  • Не используйте в продакшене для публичных сайтов — Let’s Encrypt бесплатный и автоматический
  • Всегда указывайте Subject Alternative Names для совместимости с современными браузерами
  • Используйте современные алгоритмы — RSA 2048+ или ECC P-256+
  • Мониторьте сроки действия и автоматизируйте обновление
  • Защищайте закрытые ключи — права 600 и хранение в безопасном месте

Для быстрого старта используйте простой однострочный метод, для серьёзных проектов — конфигурационные файлы с SAN. Автоматизируйте процесс через скрипты и интегрируйте в CI/CD pipeline.

И помните: самоподписанный сертификат обеспечивает такое же шифрование, как и купленный за деньги. Единственная разница — в доверии браузера. Для внутренних задач этого более чем достаточно.


В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.

Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.

Leave a reply

Your email address will not be published. Required fields are marked