Зачем это?
У защищенного соединения есть множество преимуществ перед старым добрым http: защита от перехвата траффика, защита от подмены содержимого, лучшее ранжирование в поисковых системах и т.д. Мне вот, например, нравится зеленый значок в адресной строке. Раньше за всё это удовольствие нужно было платить, поэтому сертификаты можно было увидеть только на крупных проектах, либо платежных системах (где риск компрометации данных велик и без сертификата вас просто не поймут). Проект letsencrypt.org призван изменить это положение вещей раз и навсегда.
Получение бесплатного, но полностью функционального сертификата теперь доступно каждому. Проект предоставляет утилиту командной строки, с помощью которой можно сгенерировать ключ, сертификат, и даже, в типовых случаях, установить этот сертификат в ваш конфиг веб-сервера. Единственное серьезное отличие от привычных платных сертификатов — время жизни в три месяца. Но это не минус, а намеренный подход: предполагается, что сервер будет настроен на автоматическое получение нового сертификата взамен полученного ранее (это должно помочь в борьбе с компрометацией ключей).
Настройка
Заявлено, что предоставляемая утилита командной строки умеет самостоятельно анализировать и обновлять конфиги Apache и nginx, генерируя новый сертификат и указывая все необходимые для него настройки. Понятно, что это позволит обновить малой кровью типовые конфиги, но, я считаю, этот подход далеко не всегда оправдан. Во-первых, ваш конфиг может быть значительно сложнее устроен, чем типовой и нет никакой гарантии, что автоматический режим с ним справится. Во-вторых, хорошо иметь полное представление, что и почему происходит на вашем сервере, чтобы иметь возможность исправить недочеты или повторить действия для получения результата. В-третьих, в моем случае, nginx был завернут внутрь контейнера docker — к такому утилиту точно не готовили. Так что мы будем действовать по старинке!
Для начала скачаем утилиту:
cd /opt
mkdir letsencrypt && cd letsencrypt
git clone https://github.com/letsencrypt/letsencrypt .
Теперь напишем скрипт, генерирующий сертификат. Здесь /var/www/astgo — директория, в которой находятся исходники приложения. Важно: перед созданием сертификата, нужно освободить порты (если они заняты), чтобы утилита могла использовать их для подтверждения владения вами указанного домена. В указанном ниже примере для этого останавливаются контейнеры docker, после обновления сертификата их нужно поднять обратно.
# /opt/update-cert.sh
(cd /var/www/astgo && docker-compose stop && docker-compose rm --force) &&
(cd /opt/ && ./letsencrypt/letsencrypt-auto certonly -d ast.rocks --email astartsky@gmail.com --standalone --renew-by-default --agree-tos --standalone-supported-challenges tls-sni-01) &&
cp /etc/letsencrypt/live/ast.rocks/cert.pem /var/www/astgo/build/nginx &&
cp /etc/letsencrypt/live/ast.rocks/chain.pem /var/www/astgo/build/nginx &&
cp /etc/letsencrypt/live/ast.rocks/fullchain.pem /var/www/astgo/build/nginx &&
cp /etc/letsencrypt/live/ast.rocks/privkey.pem /var/www/astgo/build/nginx &&
(cd /var/www/astgo/ && docker-compose build --no-cache && docker-compose up -d)
Разберем подробнее вызов утилиты:
- certonly — только генерация сертификата, никаких действий по автоматической установке не требуется;
- -d — домен, на который будет сгенерирован сертификат;
- —email — электронная почта, по которой с вами сможет связаться letsencrypt;
- —standalone — для подтверждения владения доменом, будет поднят отдельный веб-сервер;
- —renew-by-default — при повторном вызове не будет создан новый сертификат;
- —agree-tos — разумеется, при первом запуске нужно согласиться с условиями представления услуги;
- —standalone-supported-challenges tls-sni-01 — разрешить использовать 443 порт для проверки домена;
После запуска скрипта заветные сертификаты окажутся в указанных выше папках. Дело осталось за малым: указать их в конфигах nginx. Например, так:
ssl_stapling_verify on;
ssl_stapling on;
ssl_trusted_certificate /opt/chain.pem;
ssl_certificate_key /opt/privkey.pem;
ssl_certificate /opt/fullchain.pem;
listen 443 ssl;
Также имеет смысл поместить вызов этого скрипта в cron каждые два месяца, чтобы обновление сертификата было полностью автоматическим.