TLS/SSL: NGINX – настройка SSL от Let’s Encrypt на Debian 8

Автор: | 12/04/2016

sslLet’s Encrypt – относительно новый Certificate Authority (CA) провайдер, который раздает TLS/SSL сертификаты бесплатно.

На сегодня – Let’s Encrypt еще в открытой бете, однако работает. Не хватает поддержки NGINX и виртуальных хостов – но доделают.

Пока – подключим Let’s Encrypt и NGINX с помощью плагина Webroot.

Схема того, как работает Let’s Encrypt и NGINX:

lets_encrypt_3

Установка выполняется на:

# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 8.1 (jessie)
Release:        8.1
Codename:       jessie

Устанавливаем необходимые пакеты:

# apt-get update && apt-get install vim bc git

Установа NGINX описана в посте Debian: установка LEMP – NGINX + PHP-FPM + MariaDB.

Установка клиента Let’s Encrypt

Загружаем репозиторий:

# git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt

Файлы клиента:

# ls -l /opt/letsencrypt/
total 168
-rw-r--r-- 1 root root   378 Apr 10 15:54 CHANGES.rst
-rw-r--r-- 1 root root   621 Apr 10 15:54 CONTRIBUTING.md
-rw-r--r-- 1 root root  2848 Apr 10 15:54 Dockerfile
-rw-r--r-- 1 root root  3016 Apr 10 15:54 Dockerfile-dev
...
-rwxr-xr-x 1 root root  1348 Apr 10 15:54 tox.cover.sh
-rw-r--r-- 1 root root  3211 Apr 10 15:54 tox.ini

Настройка Webroot

В блок server {} файла настроек хоста /etc/nginx/conf.d/dev.rtfm.co.ua.conf добавляем:

...
    # Lets Encrypt Webroot
    location ~ /.well-known {
        allow all;
    }
...

Проверяем:

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

Перезагружаем конфиг:

# service nginx reload

Создаем сертификат с помощью клиента Let’s Encrypt:

# cd /opt/letsencrypt
  • certonly: скачать сертифкат – но не устанавливать его;
  • --webroot-path: путь к каталогу с приложением;
  • -d: домен, можно указать несколько, еще раз указав -d;
# ./letsencrypt-auto certonly -a webroot --webroot-path=/var/www/vhosts/dev.rtfm.co.ua -d dev.rtfm.co.ua
Bootstrapping dependencies for Debian-based OSes... 
Ign http://cloudfront.debian.net jessie InRelease 
Hit http://cloudfront.debian.net jessie-updates InRelease 
Hit http://cloudfront.debian.net jessie Release.gpg
...
MPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/dev.rtfm.co.ua/fullchain.pem. Your cert will
   expire on 2016-07-09. To obtain a new version of the certificate in
   the future, simply run Let's Encrypt again.
   ...

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

Проверяем файлы:

# ls -l /etc/letsencrypt/live/dev.rtfm.co.ua/fullchain.pem
lrwxrwxrwx 1 root root 43 Apr 11 15:42 /etc/letsencrypt/live/dev.rtfm.co.ua/fullchain.pem -> ../../archive/dev.rtfm.co.ua/fullchain1.pem
# tree /etc/letsencrypt/archive/
/etc/letsencrypt/archive/
└── dev.rtfm.co.ua
    ├── cert1.pem
    ├── chain1.pem
    ├── fullchain1.pem
    └── privkey1.pem

Генерируем ключ Diffie–Hellman:

# openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
.............+......++*++*

Проверяем:

# file /etc/ssl/certs/dhparam.pem 
/etc/ssl/certs/dhparam.pem: ASCII text

Настройка NGINX

Снова обновляем конфиг /etc/nginx/conf.d/dev.rtf.co.ua.conf и добавляем поддержку SSL.

Во всех мануалах (и даже у меня) говорится про редирект с 80 порта на порт 443 (SSL) таким образом:

...
return 301 https://$host$request_uri;
...

Но возникла проблема с зацикливанием запроса, которая приводила к ошибке “ERR_TOO_MANY_REDIRECTS“, поэтому сделал немного иначе:

server {

    listen      80 default_server;
    listen      443 ssl;

    server_name dev.rtfm.co.ua;
    access_log /var/log/nginx/vhosts/rtfm.co.ua-access.log main;
    error_log /var/log/nginx/vhosts/rtfm.co.ua-error.log debug;

    root /var/www/vhosts/rtfm.co.ua;

    if ( $scheme = "http" ) {
        return 301 https://$host$request_uri;
    }

    ssl_certificate /etc/letsencrypt/live/dev.rtfm.co.ua/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/dev.rtfm.co.ua/privkey.pem;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_stapling on;
    ssl_stapling_verify on;
    add_header Strict-Transport-Security max-age=15768000;

    location / {

       index index.php index.html;
       proxy_read_timeout 3000;
       ...

Проверяем, перезагружаем:

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

Готово:

lets_encrypt_2

Проверить состояние шифрования можно тут>>>:

lets_encrypt_4

Автопродление сертификата

Продление сертифката выполняется с помощью Let’s Encrypt клиента:

# /opt/letsencrypt/letsencrypt-auto renew
Checking for new version...
Requesting root privileges to run letsencrypt...
   /root/.local/share/letsencrypt/bin/letsencrypt renew

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/dev.rtfm.co.ua.conf
-------------------------------------------------------------------------------

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/dev.rtfm.co.ua/fullchain.pem (skipped)
No renewals were attempted.

Так как сертификат только выдан – продление не требуется.

На будущее – добавляем две задачи в крон:

# crontab -e

Раз в месяц проверять сертификат и перечитвать конфиг NGINX:

@monthly /opt/letsencrypt/letsencrypt-auto renew >> /var/log/le-renew.log
@monthly /etc/init.d/nginx reload

Для обновления Let’s Encrypt клиента:

# cd /opt/letsencrypt
# git pull

Ссылки по теме

How To Secure Nginx with Let’s Encrypt on Ubuntu 14.04

Let’s Encrypt User Guide