Создание сертификата Let’s Encrypt для Nginx в Debian 8

Published by Leave your thoughts

Let’s Encrypt – это новый центр сертификации (ЦС, или Certificate Authority, CA), который предоставляет простой способ создания сертификатов TLS/SSL, тем самым позволяя шифровать HTTPS на веб-серверах. Этот ЦС упрощает процесс создания сертификатов путём автоматизации большинства необходимых действий при помощи клиента certbot (раньше он назывался letsencrypt). На данный момент процесс получения и установки сертификата полностью автоматизирован только на веб-серверах Apache. Тем не менее, Let’s Encrypt позволяет получить бесплатный сертификат SSL, который можно установить вручную независимо от программного обеспечения веб-сервера.

Данное руководство поможет установить Let’s Encrypt и получить SSL-сертификат для Nginx в системе Debian 8 и покажет, как обновлять этот сертификат.

Требования

  • Настроенный сервер Debian 8.
  • Пользователь с доступом к sudo (инструкции по начальной настройке сервера и созданию пользователя можно найти в этом руководстве).
  • Доменное имя, которое можно использовать в сертификате (в руководстве используется условные домены example.com и www.example.com).
  • Запись А, связывающая домен с внешним IP-адресом сервера. Она необходима для того, чтобы Let’s Encrypt мог проверить доменное имя (в руководстве используется два домена, нужно создать запись А для каждого из них).

1: Установка клиента certbot

Сначала нужно установить certbot. Это клиент Let’s Encrypt, который позволяет получить SSL-сертификат.

Пакета certbot нет в официальном репозитории Debian 8. Загрузить пакет certbot можно из backports-репозитория Jessie.

Добавьте этот репозиторий:

echo 'deb http://ftp.debian.org/debian jessie-backports main' | sudo tee /etc/apt/sources.list.d/backports.list

Обновите индекс пакетов:

sudo apt-get update

Теперь можно установить пакет certbot.

Примечание: Backports-репозитории не рекомендуется использовать для общесистемных обновлений. Устанавливайте только необходимые вам пакеты. Backports-пакеты менее совместимы, чем пакеты из основных репозиториев.

Чтобы избежать случайной установки или обновления пакетов из backports-репозитория, используйте флаг –t перед именем репозитория.

sudo apt-get install certbot -t jessie-backports

Клиент certbot готов к работе.

2: Получение сертификата

Let’s Encrypt предлагает несколько способов получения сертификата при помощи разных плагинов. На данный момент плагины позволяют только получить сертификат, а настройку сервера для использования этого сертификата нужно выполнить вручную; исключением является плагин для Apache, работа с которым описана здесь.

В данном руководстве для создания SSL-сертификата используется плагин Webroot.

Использование плагина Webroot

Плагин Webroot помещает специальный файл в каталог /.well-known в каталоге document root, который сервис Let’s Encrypt может открыть для подтверждения через веб-сервер. В зависимости от настройки может понадобиться явно разрешить доступ к каталогу /.well-known.

Если Nginx ещё не установлен, установите его с помощью этого руководства.

Чтобы сервис Let’s Encrypt смог получить доступ к каталогу, отредактируйте настройки Nginx. Откройте стандартный конфигурационный файл (/etc/nginx/sites-available/default) в текстовом редакторе:

sudo nano /etc/nginx/sites-available/default

Добавьте в блок server новый блок location.

location ~ /.well-known {
allow all;
}

Также нужно проверить настройку каталога document root, за который отвечает директива root. По умолчанию каталогом document root является /var/www/html.

Сохраните и закройте файл.

Убедитесь, что в файле нет ошибок:

sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Если ошибок не обнаружено, перезапустите веб-сервер:

sudo systemctl restart nginx

Теперь можно использовать плагин Webroot для запроса SSL-сертификата. При помощи флага –d укажите доменное имя; чтобы создать один сертификат для нескольких доменных имён (например, example.com и www.example.com), добавьте в команду несколько флагов –d. Замените условные данные своими данными.

sudo certbot certonly -a webroot --webroot-path=/var/www/html -d example.com -d www.example.com

После запуска certbot запросит некоторые данные.

Примечание: Вопросы, задаваемые при первом запуске программы, отличаются от вопросов, задаваемых при дальнейшем её использовании. В руководстве предполагается, что программа запущена впервые.

Укажите адрес электронной почты, который будет использоваться для отправки извещений и восстановления утерянных ключей.

После этого нужно принять условия соглашения подписчика Let’s Encrypt.

Если всё выполнено правильно, программа вернёт:

IMPORTANT NOTES:
- If you lose your account credentials, you can recover through
e-mails sent to user@8host.com
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/example.com/fullchain.pem. Your
cert will expire on 2017-03-14. To obtain a new version of the
certificate in the future, simply run Let's Encrypt again.
- Your account credentials have been saved in your Let's Encrypt
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Let's
Encrypt so making regular backups of this folder is ideal.
- If like Let's Encrypt, please consider supporting our work by:
Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
Donating to EFF:                    https://eff.org/donate-le

