Let’s Encrypt — это бесплатный и открытый центр сертификации, разработанный исследовательской группой Internet Security Research Group (ISRG). Сертификатам, выпущенным Let's Encrypt, сегодня доверяют почти все браузеры. В этом руководстве мы рассмотрим пошаговые инструкции о том, как защитить ваш Nginx с помощью Let's Encrypt с помощью инструмента certbot в Ubuntu 16.04.

Предпосылки

Прежде чем продолжить работу с этим учебным пособием, убедитесь, что выполнены следующие предварительные условия:

  • У вас есть доменное имя, указывающее на ваш общедоступный IP-адрес сервера. В этом уроке мы будем использовать example.com.
  • У вас установлен Nginx

Установить Certbot 

Certbot — это написанная на python утилита, которая может автоматизировать задачи по получению и обновлению SSL-сертификатов Let’s Encrypt и настройке веб-серверов.

Сначала установите software-properties-commonпакет, который предоставляет add-apt-repositoryинструмент, необходимый для добавления дополнительных PPA.

Обновите индекс пакетов и установите software-properties-commonс помощью:

sudo apt update
sudo apt install software-properties-common

После завершения установки добавьте репозиторий certbot PPA в свою систему с помощью следующей команды:

sudo add-apt-repository ppa:certbot/certbot

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

sudo apt update
sudo apt install certbot

Генерация ключей Dh (Диффи-Хеллмана)

Обмен ключами Диффи-Хеллмана (DH) — это метод безопасного обмена криптографическими ключами по незащищенному каналу связи. Создайте новый набор 2048-битных параметров DH для усиления безопасности:

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

 

Получение SSL-сертификата Let’s Encrypt

Чтобы получить сертификат SSL для нашего домена, мы собираемся использовать плагин Webroot, который работает, создавая временный файл для проверки запрошенного домена в ${webroot-path}/.well-known/acme-challengeкаталоге. Сервер Let's Encrypt отправляет HTTP-запросы к временному файлу, чтобы убедиться, что запрошенный домен разрешается на сервер, на котором работает certbot.

Чтобы упростить задачу, мы собираемся сопоставить все HTTP-запросы .well-known/acme-challengeс одним каталогом /var/lib/letsencrypt.

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

sudo mkdir -p /var/lib/letsencrypt/.well-known
sudo chgrp www-data /var/lib/letsencrypt
sudo chmod g+s /var/lib/letsencrypt

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

/etc/nginx/snippets/letsencrypt.conf

location ^~ /.well-known/acme-challenge/ {
  allow all;
  root /var/lib/letsencrypt/;
  default_type "text/plain";
  try_files $uri =404;
}

/etc/nginx/snippets/ssl.conf

ssl_dhparam /etc/ssl/certs/dhparam.pem;

ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on;

ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 30s;

add_header Strict-Transport-Security "max-age=15768000; includeSubdomains; preload";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;

Вышеприведенный фрагмент включает чипперы, рекомендованные Mozilla , включает сшивание OCSP, HTTP Strict Transport Security (HSTS) и обеспечивает несколько заголовков HTTP, ориентированных на безопасность.

После создания фрагментов откройте блок сервера домена и letsencrypt.confвключите фрагмент, как показано ниже:

/etc/nginx/sites-available/example.com.conf

server {
  listen 80;
  server_name example.com www.example.com;

  include snippets/letsencrypt.conf;
}

Активируйте блок server, создав символическую ссылку  sites-available  в sites-enabled:

sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/example.com.conf

Перезагрузите конфигурацию Nginx, чтобы изменения вступили в силу:

sudo systemctl reload nginx

Запустите скрипт certbot с плагином webroot и получите файлы SSL-сертификата:

sudo certbot certonly --agree-tos --email admin@example.com --webroot -w /var/lib/letsencrypt/ -d example.com -d www.example.com

Если SSL-сертификат успешно получен, certbot напечатает следующее сообщение:

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2018-04-23. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

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

 

/etc/nginx/sites-available/example.com.conf

server {
    listen 80;
    server_name www.example.com example.com;

    include snippets/letsencrypt.conf;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name www.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    include snippets/ssl.conf;
    include snippets/letsencrypt.conf;

    return 301 https://example.com$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    include snippets/ssl.conf;
    include snippets/letsencrypt.conf;

    # . . . other code
}

С приведенной выше конфигурацией мы форсируем HTTPS и перенаправляем www версию домена на non www версию. Перезагрузите службу Nginx, чтобы изменения вступили в силу:

sudo systemctl reload nginx

Автоматическое продление SSL-сертификата

Сертификаты Let’s Encrypt действительны в течение 90 дней. Чтобы автоматически обновлять сертификаты до истечения срока их действия, пакет certbot создает cronjob , который будет запускаться два раза в день и автоматически обновлять любой сертификат за 30 дней до истечения срока его действия.

Поскольку мы используем подключаемый модуль certbot webroot после обновления сертификата, нам также необходимо перезагрузить службу nginx. Для этого добавьте --renew-hook "systemctl reload nginx"в /etc/cron.d/certbotфайл, чтобы он выглядел следующим образом:

/etc/cron.d/certbot

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew --renew-hook "systemctl reload nginx"

Чтобы протестировать процесс обновления, используйте --dry-runпереключатель certbot:

sudo certbot renew --dry-run

Если ошибок нет, значит, процесс обновления прошел успешно.
 

Заключение

В этом руководстве вы использовали клиент Let's Encrypt, certbot, для получения SSL-сертификатов для своего домена. Вы также создали фрагменты Nginx, чтобы избежать дублирования кода, и настроили Nginx для использования сертификатов. В конце руководства вы настроили cronjob для автоматического обновления сертификата.