Home » Создание самоподписанного SSL-сертификата для Nginx на Ubuntu 24
Создание самоподписанного SSL-сертификата для Nginx на Ubuntu 24

Создание самоподписанного SSL-сертификата для Nginx на Ubuntu 24

Когда разворачиваешь веб-сервер на VPS или выделенном сервере, рано или поздно встает вопрос о SSL-сертификате. Да, Let’s Encrypt — это круто, но что если нужен быстрый деплой в dev-среде? Или у тебя intranet-приложение? Самоподписанный сертификат — это твой друг в таких случаях.

Сегодня разберем, как создать самоподписанный SSL-сертификат для Nginx на Ubuntu 24. Это не для продакшена (браузеры будут ругаться), но для разработки и тестирования — самое то. Плюс поймешь, как вообще работает SSL и почему браузеры так параноят насчет сертификатов.

Зачем это нужно и как работает

SSL-сертификат — это цифровая подпись, которая подтверждает, что сервер действительно тот, за кого себя выдает. Обычно его выдает доверенный центр сертификации (CA), но мы можем создать свой собственный.

Самоподписанный сертификат работает так же, как и обычный, но браузеры не доверяют ему по умолчанию. Поэтому пользователи видят предупреждение о безопасности. Но трафик все равно шифруется — это главное.

Основные сценарии использования:

  • Разработка и тестирование веб-приложений
  • Внутренние корпоративные сервисы
  • Временное решение до получения “настоящего” сертификата
  • Обучение и эксперименты с SSL

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

Убедимся, что у нас есть все необходимое. OpenSSL должен быть установлен по умолчанию, но проверим:

sudo apt update
sudo apt install openssl nginx -y
nginx -v
openssl version

Если Nginx еще не установлен, команда выше его поставит. Создадим директорию для наших сертификатов:

sudo mkdir -p /etc/nginx/ssl
sudo chmod 700 /etc/nginx/ssl

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

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

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/nginx/ssl/nginx-selfsigned.key \
-out /etc/nginx/ssl/nginx-selfsigned.crt

Разберем параметры:

  • -x509 — создаем самоподписанный сертификат
  • -nodes — не шифруем приватный ключ паролем
  • -days 365 — сертификат действует год
  • -newkey rsa:2048 — создаем новый RSA-ключ на 2048 бит

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

Country Name (2 letter code) [AU]: RU
State or Province Name (full name) [Some-State]: Moscow
Locality Name (eg, city) []: Moscow
Organization Name (eg, company) [Internet Widgits Pty Ltd]: MyCompany
Organizational Unit Name (eg, section) []: IT Department
Common Name (e.g. server FQDN or YOUR name) []: myserver.local
Email Address []: admin@mycompany.com

Важно! Common Name должен совпадать с доменом, по которому будешь обращаться к серверу. Если это локальный сервер, можешь указать IP-адрес.

Создадим также сильные параметры Диффи-Хеллмана для дополнительной безопасности:

sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

Эта команда может выполняться несколько минут — это нормально.

Настройка Nginx

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

sudo nano /etc/nginx/sites-available/ssl-example

Вставляем следующую конфигурацию:

server {
    listen 443 ssl http2;
    server_name myserver.local;

    ssl_certificate /etc/nginx/ssl/nginx-selfsigned.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx-selfsigned.key;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    # Настройки SSL
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_timeout 10m;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;

    # Заголовки безопасности
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";

    root /var/www/html;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}

# Редирект с HTTP на HTTPS
server {
    listen 80;
    server_name myserver.local;
    return 301 https://$server_name$request_uri;
}

Активируем сайт и проверим конфигурацию:

sudo ln -s /etc/nginx/sites-available/ssl-example /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Проверка работы

Создадим простую HTML-страницу для тестирования:

sudo nano /var/www/html/index.html
<!DOCTYPE html>
<html>
<head>
    <title>SSL Test Page</title>
</head>
<body>
    <h1>SSL работает!</h1>
    <p>Если ты видишь эту страницу через HTTPS, то всё настроено правильно.</p>
</body>
</html>

Теперь проверим работу с помощью curl:

# Проверка без игнорирования ошибок сертификата (должна показать ошибку)
curl https://myserver.local

# Проверка с игнорированием ошибок самоподписанного сертификата
curl -k https://myserver.local

Если все настроено правильно, вторая команда покажет содержимое нашей HTML-страницы.

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

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

#!/bin/bash

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

# Создаем директорию если не существует
mkdir -p $CERT_DIR