Выпишите или запомните путь и срок действия сертификата (в примере они выделены красным).

Важно! Если вы получили ошибку Failed to connect to host for DVSNI challenge, разблокируйте трафик на портах 80 и 443.

Примечание: В некоторых случаях домен нужно отключить на время получения сертификата.

Файлы сертификата

После получения сертификата на сервере появятся следующие PEM-файлы:

  • cert.pem: сертификат домена.
  • chain.pem: сертификат цепочки Let’s Encrypt.
  • fullchain.pem: комбинация cert.pem и chain.pem.
  • privkey.pem: закрытый ключ сертификата.

Важно знать место хранения сертификата, так как его нужно будет указать в конфигурации веб-сервера. Файлы хранятся в подкаталоге /etc/letsencrypt/archive, также Let’s Encrypt создаёт символьную ссылку на наиболее актуальный сертификат в каталог /etc/letsencrypt/live/your_domain_name.

Чтобы убедиться, что все файлы существуют, нужно выполнить такую команду:

sudo ls -l /etc/letsencrypt/live/your_domain_name

Команда покажет список существующих файлов.

Ключи Диффи-Хеллмана

Чтобы увеличить уровень защиты, нужно сгенерировать ключи Диффи-Хеллмана. Чтобы сгенерировать 2048-битные ключи, введите:

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

Выполнение команды займёт несколько минут. Ключи DH будут храниться в /etc/ssl/certs/dhparam.pem.

3: Настройка TLS/SSL на веб-сервере Nginx

Теперь нужно настроить веб-сервер Nginx для обслуживания сертификата. Для этого нужно внести в настройки такие изменения:

  1. Добавить сниппет для сертификата и ключа SSL.
  2. Добавить сниппет общих настроек SSL, который будет доступен всем сертификатам.
  3. Настроить поддержку SSL и обработку новых сниппетов в виртуальном хосте (блоке server) Nginx.

Сниппет для SSL-сертификата и ключа

Создайте новый сниппет Nginx в каталоге /etc/nginx/snippets. Выберите для него описательное имя (например, можно добавить префикс ssl-):

sudo nano /etc/nginx/snippets/ssl-example.com.conf

В этом файле нужно определить директивы ssl_certificate и ssl_certificate_key, которые указывают путь к сертификату и ключу соответственно.

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

Сохраните и закройте файл.

Сниппет общих настроек SSL

Теперь нужно создать сниппет общих настроек SSL. Здесь нужно определить шифрование и включить дополнительные функции безопасности.

Эти параметры Nginx сможет использовать  и в будущих настройках.

sudo nano /etc/nginx/snippets/ssl-params.conf

Для настройки SSL на Nginx используйте рекомендации Remy van Elst с сайта Cipherli.st. Больше рекомендаций для Nginx можно найти здесь.

Примечание: Предлагаемые на сайте Cipherli.st настройки очень надёжны. Однако в некоторых случаях это негативно влияет на совместимость клиента. Если вам нужна поддержка старых клиентов, откройте альтернативный список настроек, перейдя по ссылке «Yes, give me a ciphersuite that works with legacy / old software».

Эти альтернативные настройки можно использовать далее вместо рекомендуемых настроек по умолчанию. Выбор настроек во многом зависит от потребностей сайта или приложения.

Скопируйте все предложенные настройки и внесите в них небольшие коррективы.

Сначала укажите DNS-преобразователь. В данном руководстве используется преобразователь Google. Также нужно добавить параметр ssl_dhparam, чтобы указать сгенерированный ключ Диффи-Хеллмана.

Ознакомьтесь с HTTP Strict Transport Security (или HSTS), особое внимание обратите на раздел preload.

Предзагрузка HSTS обеспечивает повышенную безопасность, но неправильное или случайное подключение может иметь далеко идущие последствия. В этом руководстве мы не будем предварительно загружать настройки, но вы можете сделать это, если вы уверены, что понимаете последствия:

# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable preloading HSTS for now.  You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_dhparam /etc/ssl/certs/dhparam.pem;

Сохраните и закройте файл.

Настройка Nginx для поддержки SSL

Теперь сниппеты готовы, и вы можете отредактировать конфигурации Nginx, чтобы настроить поддержку SSL.

Примечание: Далее предполагается, что вы используете виртуальный хост default из каталога /etc/nginx/sites-available. Если вы используете другой файл, укажите его имя.

Сначала нужно создать резервную копию виртуального хоста:

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak

Откройте файл в редакторе:

sudo nano /etc/nginx/sites-available/default

На данный момент файл, скорее всего, содержит такие строки:

server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
. . .

Теперь нужно изменить настройки так, чтобы незашифрованные запросы HTTP автоматически перенаправлялись на HTTPS. Это обеспечивает максимальную безопасность сайта.

Примечание: Если вы хотите настроить поддержку и HTTP, и HTTPS трафика, использовать альтернативные настройки, которые можно найти ниже.

Настройки нужно разделить на два блока. После директив listen нужно добавить server_name и указать доменное имя сервера. Затем нужно настроить редирект.

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
# SSL configuration
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
. . .

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

