Table of Contents

SSL сертификаты Letsencrypt

Letsencrypt это открытый CA (Certificate Authority) который выдает бесплатные SSL сертификаты. Сертификаты выдаются сроком на 3 месяца, есть обвязка которая помогает получить сертификат и автоматически обновлять его по мере необходимости. Проект поддерживают много крупных сетевых контор.

Сайт проекта - https://letsencrypt.org/
Клиент letsencrypt - https://certbot.eff.org/
Документация - https://certbot.eff.org/docs/

Получение сертификата

Ubuntu 20.04 + Nginx + Certbot

QuickStart - https://certbot.eff.org/lets-encrypt/ubuntufocal-nginx

Считаем, что у нас есть настроенный nginx, который работает в качестве фронтенда для наших сайтов и сервисов.
Получать сертификат будет с помощью модуля webroot.

Ставим Certbot.

# apt install certbot python3-certbot-nginx

Создаем папку для временных файлов модуля webroot.

# mkdir /var/www/acme

Проднастраиваем nginx.
Пишем include инструкцию, что делать с http запросами вида “/.well-known/acme-challenge/*”.
Запросы будут обрабатываться в директории /var/www/acme.

# cat /etc/nginx/includes/acme

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

Пишем правила дефолтного “сайта” nginx и подключаем там include acme.
Такой конфиг позволит получить сертификат даже для сайта, который ещё не работает.

# cat /etc/nginx/sites-available/default
server {
	listen 80 default;

	include includes/acme;

	location / { return 444; } 

}

Включаем defaut и перезапускаем nginx.

# cd /etc/nginx/sites-enabled/
# ln -s /etc/nginx/sites-available/default default
# ll
..
lrwxrwxrwx 1 root root   34 Aug 13 12:52 default -> /etc/nginx/sites-available/default
..
# systemctl restart nginx

Получаем сертификат.
Сначала, с помощью опции dry-run, проверяем, что все хорошо.

# letsencrypt certonly -n --webroot -w /var/www/acme/ -d site.companyname.xyz --agree-tos --email info@companyname.xyz --dry-run

После получаем.

# letsencrypt certonly -n --webroot -w /var/www/acme/ -d site.companyname.xyz --agree-tos --email info@companyname.xyz

Подключаем полученный сертификат.

server {
    listen 443 ssl; 
    server_name  site.companyname.xyz;
    root         /var/www/site.companyname.xyz/;

    ssl_certificate /etc/letsencrypt/live/site.companyname.xyz/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/site.companyname.xyz/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

Перезапускаем nginx, должно работать.

Centos 7 + Apache + Certbot

QuickStart - https://certbot.eff.org/#centosrhel7-apache

Ставим LE клиента

[root@fry ~]# yum search certbot
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirror.yandex.ru
 * epel: epel.mirror.far.fi
 * extras: mirror.corbina.net
 * updates: mirror.corbina.net
============================================================================================ N/S matched: certbot =============================================================================================
python2-certbot.noarch : Python 2 libraries used by certbot
python2-certbot-apache.noarch : The apache plugin for certbot
python2-certbot-nginx.noarch : The nginx plugin for certbot
certbot.noarch : A free, automated certificate authority client

  Name and summary matches only, use "search all" for everything.
[root@fry ~]# yum install python2-certbot-apache
...

Запрашиваем сертификат в режиме standalone (надо на время руками погасить apache).

[root@fry ~]# systemctl stop httpd 
[root@fry ~]# systemctl status httpd 
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: man:httpd(8)
           man:apachectl(8)


[root@fry ~]# certbot certonly --standalone -d name.domain.com --email name@domain.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org

-------------------------------------------------------------------------------
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf. You must agree
in order to register with the ACME server at
https://acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(A)gree/(C)ancel: A

-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o: N
Obtaining a new certificate
Performing the following challenges:
tls-sni-01 challenge for name.domain.com
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/name.domain.com/fullchain.pem. Your cert
   will expire on 2017-09-12. 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"
 - 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

Сертификат будет лежать в /etc/letsencrypt/

[root@fry name.domain.com]# pwd
/etc/letsencrypt/live/name.domain.com
[root@fry name.domain.com]# ll
total 4
lrwxrwxrwx 1 root root  40 Jun 14 23:31 cert.pem -> ../../archive/name.domain.com/cert1.pem
lrwxrwxrwx 1 root root  41 Jun 14 23:31 chain.pem -> ../../archive/name.domain.com/chain1.pem
lrwxrwxrwx 1 root root  45 Jun 14 23:31 fullchain.pem -> ../../archive/name.domain.com/fullchain1.pem
lrwxrwxrwx 1 root root  43 Jun 14 23:31 privkey.pem -> ../../archive/name.domain.com/privkey1.pem
-rw-r--r-- 1 root root 543 Jun 14 23:31 README

Прописываем сертификат в настройках apache.

[root@fry conf.d]# cat vhosts.conf
NameVirtualHost *:443
...
<VirtualHost *:443>
...
	#####
	SSLEngine on
	SSLCertificateKeyFile /etc/letsencrypt/live/name.domain.com/privkey.pem
	SSLCertificateFile /etc/letsencrypt/live/name.domain.com/cert.pem
	SSLCertificateChainFile /etc/letsencrypt/live/name.domain.com/chain.pem
	####
...
</VirtualHost>

Перезапускаем apache, должно работать.


Продление сертификата

Продлить сертификат можно не ранее черем за 30 дней до срока окончания его действия.
Проверить срок действия можно командой “certbot certificates”.

[root@fry letsencrypt]# certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Found the following certs:
  Certificate Name: name.domain.com
    Domains: name.domain.com
    Expiry Date: 2017-09-12 19:31:00+00:00 (VALID: 85 days)
    Certificate Path: /etc/letsencrypt/live/name.domain.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/name.domain.com/privkey.pem
-------------------------------------------------------------------------------

Продление без остановки веб-сервера

Certbot по кропу запускается два раза в сутки.

# cat /etc/cron.d/certbot

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

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

Правим настройки certbot, меняем дефолтную директорию для хранения временных файлов webroot.

# cat /etc/letsencrypt/cli.ini
...
webroot-path = /var/www/acme
...

В http секцию сайта дописываем include acme.

server {
    listen       80;
    server_name  mykb.ru;
    
    include includes/acme;
    
    location / {
	return 301 https://$host$request_uri;
    }
}

Перезапускаем nginx, должно работать.

Centos 7, продление с остановкой веб-сервера

Для продления сертификата точно так же надо останавливать веб-сервер.
Остановить и запустить сервер можно автоматически (через ключи –pre-hook и –post-hook) или руками.

Перед продлением можно запустить проццесс в тестором режиме, для этого используем ключ –dry-run.

[root@fry letsencrypt]# certbot renew --pre-hook "systemctl stop httpd" --post-hook "systemctl start httpd" --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/name.domain.com.conf
-------------------------------------------------------------------------------
Cert not due for renewal, but simulating renewal for dry run
Starting new HTTPS connection (1): acme-staging.api.letsencrypt.org
Running pre-hook command: systemctl stop httpd
Renewing an existing certificate
Performing the following challenges:
tls-sni-01 challenge for name.domain.com
Waiting for verification...
Cleaning up challenges

-------------------------------------------------------------------------------
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/name.domain.com/fullchain.pem
-------------------------------------------------------------------------------
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/name.domain.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
Running post-hook command: systemctl start httpd

Добавляем правило в crontab, проверяем один раз в неделю.

[root@leela letsencrypt]# crontab -l
...
#Try renew ssl cert
7 23 6 * * /usr/bin/certbot renew --pre-hook "systemctl stop httpd" --post-hook "systemctl start httpd"
...

Centos 6

В Centos 6 вроде можно не останавливать веб-сервер.
Запускаем тестовое продление.

[root@fry1 ~]# certbot-auto renew --dry-run
/root/.local/share/letsencrypt/lib/python2.6/site-packages/cryptography/__init__.py:26: DeprecationWarning: Python 2.6 is no longer supported by the Python core team, please upgrade your Python. A future version of cryptography will drop support for Python 2.6
  DeprecationWarning
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/name1.domain.com
-------------------------------------------------------------------------------
Cert not due for renewal, but simulating renewal for dry run
Renewing an existing certificate
Performing the following challenges:
tls-sni-01 challenge for name1.domain.com
Waiting for verification...
Cleaning up challenges

-------------------------------------------------------------------------------
new certificate deployed with reload of apache server; fullchain is
/etc/letsencrypt/live/name1.domain.com/fullchain.pem
-------------------------------------------------------------------------------
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/name1.domain.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)

Если все хорошо, то добавляем правило в crontab, запускаем раз в неделю.

[root@fry1 ~]# crontab -l
..
#Try renew ssl cert
6 18 6 * * /root/bin/certbot-auto renew
...

Полезные ссылки