Установка ssl-сертификата на Nginx в системе Debian)

lepiloff

Nov. 9, 2017, 2:27 p.m.

Для использования этой инструкции у вас должен быть настроен сервер на базе Debian. Так же вы должны иметь доменное имя типа example.com и настроенную DNS запись типа A, связывающую домен с внешним IP-адресом.

 

Шаг 1: установка Certbot

Если вы используете Debian 9 Strech или Ubuntu 17.x, то все довольно просто:

apt-get install certbot

В ином случае надо подключить Debian репозиторий  

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

Обновляем список установок

sudo apt-get update

Устанавливаем пакет Certbot's Nginx

sudo apt-get install certbot -t jessie-backports

Теперь Certbot установлен и готов к использованию, но требует внесения изменений в конфиг Nginx.

 

Шаг 2: получение сертификата

Let's Encrypt предоставляет несколько вариантов получения SSL сертификата с помощью плагинов. Но большинство плагинов предоставляют возможность только получения сертификата, а настройку web-сервера надо делать вручную. В данном руководстве для создания SSL-сертификата используется плагин Webroot.

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

Webroot работает со специальным файлом, расположенном в каталоге /.well-known. В зависимости от конфигурации вашего сервера, может потребоваться разрешить доступ к этому каталогу явно. Для этого откроем конфигурационный файл 

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

Если у вас на хостинге располагаются несколько сайтов, то возможно править нужно не дефолтный файл, а файл для конкретного домена. Например у меня папка  sites-available содержит три файла: default, first, second. Соответственно и править надо файл, соответствующий конкретному домену, для которого устанавлиывается ssl сертификат. Добавляем в поле server

 location ~ /.well-known {
            allow all;
            root /var/www/html;
        }

Мой файл sites-available/first стал выглядеть вот так:

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

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/gk/first;
    }

    location / {
        include         uwsgi_params;
        uwsgi_pass      unix:/run/uwsgi/first.sock;
    }
    
    location ~ /.well-known {
            allow all;
            root /var/www/html;
        }
}

Сохраняем, закрываем и проверяем на ошибки

sudo nginx -t

Если видим сообщение

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

значит ошибок не обнаружено и мы можем перезапустить nginx

sudo systemctl restart nginx

Теперь можно использовать плагин Webroot для запроса ssl сертификата. При помощи символа -d можно добавлять варианты сайта с-www и без-www.

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

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

Output:
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/example.com/fullchain.pem. Your cert
   will expire on 2017-09-05. 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 lose your account credentials, you can recover through
   e-mails sent to sammy@example.com.
 - Your account credentials have been saved in your Certbot
   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 Certbot so
   making regular backups of this folder is ideal.
 - 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
   

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

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

Для проверки наличия полученных сертификатов перейдите в 

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

и проверьте наличие файлов cert.pem, chain.pem, fullchain.pem, privkey.pem


Добавление ключей Диффи-Хеллмана

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

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


Шаг 3: конфигурирование TLS/SSL на Web-сервере Nginx

Теперь у нас есть подписанный сертификат, но для его использования необходимо дополнительно сконфигурировать сервер. Для этого надо сделать несколько настроек.

1. Создать сниппет содержащий наш SSL ключ и расположение файлов сертификата.
2. Создать конфигурационный сниппет содержащий общие SSL настройки, используемые всеми сертификатами в будущем.
3. Настроить Nginx сервер для поддержки SSL запросов и два свежесозданных сниппета.  


Создание конфигурационного сниппета для SSL ключа 

Создадим новы файл расположенный по адресу /etc/nginx/snippets. Для наглядности назовем его именем домена с приставкой ssl

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

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

ssl_certificate /etc/letsencrypt/live/your_domain_name/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain_name/privkey.pem;

После добавления сохраните и закройте файл.

Создание и настройка файла общих настроек

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

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

И добавим в него следующие строки

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 HSTS header for now
#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 для работы с SSL

Как и в начале инструкции название файла в который вносятся изменения выбирается исходя из содержимого папки /etc/nginx/sites-available. Если у вас один сайт используйте default, если несколько - имя вашего проекта. Я по прежнему буду работать с first.

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

Откроем файл для вснесения изменений 

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

Перед правками файл first содержит следующий код

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

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/gk/first;
    }

    location / {
        include         uwsgi_params;
        uwsgi_pass      unix:/run/uwsgi/first.sock;
    }
    
    location ~ /.well-known {
            allow all;
            root /var/www/html;
        }
}

Файл default выглядит так

server {
        listen 80 default_server;
        listen [::]:80 default_server;
        root /var/www/html;
        server_name _;

Я привел пример своего файла default, так как надо учитывать, что в одном из конфигурационных файлов обязательно должны содержаться строки default_server. Если у вас нет файла default добавьте их в свой файл.

Теперь нам надо добавить перенаправление незашифрованных запросов http на зашифрованный протокол https. После внесения изменений получим

server {
    listen 80;
    listen [::]:80;
    server_name first.com www.first.com;
    return 301 https://first.com$request_uri;
}

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name www.first.com;
        include snippets/ssl-first.com.conf;
        include snippets/ssl-params.conf;
        return 301 https://first.com$request_uri;
}

server {
        # SSL configuration

        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        include snippets/ssl-first.com.conf;
        include snippets/ssl-params.conf;

        root /var/www/html;

        server_name first.com;

        location = /favicon.ico { access_log off; log_not_found off; }
        location /static/ {
            root /home/gk/first;
        }

        location / {
            include         uwsgi_params;
            uwsgi_pass      unix:/run/uwsgi/first.sock;
        }

        location ~ /.well-known {
            allow all;
            root /var/www/html;
        }

        location ~ /\.ht {
            deny all;
        }
}


Шаг 4: настройка файервола

Настройка брандмаузера UFW

Если вы используете на своем сервере UFW, то необходимо добавить в его исключения трафик SSL. Для начала проверим текщие правила:

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)

Пропишем следующие правила:

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


Брандмаузер iptables

Если вы используете брандмаузер iptables активируйте работу с SSL

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

 

Шаг 5: применение изменений в настройках Nginx

Проверим отсутствие ошибок синтаксиса:

sudo nginx -t

Если получаем вывод:

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

то все правильно и можно перезапустить Nginx:

sudo systemctl restart nginx

Теперь ваш SSL сертификат установлен и работает, проверить его можно по ссылке

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


Шаг 6: автообновление сертификата

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

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

sudo certbot renew

Что бы избавиться и от этих действий, можно воспользоваться линуксовым планировщиком cron. Откройте файл

sudo crontab -e

И добавьте строку 

30 2 * * * /usr/bin/certbot renew --noninteractive --renew-hook "/bin/systemctl reload nginx" >> /var/log/le-renew.log

Это позволит ежедневно запускать команду certbot renew и записывать результат выполнения в логфайл по адресу /var/log/le-renewal.log.

debian, django, nginx