MyTetra Share
Делитесь знаниями!
О, смотри-ка какое хорошее место. Дайте два!
Настройка сертификатов Let's Encrypt HTTPS на веб-сервере NGinx в Debian Linux Jessie
04.07.2017
10:30
Автор: xintrea
Текстовые метки: https, ssl, Let's Encrypt, LetsEncrypt, вебсервер, nginx, debian, сертификат, сайт, linux
Раздел: Компьютер - Linux - Сеть в Linux - HTTPS

С некоторых пор специалисты Let's Encrypt сделали скрипт, позволяющий практически полностью автоматизировать процесс получения и обновления сертификатов. Но, к сожалению, этот скрипт и методы его использования постоянно меняются. Здесь описано как сделать настройку HTTPS с использованием автообновляемых сертификатов Let's Encrypt на сайте, крутящемся на веб-сервере NGinx. Сведения актуальны на июль 2017 года.



Установка скрипта Let's Encrypt


В Debian существует возможность устанавливать скрипт из репозитария. Однако, скрипты Let's Encrypt постоянно меняются, API сервера переделывается, поэтому здесь будет описан метод установки скрипта Let's Encrypt с официального сайта Electronic Frontier Foundation eff.org.


Вначале нужно создать директорию, в которой будет лежать скрипт автообновления от компании Let's Encrypt. Надо создать директорию /opt/letsencrypt:


mkdir -p /opt/letsencrypt


Затем надо зайти в эту директорию и дать команду:


wget https://dl.eff.org/certbot-auto


В результате будет загружен файл certbot-auto, который надо сделать выполняемым:


chmod 755 ./certbot-auto


Внимание! Данный файл - это не скрипт для работы с сертификатами. Это инсталлятор скрипта для работы с сертификатами. Можно запустить его с опцией --help и увидеть следующее:


# ./certbot-auto --help


Usage: $BASENAME [OPTIONS]

A self-updating wrapper script for the Certbot ACME client. When run, updates

to both this script and certbot will be downloaded and installed. After

ensuring you have the latest versions installed, certbot will be invoked with

all arguments you have provided.


Help for certbot itself cannot be provided until it is installed.


--debug attempt experimental installation

-h, --help print this help

-n, --non-interactive, --noninteractive run without asking for user input

--no-bootstrap do not install OS dependencies

--no-self-upgrade do not download updates

--os-packages-only install OS dependencies and exit

-v, --verbose provide more output

-q, --quiet provide only update/error output;

implies --non-interactive


All arguments are accepted and forwarded to the Certbot client when run.


Для того, чтобы произвести инсталляцию скрипта для работы с сертификатами, нужно запустить ./certbot-auto без опций. Запуск надо делать от пользователя root, так как скрипт будет доустанавливать нужные пакеты. В процессе инсталляции будет выведен список сертификатов. Для продолжения нужно будет промотать список вниз, и нажать кнопку q. В конечном итоге процесс инсталляции завершится сообщением:


Installation succeeded.

Saving debug log to /var/log/letsencrypt/letsencrypt.log

With the webroot plugin, you probably want to use the "certonly" command, eg:


certbot-auto certonly --webroot


(Alternatively, add a --installer flag. See https://eff.org/letsencrypt-plugins

and "--help plugins" for more information.)


С этого момента скрипт /opt/letsencrypt/certbot-auto будет самостоятельно определять, что инсталляция была произведена, и если снова вызвать его с опцией --help, то вывод будет уже совершенно другой:


# ./certbot-auto --help


certbot-auto [SUBCOMMAND] [options] [-d DOMAIN] [-d DOMAIN] ...


Certbot can obtain and install HTTPS/TLS/SSL certificates. By default,

it will attempt to use a webserver both for obtaining and installing the

certificate. The most common SUBCOMMANDS and flags are:


obtain, install, and renew certificates:

(default) run Obtain & install a certificate in your current webserver

certonly Obtain or renew a certificate, but do not install it