# Создаем сертификат
openssl req -x509 -nodes -days $DAYS -newkey rsa:2048 \
-keyout $CERT_DIR/$DOMAIN.key \
-out $CERT_DIR/$DOMAIN.crt \
-subj "/C=RU/ST=Moscow/L=Moscow/O=MyCompany/OU=IT/CN=$DOMAIN"

# Создаем DH параметры
openssl dhparam -out $CERT_DIR/dhparam.pem 2048

echo "Сертификат для $DOMAIN создан в $CERT_DIR"

Сохраним скрипт как create-ssl-cert.sh и сделаем исполняемым:

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

Сравнение с другими решениями

Решение Плюсы Минусы Подходит для
Самоподписанный сертификат Быстро, бесплатно, полный контроль Предупреждения браузера Dev/test, внутренние сервисы
Let’s Encrypt Бесплатно, доверенный Нужен публичный домен Продакшен, публичные сайты
Коммерческие CA Максимальное доверие Платно, бюрократия Корпоративные проекты
Cloudflare SSL Простота настройки Зависимость от сервиса Веб-сайты через CDN

Продвинутые настройки

Для более серьезного использования можно создать собственный центр сертификации (CA). Сначала создаем корневой сертификат:

# Создаем приватный ключ для CA
openssl genrsa -out myCA.key 2048

# Создаем корневой сертификат
openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.pem \
-subj "/C=RU/ST=Moscow/L=Moscow/O=MyCompany/CN=MyCompany Root CA"

Теперь создаем сертификат, подписанный нашим CA:

# Создаем приватный ключ для сервера
openssl genrsa -out server.key 2048

# Создаем запрос на сертификат
openssl req -new -key server.key -out server.csr \
-subj "/C=RU/ST=Moscow/L=Moscow/O=MyCompany/CN=myserver.local"

# Подписываем сертификат нашим CA
openssl x509 -req -in server.csr -CA myCA.pem -CAkey myCA.key \
-CAcreateserial -out server.crt -days 365 -sha256

Теперь, если добавить myCA.pem в доверенные корневые сертификаты системы, браузеры не будут показывать предупреждения.

Мониторинг и обслуживание

Полезно создать скрипт для проверки срока действия сертификатов:

#!/bin/bash

check_cert_expiry() {
    local cert_file=$1
    local expires=$(openssl x509 -enddate -noout -in "$cert_file" | cut -d= -f2)
    local expires_epoch=$(date -d "$expires" +%s)
    local current_epoch=$(date +%s)
    local days_until_expiry=$(( ($expires_epoch - $current_epoch) / 86400 ))
    
    echo "Сертификат $cert_file истекает через $days_until_expiry дней"
    
    if [ $days_until_expiry -lt 30 ]; then
        echo "ВНИМАНИЕ: Сертификат скоро истечет!"
    fi
}

check_cert_expiry "/etc/nginx/ssl/nginx-selfsigned.crt"

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

Если используешь Docker, можно создать контейнер с предустановленными сертификатами:

FROM nginx:alpine

RUN apk add --no-cache openssl

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

COPY nginx-ssl.conf /etc/nginx/conf.d/default.conf

EXPOSE 80 443

CMD ["/usr/local/bin/create-ssl-cert.sh", "localhost"] && nginx -g 'daemon off;'

Troubleshooting

Частые проблемы и их решения:

  • Permission denied — проверь права на файлы сертификатов: sudo chmod 600 /etc/nginx/ssl/*
  • Nginx не стартует — проверь синтаксис конфигурации: sudo nginx -t
  • Сертификат не найден — убедись, что пути в конфигурации правильные
  • Слабые шифры — используй современные SSL-настройки из примера выше

Для отладки SSL-соединений используй:

openssl s_client -connect myserver.local:443 -servername myserver.local

Заключение

Самоподписанные SSL-сертификаты — это отличный инструмент для разработки и тестирования. Они дают понимание того, как работает SSL/TLS, и позволяют быстро настроить шифрование без внешних зависимостей.

Главное помнить:

  • Используй только для dev/test или внутренних сервисов
  • Следи за сроками действия сертификатов
  • Не забывай про безопасные настройки SSL
  • Для продакшена переходи на Let’s Encrypt или коммерческие сертификаты

Дополнительная информация и документация:

Теперь у тебя есть рабочий HTTPS-сервер с самоподписанным сертификатом. Время экспериментировать!


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

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

Leave a reply

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