Настройка сертификата для nginx

Защищать соединение будем с помощью сертификатов от Let's Encrypt. Проект был создан для широкого распространения https среди веб-сайтов. В отличии от коммерческих центров сертификации, Let's Encrypt не требует оплаты, но существует ряд ограничений:

  • сертификат выдаётся на 90 дней
  • нет wildcard (сертификат дают строга на один домер)
  • ограничение 5-7 сертификатов в неделю

Огромный плюс Let's Encrypt в том, что процедура выдачи и обновления сертификатов полностью автоматизирована.

Оглавление:

  1. Установка Let's Encrypt
  2. Настройка Nginx
  3. Настройка Let's Encrypt
  4. Донастройка Nginx
  5. Настройка автообновления

1. Установка Let's Encrypt


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

Для последующего обновления клиента можно воспользоваться такой командой:

cd /opt/letsencrypt
sudo git pull

Создадим сильный приватный ключ по алгоритму Диффи – Хеллмана:

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

2. Настройка Nginx


Создаём директорию, с которой будет общаться letsencrypt, для проверки прав на домен:

cd /var/www
sudo mkdir letsencrypt
sudo chgrp www-data letsencrypt

Разрешаем letsencrypt получать доступ через webroot, вставляем этот кусок в /etc/nginx/snippets/well-known.conf:

location /.well-known/acme-challenge {
    root /var/www/letsencrypt;
}

Конфигурация для сайта /etc/nginx/sites-available/tai-pan.org, должна выглядить так:

server {
    listen 80 default_server;
    server_name tai-pan.org www.tai-pan.org;
    include snippets/well-known.conf;
    ...
}

Создадим файлик /etc/nginx/snippets/ssl-params.conf с дополнительными настройками ssl, он пригодится нам пожже:

# 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;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

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

Проверим конфигурацию и перезагрузим nginx:

sudo nginx -t && sudo nginx -s reload

3. Настройка Let's Encrypt


Создаём конфиг для получения/настройки сертификата, хорошая практика один конфиг на домен, но для www сделаем исключение, чтобы не было путаницы, так это всё равно будет алиас на основной домен:

sudo mkdir -p /etc/letsencrypt/configs

Создаём вот такой файл /etc/letsencrypt/configs/tai-pan.org.conf:

domains = tai-pan.org

# increase key size
rsa-key-size = 2048 # Or 4096

# the current closed beta (as of 2015-Nov-07) is using this server
server = https://acme-v01.api.letsencrypt.org/directory

# this address will receive renewal reminders
email = info@tai-pan.org

# turn off the ncurses UI, we want this to be run as a cronjob
text = True

# authenticate by placing a file in the webroot (under .well-known/acme-challenge/)
# and then letting LE fetch it
authenticator = webroot
webroot-path = /var/www/letsencrypt/

Для домена www.tai-pan.org делаем аналогичный /etc/letsencrypt/configs/www.tai-pan.org.conf

Наконец можно сгенерировать сертификат:

cd /opt/letsencrypt
./letsencrypt-auto --config /etc/letsencrypt/configs/tai-pan.org.conf certonly

4. Донастройка Nginx


Допишем в файл конфигурации хоста /etc/nginx/sites-available/tai-pan.org настройку для https:

server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

    ssl_certificate /etc/letsencrypt/live/tai-pan.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/tai-pan.org/privkey.pem;
    include snippets/ssl-params.conf;
    ...

Для редиректа с www.tai-pan.org на tai-pan.org допишем:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name tai-pan.org www.tai-pan.org;
    include snippets/well-known.conf;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name www.tai-pan.org;
    ssl_certificate /etc/letsencrypt/live/www.tai-pan.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.tai-pan.org/privkey.pem;
    return 301 https://tai-pan.org$request_uri;
}

server {
  listen 443 ssl default_server;
  listen [::]:443 ssl default_server;
  server_name tai-pan.org;

  ssl_certificate /etc/letsencrypt/live/tai-pan.org/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/tai-pan.org/privkey.pem;
  include snippets/ssl-params.conf;

  server_tokens off;

Теперь применяем найтройки и перезапускаем:

sudo nginx -t && sudo service nginx restart

Для проверки, что мы всё правильно настроили можно можно воспользоваться таким сервисом: https://www.ssllabs.com/ssltest/analyze.html?d=tai-pan.org

5. Настройка автообновления


Для ручного вызова обновления сертификатов:

/opt/letsencrypt/letsencrypt-auto renew

Создадим cron задачу, которая будет обновлять сертификаты каждое первое число месяца и перезапускать nginx через 10 минут, открываем cron sudo crontab -e и вписываем:

0 0 1 * * /opt/letsencrypt/letsencrypt-auto renew >> /var/log/le-renew.log
10 0 1 * * /bin/systemctl reload nginx