renew Renew all previously obtained certificates that are near expiry

-d DOMAINS Comma-separated list of domains to obtain a certificate for


--apache Use the Apache plugin for authentication & installation

--standalone Run a standalone webserver for authentication

--nginx Use the Nginx plugin for authentication & installation

--webroot Place files in a server's webroot folder for authentication

--manual Obtain certificates interactively, or using shell script hooks


-n Run non-interactively

--test-cert Obtain a test certificate from a staging server

--dry-run Test "renew" or "certonly" without saving any certificates to disk


manage certificates:

certificates Display information about certificates you have from Certbot

revoke Revoke a certificate (supply --cert-path)

delete Delete a certificate


manage your account with Let's Encrypt:

register Create a Let's Encrypt ACME account

--agree-tos Agree to the ACME server's Subscriber Agreement

-m EMAIL Email address for important account notifications


More detailed help:


-h, --help [TOPIC] print this message, or detailed help on a topic;

the available TOPICS are:


all, automation, commands, paths, security, testing, or any of the

subcommands or plugins (certonly, renew, install, register, nginx,

apache, standalone, webroot, etc.)



Предварительная настройка скрипта Let's Encrypt и сервера NGinx


Чтобы не писать каждый раз длинную строку из опций, а еще лучше — не вспоминать о них, основные настройки надо записать в файл конфигурации, который certbot-auto ожидает найти в файле /etc/letsencrypt/cli.ini. Нужно создать каталог /etc/letsencrypt и создать в нем файл cli.ini следующего содержания:


authenticator = webroot

webroot-path = /var/www/acmehtml

post-hook = service nginx reload

text = True


Где /var/www/acmehtml - это директория, через которую будет осуществляться протокол взаимодествия с API сервера Let's Encrypt (Да, эта директория не принадлежит ни одному сайту, которые крутятся на nginx. Это совершенно отдельная директория, которая только будет подключаться к каждому сайту.). Директива text = True отключает интерфейс ncurses, и заставляет работать скрипт просто в консольном режиме. Директива post-hook содержит команды, которые должны выполниться после успешной установки/смены сертификатов. Если нужно сделать несколько команд, то команды разделяются точкой с запятой.



Примечание:


Если вы видите такую ошибку:


letsencrypt: error: Unexpected line 14 in /etc/letsencrypt/cli.ini: post-hook = service nginx reload; service postfix reload


То вам нужно обновить python-configargparse. Ошибка была исправлена в 0.11.0.



Согласно настройкам в cli.ini, скрипт Let's Encrypt будет создавать сертификаты и файлы, необходимые для подтверждения прав на доменое имя, в каталоге:


/var/www/acmehtml/.well-known/acme-challenge


Файлы в этом каталоге должны быть доступны из сети. Вначале нужно создать этот каталог и тестовый файл:


mkdir -p /var/www/acmehtml/.well-known/acme-challenge

echo Success > /var/www/acmehtml/.well-known/acme-challenge/example.html


Далее, в каталоге /etc/nginx надо создать файл acme следующего содержания:


# File: /etc/nginx/acme

location /.well-known {

root /var/www/acmehtml;

}


и подключить этот файл в настроечных файлах сайтов, расположенных в каталоге /etc/nginx/sites-enabled. Для этого, в блоке server перед всеми блоками location нужно указать:


include acme;


Для применения изменений надо перезагрузить nginx:


# service nginx reload


После чего можно открыть в браузере ссылку:


mysite.ru/.well-known/acme-challenge/example.html


Если в ответе будет выдано Success, это значит, что файлы нормально доступны из Web, и можно продолжать настройку.


Если в ответе показывается ошибка 404, то можно проверить следующее. Возможно, что в конфигурации NGinx для сайта включено rewrite правило, которое искажает URI, включая URI c целью /.well-known. Это правило может выглядеть так:


if (!-e $request_filename) {

rewrite "^/(.*)$" /index.php?$1 last;

}


