Установка, настройка NGINX+certbot на Alma Linux 8

установить yum-utils:

dnf install epel-release yum-utils wget nano

для добавления репозитория NGINX создать файл /etc/yum.repos.d/nginx.repo и заполнить:

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

установить NGINX:

dnf install nginx

запустить и добавить в автозапуск:

systemctl start nginx && systemctl enable nginx

добавить в Firewall:

firewall-cmd --zone=public --add-port=80/tcp --permanent && firewall-cmd --zone=public --add-port=443/tcp --permanent && firewall-cmd --reload

установка certbot для nginx

dnf install certbot python3-certbot-nginx

заполнить файл /etc/nginx/nginx.conf:

user  nginx;

# кол-во процессоров
worker_processes  2;

# Данная директива указывает сколько файловых дескрипторов будет использовать Nginx.
# На каждое соединение надо выделять по два дексриптора,
# даже для статических файлов (картинки/JS/CSS):
# один для соединения с клиентом,
# а второй — для открытия статического файла.
# Таким образом, значение worker_rlimit_nofile должно быть равным удвоенному значению Max Clients.
worker_rlimit_nofile 10240;

# Логирование:
# notice - все
# warn - предупреждения и критических ошибок
# crit - только критических ошибок
error_log  /var/log/nginx/error.log crit;

pid        /var/run/nginx.pid;


events {

    # Для обработки подключений Nginx поддерживает ряд методов.
    # Наиболее эффективным для Linux является метод epoll.
    use epoll;

    # Задаёт максимальное число соединений, которые одновременно может открыть рабочий процесс.
    # Следует иметь в виду, что в это число входят все соединения (в том числе, например, 
    # соединения с проксируемыми серверами), а не только соединения с клиентами.
    # не может превышать ограничения worker_rlimit_nofile
    worker_connections  10240;

}


http {

    # Подгрузка конфига со списком MIME типов
    include       /etc/nginx/mime.types;

    # MIME тип по умолчанию когда не известно
    # application/octet-stream - открывает в виде текста браузером
    # application/force-download - информирует браузер, что нужно файл качать
    default_type  application/force-download;

    # Формат логирования
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    # Путь к файлу логирования запросов
    access_log  /var/log/nginx/access.log  main;

    # Произвести редирект, если заходят на http с указанием порта 443 на https
    proxy_redirect ~^http://([^:]+):443(/.+)$ https://$1$2;
    # Максимальный размер загружаемых файлов
    client_max_body_size 20M;

    # Директива sendfile активирует копирование данных между файловыми дескрипторами
    # средствами ядра, что намного эффективнее связки read() + write(), которая
    # требует обмена данными с пользовательским пространством.
    sendfile			on;

    # После включения sendfile, можно заставить Nginx отправлять заголовки 
    # HTTP-ответов одним пакетом, а не отдельным частями.
    tcp_nopush			on;

    # Для keep-alive подключений можно выключить буферизацию (алгоритм Нейгла).
    # Это будет полезно при частом запросе маленьких объёмов данных в режиме
    # реального времени, без получения немедленного ответа, когда важна 
    # своевременная доставка данных. Классический пример — события наведения 
    # мышкой.
    tcp_nodelay			on;

    # Отвечает за максимальное время поддержания keepalive-соединения, 
    # в случае, если пользователь по нему ничего не запрашивает.
    # Для современных систем, стоит выставить от 30 до 50.
    keepalive_timeout  30;

    # Если клиент перестал читать страницу, Nginx будет сбрасывать соединение с ним.
    reset_timedout_connection on;

    # Ждет выставленное количество секунд тело запроса от клиента, после чего 
    # сбрасывает соединение. Таймаут задается только для периода между двумя 
    # последовательными операциями чтения, а не для передачи всего тела запроса. 
    # Если клиент ничего не передает в течение этого времени, запрос 
    # завершается с ошибкой 408 (Request Time-out). По умолчанию 60.
    client_body_timeout 10;

    # Если клиент прекратит чтение ответа, Nginx подождет выставленное 
    # количество секунд и сбросит соединение. По умолчанию 60.
    send_timeout 2;

    # Сжатие данных для MIME типов:
    # application/x-javascript
    # application/javascript
    # text/css
    # text/xml
    # text/plain
    # application/xml
    gzip				on;
	gzip_proxied			any;
	gzip_static			on;
	gzip_http_version		1.0;
    gzip_min_length 1000;
	gzip_types			application/x-javascript application/javascript text/css text/xml text/plain application/xml;
    gzip_disable "msie6";

    include /etc/nginx/vhost.conf;

}

