Настройка HTTPS с сертификатами Let’s Encrypt

16 февраля 2018

Как вам может быть известно, современные браузеры помечают в адресной строке сайты, работающие по HTTP, как небезопасные. Есть также информация (мне, впрочем, неизвестно, насколько она достоверна) о том, что поисковые системы пессимизируют такие сайты в выдаче. Плюс к этому были выявлены случаи, когда операторы мобильной связи подмешивали рекламу в HTTP-трафик своих абонентов — естественно, на весь экран мобильного устройства и с поломанной версткой сайта. В общем, как ни крути, времена меняются, и мир переходит на HTTPS. Если у вас один домен, обычно не проблема купить сертификат для него прямо у вашего хостинг-провайдера. Но если сайтов много, или сайт один, но с большим числом поддоменов, цена на сертификаты или один wildcard сертификат выйдет просто неразумной. На помощь приходит сертификационный центр Let’s Encrypt, существующий за счет спонсоров и выдающий сертификаты бесплатно.

Помимо бесплатности, Let’s Encrypt интересен тем, что выдает сертификаты автоматически, при помощи специального клиента — Certbot. Сертификат действует 90 дней и продлевается также автоматически. В рамках этой заметки мы рассмотрим настройку всего этого хозяйства на примере Ubuntu Linux, как, по всей видимости, наиболее популярного серверного дистрибутива Linux. Отличия для других дистрибутивов и операционных систем будут минимальными.

Далее предполагается, что у вас уже установлен и настроен веб-сервер Nginx. Если это не так, вам поможет пост Установка и настройка Nginx, пара несложных примеров. Также предполагается, что если вы используете на сервере фаервол, то знаете, как открыть порт 443. Здесь вам поможет заметка Настройка фаервола с помощью iptables за пять минут.

Итак, устанавливаем Certbot:

sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python3-certbot-nginx

В конфиге nginx проверяем, что параметром server_name явно указано доменное имя вашего сайта, или несколько имен через пробел. Например:

# Вариант А, типичная раздача статики
server {
    listen 80 default_server;

    charset UTF-8;

    root /home/afiskon/afiskon.ru;
    index index.html index.htm;

    server_name afiskon.ru; # <--- !!!

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

# Вариант Б, типичный reverse proxy
server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    server_name forum.devzen.ru;

    location / {
        proxy_pass http://127.0.0.1:8080;

        proxy_set_header Host forum.devzen.ru;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

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

sudo service nginx reload

… и просим Certbot получить сертификат:

sudo certbot --nginx -d afiskon.ru

Можно указать несколько доменов, просто добавив в команду аргументов в стиле -d www.afiskon.ru. Далее вводим свой email для экстренной связи, соглашаемся с terms of service, отказываемся от получения новостей, просим перенаправить весь HTTP трафик в HTTPS. Если все было сделано правильно, Certbot поздравит вас с успешной настройкой HTTPS, а в браузере вы начнете видеть что-то вроде:

Пример настройки Let's Encrypt в Ubuntu Linux

Плюс к этому не лишено смысла проверить свой сайт на ssllabs.com/ssltest/, на всякий случай. Дополнительно рекомендуется проверить работу автоматического продления сертификатов. Сделать это можно командой:

sudo certbot renew --dry-run

Если вы все еще не убеждены, что сертификаты будут продлены автоматически, стоит проверить наличие файла /etc/cron.d/certbot.

Fun fact! Есть серьезная ошибка, которую можно допустить при настройке HTTPS и не заметить. К Let’s Encrypt она не имеет отношения, так как Certbot все настраивает правильно, но знать о ней все равно полезно. Суть в том, что вместе со своим сертификатом сервер обязательно должен отдавать цепочку всех промежуточных сертификатов вплоть до корневого. Проблему легко не заметить, так как некоторые браузеры, например, Chrome, умеют получать промежуточные сертификаты самостоятельно. Однако Firefox, а также многие социальные сети и веб-сервисы, в частности, ВКонтакте, Facebook и Feedburner, этого не умеют. И можно наткнуться на неприятную ситуацию (знаю по своему печальному опыту), когда у тебя в браузере все хорошо, а у других посетителей сайт помечен небезопасным, и плюс к этому у всех сломалась подписка по RSS. Проверить свой сайт на наличие проблемы и при необходимости сгенерировать полную цепочку можно на whatsmychaincert.com.

Важно понимать, что HTTPS не защищает абсолютно от всего. В частности, DNS все также никем не шифруется, а значит при желании не представляет труда завернуть пользователей сайта на его поддельную версию без HTTPS. Конечно, в случае с вашим личным блогом вы наверняка заметите отсутствие HTTPS и поймете, что дело нечисто. Однако средний пользователь вашего сайта ничего не заподозрит. Аналогично, если вы хостите статический сайт на каком-нибудь GitHub Pages, нужно понимать, что сертификатом владеете не вы, а GitHub, и при желании он может сделать с вашим трафиком все, что захочет.

Впрочем, невзирая на несовершенство современного веба с точки зрения безопасности, пожалуй, лучше с HTTPS, чем без него. Как минимум, благодаря HTTPS положение дел становится не хуже. Что до настройки, как мы только что выяснили, она занимает от силы минут пять времени и ноль денег.

Дополнение: В тему про то, почему не нужно слишком сильно полагаться на HTTPS — 23 тысячи SSL-сертификатов будут отозваны из-за инцидента в Trustico. Краткое содержание: реселлер «на всякий случай» хранил все приватные ключи клиентов.

Дополнение: Пример прикручивания Let’s Encrypt к Postfix и Dovecot вы найдете в статье Поднимаем собственный почтовый сервер на VDS. Наглядное объяснение, зачем вообще все это нужно, ищите в заметке О публичном Wi-Fi, поддельных SSID’ах и sslstrip.

Метки: , , .


Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.