Введение
В современном интернете безопасность передачи данных — обязательное требование. SSL/TLS-сертификаты обеспечивают шифрование соединения между клиентом и сервером, защищая данные от перехвата.
Docker упрощает развертывание приложений, но правильная настройка SSL внутри контейнеров требует понимания:
- Как генерировать и подключать сертификаты?
- Как автоматизировать обновление Let’s Encrypt в контейнерах?
- Какие есть альтернативы (например, Traefik)?
Это руководство охватывает все этапы — от локальной разработки с самоподписанными сертификатами до продакшена с автоматическим HTTPS.
Docker оказался самой сложной средой для автоматизации сертификации. В то время как сервисы на базе Linux могут использовать таймеры cron или systemd и такие клиенты, как certbot, для продления сертификатов, а в Kubernetes есть такие пакеты, как cert-manager, для управления сертификатами, в контейнерах Docker инструментов для этого практически нет. Не существует универсального решения для управления сертификатами TLS в Docker.
Подробнее о SSL-сертификатах
Что такое SSL-сертификаты?
SSL (Secure Sockets Layer) и его преемник TLS (Transport Layer Security) — это криптографические протоколы, обеспечивающие:
- Преобразует информацию в нечитаемый формат для посторонних.
- Пример: без SSL пароли передаются в открытом виде.
- Подтверждает, что пользователь подключен к настоящему серверу, а не к мошеннической копии.
- Проверяется центром сертификации (CA).
- Гарантирует, что данные не были изменены при передаче.
Зачем использовать SSL в Docker?
В Docker, как и в любых других сетевых приложениях, SSL помогает предотвратить перехват и искажение данных при их передаче между контейнерами и конечными пользователями или между контейнерами и внешними сервисами. Это существенно повышает уровень безопасности и доверия к приложению.
Настройка SSL-сертификатов в Docker
Локальная разработка: самоподписанные сертификаты
Генерация сертификата (OpenSSL)
mkdir -p ./certs && cd ./certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout localhost.key -out localhost.crt \
-subj "/CN=localhost" -addext "subjectAltName=DNS:localhost"
Важно: Добавляем subjectAltName
, иначе Chrome/Firefox будут ругаться.
Настройка Nginx в Docker
docker-compose.yml
:
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "443:443"
volumes:
- ./certs:/etc/ssl/certs
- ./nginx.conf:/etc/nginx/conf.d/default.conf
nginx.conf
:
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/ssl/certs/localhost.crt;
ssl_certificate_key /etc/ssl/certs/localhost.key;
location / {
return 200 "HTTPS works!";
add_header Content-Type text/plain;
}
}
Добавляем сертификат в доверенные (для браузера)
- Linux: sudo cp ./certs/localhost.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates
- Windows:
Импортируйте.crt
файл в «Доверенные корневые центры сертификации» черезcertmgr.msc
.
Продакшен: Let’s Encrypt + Certbot
Docker-compose с автоматическим обновлением
docker-compose.prod.yml
:
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
certbot:
image: certbot/certbot
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
nginx.conf
(для Certbot):
server {
listen 80;
server_name your-domain.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
Первоначальный запуск Certbot
docker-compose -f docker-compose.prod.yml up -d nginx
docker-compose -f docker-compose.prod.yml run --rm certbot certonly --webroot --webroot-path /var/www/certbot --email your@email.com --agree-tos --no-eff-email -d your-domain.com
Финальная конфигурация Nginx
Обновите nginx.conf
для HTTPS:
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
location / {
proxy_pass http://app:3000; <em># Пример проксирования</em>
}
}
Альтернатива: Traefik v2 (автоматический SSL)
docker-compose.traefik.yml
:
version: '3.8'
services:
traefik:
image: traefik:v2.10
command:
- --providers.docker
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --certificatesresolvers.letsencrypt.acme.email=your@email.com
- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.letsencrypt.acme.tlschallenge=true
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./letsencrypt:/letsencrypt
whoami:
image: traefik/whoami
labels:
- "traefik.http.routers.whoami.rule=Host(`whoami.your-domain.com`)"
- "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
Заключение
SSL в Docker — это необходимость. Использование SSL/TLS-сертификатов в Docker — не просто рекомендация, а критически важная практика для безопасности ваших приложений. Без HTTPS ваш сервис помечается как «Небезопасный», а данные пользователей — под угрозой. Let’s Encrypt и Certbot позволяют получить бесплатные сертификаты с автоматическим обновлением.