То есть, на сайте используется CMS, для работы которой подменяются адреса вида http://mysite.ru/news/125 на http://mysite.ru/index.php?news/125. Чтобы отменить такое преобразование для URI с целевым каталогом /.well-known, нужно перед таким if{...} прописать еще одно правило:


# Запрет редиректа .well-known

rewrite "^/\.well-known(.*)$" /.well-known$1 last;


Видимо, запрет редиректа делается как-то по другому, но разобраться как правильно не смог. Документация у nginx максимально непонятная.


После проверки возможности доступа через Web, тестовый файл example.html следует удалить, потому что такой файл будет мешать скрипту Let's Encrypt, о чем будет говорить сообщение об ошибке "Unable to clean up challenge directory".


Регистрация в системе Let's Encrypt


Регистрация происходит командой:


# ./certbot-auto register --email mysiteadmin@mail.ru


Где mysiteadmin@mail.ru - это email, который будет использоваться для дальнейших действий с аккаунтом Let's Encrypt. В процессе регистрации потребуется принять несколько соглашений.


После отработки скрипта появится подкаталог:


/etc/letsencrypt/accounts


в котором будут размещены данные, используемые при подключении к серверам Let's Encrypt.


На указанный емайл будет направлено сообщение со ссылкой, на которую надо перейти для подтверждения регистрации. На странице подтверждения будет следующий текст:


Welcome! You're confirmed!

Thanks for confirming you want to be on the EFF mailing list. You'll be getting occasional email messages from us. Remember: you can unsubscribe or change your email settings at any time.



Получение сертификатов Let's Encrypt


Для того, чтобы сервис Let's Encrypt не забивали непрекращающимся потоком запросов на сертификаты, в нем сделаны ограничения в частоте выдачи сертификатов на одно доменное имя. Для одного доменного имени возможно получение не более 20 сертификатов в неделю. Если какие-то настройки сделаны неправильно, то запросто можно превысить данный лимит, пока разбираешься что не так. Есть и другие ограничения.


Поэтому, перед запросом реальных сертификатов, надо сделать имитацию запроса сертификатов. Такой запрос делается командой:


# ./certbot-auto certonly --dry-run -d mysite.ru -d www.mysite.ru


Saving debug log to /var/log/letsencrypt/letsencrypt.log

Obtaining a new certificate

Performing the following challenges:

http-01 challenge for mysite.ru

http-01 challenge for www.mysite.ru

Using the webroot path /var/www/acmehtml for all unmatched domains.

Waiting for verification...

Cleaning up challenges

Running post-hook command: service nginx reload


IMPORTANT NOTES:

- The dry run was successful.


Если в последней строчке видна надпись "The dry run was successful", значит имитация прошла успешно, и можно получать настоящие сертификаты. Получение сертификатов выполняется командой:


# ./certbot-auto certonly -d mysite.ru -d www.mysite.ru


Saving debug log to /var/log/letsencrypt/letsencrypt.log

Obtaining a new certificate

Performing the following challenges:

http-01 challenge for mysite.ru

http-01 challenge for www.mysite.ru

Using the webroot path /var/www/acmehtml for all unmatched domains.

Waiting for verification...

Cleaning up challenges

Running post-hook command: service nginx reload


IMPORTANT NOTES:

- Congratulations! Your certificate and chain have been saved at

/etc/letsencrypt/live/mysite.ru/fullchain.pem. Your cert will

expire on 2017-10-02. To obtain a new or tweaked version of this

certificate in the future, simply run certbot-auto again. To

non-interactively renew *all* of your certificates, run

"certbot-auto renew"

- If you like Certbot, please consider supporting our work.


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


/etc/letsencrypt/live/mysite.ru/



Переключение NGinx на SSL и подключение полученных сертификатов