Примечание: Вы можете использовать только одну директиву listen с модификатором default_server для каждой комбинации IP-адреса и порта. Если эти порты и default_server используются в другом виртуальном хосте, оставьте модификатор только водном из них.

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
# SSL configuration
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
. . .

Сохраните и закройте файл.

Настройка трафика HTTP и HTTPS (альтернативный вариант)

Чтобы настроить поддержку шифрованного и нешифрованного трафика, используйте следующие настройки Nginx.

Примечание: Использовать незашифрованный трафик не рекомендуется.

В целом, нужно просто сжать два отдельных блока в один блок и удалить редирект:

server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name example.com www.example.com;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
. . .

Сохраните и закройте файл.

4: Настройка брандмауэра

Если вы включили брандмауэр, нужно разблокировать трафик SSL.

Примечание: Если брандмауэр отключен, можете пропустить этот раздел.

Брандмауэр UFW

Чтобы просмотреть текущие правила UFW, введите:

sudo ufw status

Если они выглядят так, то брандмауэр пропускает только трафик HTTP:

Status: active
To                         Action      From
--                         ------      ----
SSH                        ALLOW       Anywhere
WWW                        ALLOW       Anywhere
SSH (v6)                   ALLOW       Anywhere (v6)
WWW (v6)                   ALLOW       Anywhere (v6)

Чтобы разблокировать трафик HTTPS, включите поддержку профиля WWW Full и удалите профиль WWW.

sudo ufw allow 'WWW Full'
sudo ufw delete allow 'WWW'

Теперь настройки выглядят так:

sudo ufw status
Status: active
To                         Action      From
--                         ------      ----
SSH                        ALLOW       Anywhere
WWW Full                   ALLOW       Anywhere
SSH (v6)                   ALLOW       Anywhere (v6)
WWW Full (v6)              ALLOW       Anywhere (v6)

Теперь брандмауэр поддерживает трафик HTTPS.

Брандмауэр iptables

Чтобы просмотреть текущий набор правил iptables, введите:

sudo iptables -S

На экране появится список правил. Например:

-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

Какие правила нужно добавить, чтобы настроить поддержку SSL, зависит от текущих правил брандмауэра. Если вы используете базовый набор правил, используйте такое правило:

sudo iptables -I INPUT -p tcp -m tcp --dport 443 -j ACCEPT

Просмотрите правила. Теперь они выглядят так:

sudo iptables -S
-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

Если правила iptables загружаются автоматически вместе с сервером, добавьте в эту настройку и новое правило.

5: Обновление настроек Nginx

Теперь нужно перезапустить Nginx, чтобы изменения вступили в силу. Сначала проверьте синтаксис:

sudo nginx -t

Если в настройках не обнаружено ошибок, вы увидите такой вывод:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Перезапустите веб-сервер:

sudo systemctl restart nginx

Теперь веб-сервер поддерживает TLS/SSL-сертификат Let’s Encrypt, а брандмауэр пропускает трафик на портах 80 и 443.

Чтобы убедиться, что сертификат работает, откройте свой домен в браузере.

Чтобы проверить настройку сертификата, можно использовать сервис Qualys SSL Labs.

https://www.ssllabs.com/ssltest/analyze.html?d=example.com

Проверка может занять несколько минут.

6: Автоматическое обновление сертификата

Сертификаты Let’s Encrypt действительны в течение 90 дней, но во избежание ошибок их рекомендуется обновлять каждые 60 дней. На момент написания статьи клиент не оборудован функцией автоматического обновления сертификатов. Этот процесс можно выполнить вручную при помощи опции Let’s Encrypt renew.

Чтобы запустить обновление для всех доменов, запустите:

sudo certbot renew

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

Saving debug log to /var/log/letsencrypt/example.com.log
-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/example.com.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal
The following certs are not due for renewal yet:
/etc/letsencrypt/live/example.com/fullchain.pem (skipped)
No renewals were attempted.

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

Надёжный способ обеспечить своевременное обновление сертификата – это демон cron.

Команда renewal будет отслеживать срок действия сертификата и обновлять его за 30 дней до истечения этого срока. Настройте cron запускать команду раз в неделю. Таким образом, в случае сбоя cron у вас будет в запасе 30 дней, чтобы снова попытаться обновить сертификат.

Отредактируйте crontab:

sudo crontab -e

Программа может предложить выбрать текстовый редактор по умолчанию. Добавьте в crontab root-пользователя следующие строки:

30 2 * * 1 /usr/bin/certbot renew >> /var/log/le-renew.log
35 2 * * 1 /bin/systemctl reload nginx

Сохраните и закройте файл.

Теперь cron будет запускать команду renew каждый понедельник в 2:30 ночи, а вывод команды будет помещён в лог /var/log/le-renewal.log.

Читайте также: Автоматизация задач с помощью cron

Теперь ве-сервер защищен при помощи SSL-сертификата Let’s Encrypt.

Tags: , , , ,

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *


*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>