заполнить файл /etc/nginx/vhost.conf:

# Хост по умолчанию.
# В таких хостах разполагаю сервисные скрипты.
server {

    # Какой интерфейс и порт слушать
    # 0.0.0.0 - все сетевые интерфейсы
    # default_server - указывает, что этот виртуальных хост будет по умолчанию
    listen 0.0.0.0:80 default_server;
    server_name  srv01.example.com;

    # Какой файл подгрузится если обратиться к директории
    index index.html index.htm;
    # корневая директория веб
    root /var/www/html;

}

проверяем конфиги nginx:

nginx -t

при успешной проверке будет выведен результат:

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

перечитываем конфигурацию nginx:

nginx -s reload

добавить домен и получить сетификат в certbot:

certbot --nginx -d srv01.example.com

сперва запрашивает email для уведомлений:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel):

затем нужно принять условия Let’s Encrypt:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

подписаться-ли на рассылку от Let’s Encrypt:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, 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 our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

при успешном применении сертификата будет примерно такой результат:

Account registered.
Requesting a certificate for srv01.example.com

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/srv01.example.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/srv01.example.com/privkey.pem
This certificate expires on 2024-06-19.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

Deploying certificate
Successfully deployed certificate for srv01.example.com to /etc/nginx/vhost.conf
Congratulations! You have successfully enabled HTTPS on https://srv01.example.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

добавить конфигурационный файл для подключения SSL /etc/nginx/conf.d/ssl.conf:

ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 144000m;
ssl_session_tickets off;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;

ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";

ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

поправить файл /etc/nginx/vhost.conf:

server {

    # Какой интерфейс и порт слушать
    # 0.0.0.0 - все сетевые интерфейсы
    # default_server - указывает, что этот виртуальных хост будет по умолчанию
    listen       0.0.0.0:80 default_server;
    server_name  srv01.example.com;

    # редирект с 80 порта на 443 который с сертификатом
    return 301 https://$host$request_uri;

    index index.html index.htm;
    root /var/www/html;

}

server {

    # ssl - SSL протокол
    # http2 - работать по протоеолу HTTP/2
    listen       0.0.0.0:443 ssl http2 default_server;
    server_name  srv01.example.com;

    include conf.d/ssl.conf;

    ssl_certificate /etc/letsencrypt/live/srv01.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/srv01.example.com/privkey.pem;

    index index.html index.htm;
    root /var/www/html;

}

добавить автопродление сертификатов в крон (каждые сутки в 5 утра):

0 5 * * * /usr/bin/certbot renew --quiet > /dev/null 2>&1

 

пример добавления получения сетификата домена + домена с www:

certbot --nginx -d example.com -d www.example.com

 

пример конфига с доменом + домен www (редиректим на домен без www):

server {

    listen       0.0.0.0:80 default_server;
    server_name  srv01.example.com;

    # редирект с 80 порта на 443 который с сертификатом
    return 301 https://$host$request_uri;

}

server {

    listen       0.0.0.0:443 ssl http2 default_server;
    server_name  srv01.example.com;

    include conf.d/ssl.conf;

    ssl_certificate /etc/letsencrypt/live/srv01.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/srv01.example.com/privkey.pem;

    index index.html index.htm;
    root /var/www/html;

}

server {

    listen       0.0.0.0:80 default_server;
    server_name  example.com www.example.com;

    return 301 https://$host$request_uri;

}

server {

    listen       0.0.0.0:443 ssl http2 default_server;
    server_name  example.com www.example.com;

    include conf.d/ssl.conf;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # проверяем что домен с www
    if ($host = www.example.com) {
        # редиректим на домен без www
        return 301 https://example.com$request_uri;
    }

    index index.html index.htm;
    root /var/www/html;

}

 

в ручном режиме обновить сертификаты:

certbot renew

 

посмотреть список сертификатов:

certbot certificates

пример результата:

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

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
  Certificate Name: srv01.example.com
    Serial Number: 3d56e240c2e846c017ef3041106f1833940
    Key Type: RSA
    Domains: srv01.example.com
    Expiry Date: 2024-07-13 10:43:39+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/srv01.example.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/srv01.example.com/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

 

удалить неиспользуемые сертификаты:

certbot delete --cert-name srv01.example.com