Для того, чтобы сайт заработал на протоколе HTTPS, нужно поменять настройки в конфиге nginx. Ниже дан кусок конфига nginx, в котором видны закомментированные настройки, используемые для HTTP, и новые настройки, включающие режим HTTPS:


server {

# Для протокола HTTP

# listen 80; # Порт для IPv4 (порт для IPv6 должен указываться только один раз, в следующей секции)

# server_name www.mysite.ru; # Имя сервера

# rewrite ^(.*) http://mysite.ru$1 permanent; # здесь при заходе на www.mysite.ru происходит редирект на mysite.ru


# Для протокола HTTPS

listen 80;

server_name mysite.ru;

return 301 https://$host$request_uri;

}


server {

# Для протокола HTTP

# listen 80 default_server; # Порт для IPv4

# listen [::]:80 default_server; # Порт для IPv6

# server_name mysite.ru; # Имя сервера


# Для протокола HTTPS

listen 443 ssl;

server_name mysite.ru www.mysite.ru;

ssl_certificate /etc/letsencrypt/live/mysite.ru/fullchain.pem;

ssl_certificate_key /etc/letsencrypt/live/mysite.ru/privkey.pem;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

ssl_prefer_server_ciphers on;

ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

...

}


Более подробную информацию следует искать в интернете. По сути, настройка веб-сервера nginx - это самая трудная часть процесса включения шифрования HTTPS.


После внесения правильных настроек, сервер nginx нужно перезапустить, и HTTPS должен сразу заработать.



Настройка автоматического продления сертификатов


Сертификат Let's Encrypt выдается на 90 дней. Ранее, по соображениям безопасности, сам сервис Let's Encrypt рекомендовал менять сертификаты два раза в день. Мы не будем так параноиться, и сделаем обновление сертификатов раз в месяц. Таким образом будет получен нахлест длинной в два месяца. Он нужен, чтобы успеть разобраться если что-то пошло не так, имея на крайний случай действующий сертификат.


Команда обновления сертификатов следующая:


/opt/letsencrypt/certbot-auto renew


Именно ее и нужно прописать в Cron. В принципе, эту команду, для пробы, можно запускать вручную. Поведение этой команды достаточно умное: если сертификаты новые, она не будет делать обновление:


Saving debug log to /var/log/letsencrypt/letsencrypt.log


--------------------------------------------------

Processing /etc/letsencrypt/renewal/mysite.ru.conf

--------------------------------------------------

Cert not yet due for renewal


The following certs are not due for renewal yet:

/etc/letsencrypt/live/mysite.ru/fullchain.pem (skipped)

No renewals were attempted.

No hooks were run.


После сработавшего обновления будет произведен перезапуск сервера nginx. Это прописано в опции post-hook в файле /etc/letsencrypt/renewal/mysite.ru.conf. Прописывание данной опции произошло потому, что ранее был настроен файл /etc/letsencrypt/cli.ini, в котором были указаны post-hook действия (см. раздел "Предварительная настройка скрипта Let's Encrypt и сервера NGinx").


Для сертификатов, которые были созданы в комплекте с несколькими доменами, есть одна тонкость: в консоли отображается только базовое имя домена, однако при продлении будут продлены все домены, включенные в этот сертификат.


В Debian Linux файлом настройки cron является /etc/crontab. Это не единственный конфиг cron, но мы будет пользоваться им, как самым классическим методом конфигурирования запуска заданий по расписанию. Для автообновления в режиме "раз в месяц" нужно прописать такую строку:


0 2 1 * * root /opt/letsencrypt/certbot-auto renew


Она означает: каждое первое число месяца, в 2:00 запускать автообновление сертификатов от пользователя root.


Всё, теперь веб-сервер использует шифрование TLS (SSL), и это бесплатно. Говорят, что перевод на протокол HTTPS повышает видимость сайтов в основных поисковиках. Использование Let's Encrypt позволяет на практике посмотреть, действительно ли это так.



Так же в этом разделе:
 
MyTetra Share v.0.44
Яндекс индекс цитирования