Получим и настроим автоматическое обновление бесплатного сертификата SSL для сайта от компании Lets`Encrypt. Срок сертификата 90 дней. Настроить получение сертификатов возможно на любой операционной системе Linux. Стабильная и удобная работа с сервисом.
Содержание:
Введение
С января 2017 года Firefox и Chrome маркируют как надежные только сайты с SSL-сертификатами. Это одна из причин по которой следует использовать этот сертификат.
Если коротко, то это защита сайта которая многим не нужна, но введение некоторых ограничений заставляет использовать её. Хорошо что есть ресурсы которые предоставляют сертификаты бесплатно, сколько времени еще так будет не известно, но мы пока попользуемся.
Мной было найдено два ресурса выдающие бесплатные SSL для сайтов:
- StartCom — у этого ресурса проблемы с разработчиками браузеров и чем все это закончится не понятно. Удобно что выдается на 3 года и можно установить на любой обычный хостинг.
- Let’s Encrypt is — все работает и никаких проблем нет. Для установки нужен свой VDS хостинг. Хоть сертификат и выдается на 90 дней, но при настройке автоматического обновления никаких проблем не возникает.
Мой выбор однозначно пал на второй вариант, так как стабильность и понятность для меня самое важное.
Подробно про установку и начальную настройку сервера вы можете узнать в моей статье Rocky Linux 8 установка и настройка.
Установка Certbot от Let’s Encrypt
На сайте компании есть инструкция об установке и использованию. По ссылке вы можете увидеть инструкцию для установки SSL на Nginx под управлением CentOS 8 = Rocky Linux 8. Можете указать свои системы и получить инструкцию для них.
Разработчик рекомендует использовать пакетную систему Snap. Ее смысл заключается в том, что в пакет с приложением входит полный набор компонентов, необходимых для запуска данного приложения. Такие пакеты можно устанавливать в систему не заботясь о зависимостях, так как все зависимости уже включены в пакет. Пакетная система Snap была созданная компанией Canonical и изначально появилась в дистрибутиве Ubuntu Linux.
При установке на дистрибутивы которые используют не стабильные репозитории это очень оправдано и понятно почему. В нашем случае устанавливать в таком виде не имеет смысла. Лично у меня на протяжении лет 5 проблем не возникало.
Для использования Certbot, необходимо сначала добавить репозиторий Epel . Подключим необходимый репозиторий:
dnf -y install epel-release
Установим без вопросов Certbot от Let’s Encrypt:
yum -y install certbot
Предварительная подготовка
Предварительная подготовка заключается в выполнении двух действий:
- Ответы на вопросы от разработчика;
- Вносим необходимые настройки в конфигурацию Nginx.
Подробно про установку и начальную настройку сервера вы можете узнать в моей статье NGINX установка и настройка.
Ответы на вопросы от разработчика
Запускаем получение сертификата, но получать его не будем. Необходимо ответить на несколько вопросов от разработчика:
certbot certonly = вывод команды = Saving debug log to /var/log/letsencrypt/letsencrypt.log How would you like to authenticate with the ACME CA? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: Spin up a temporary webserver (standalone) 2: Place files in webroot directory (webroot) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2 Enter email address (used for urgent renewal and security notices) = в случае проблем с получением сертификата на эту почту будут приходить сообщения = = можно указать выдуманный = (Enter 'c' to cancel): info@sevo44.ru - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must agree in order to register with the ACME server. Do you agree? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - = подтверждаем что ознакомились с условиями предоставления услуг = (Y)es/(N)o: Y - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - = Просят поделиться своим адресом электронной почты с Фондом Electronic Frontier, партнером-основателем проекта Let's Encrypt и некоммерческой организацией, которая разрабатывает Certbot. Отказываюсь. = (Y)es/(N)o: N Account registered. = Выходим по Ctrl + C =
В данном примере есть два варианта получения сертификата. Расскажу грубо о каждом варианте и поясню разницу:
- Spin up a temporary webserver (standalone) — при таком варианте сертификат будет получен с использованием тестового сервера разработчика. Этот вариант подходит при условии что сайт уже где то работает и нам его надо перенести. После переезда нам надо заходить в настройки получения сертификата и менять параметры. Мне такой вариант не нравится и ниже вы узнаете почему;
- Place files in webroot directory (webroot) — при этом варианте сервис проверяет доступ к серверу и если он есть выдает сертификат. Основное преимущество данного вида в том что мне не надо в последствии править настройки получения сертификата. Достаточно с работающего сервера взять действующие сертификаты положить их в свое место и прописать пути в настройках Nginx. После реального переезда сайта достаточно получить сертификаты и указать в настройках Nginx новые пути.
Вносим необходимые настройки в конфигурацию Nginx
В конфигурации Nginx для сайта должны быть добавлены следующие строки:
location /.well-known/acme-challenge/ { root /etc/nginx/cert-renewal/; }
Создадим необходимую папку:
mkdir /etc/nginx/cert-renewal/
Можно для каждого сайта указывать свою директорию, но мне это не нравится. Предпочитаю делать общую.
При настройке Nginx для работы сайтов с использованием сертификатов есть два варианта:
- Внести все основные настройки для работы сайта с сертификатом в главный файл настройки Nginx а в настройках для самого сайта указывать только пути для сертификата;
- Не трогать главный файл и все настройки прописывать в настройках для сайта.
Лично я предпочитаю первый вариант и именно он будет описан ниже.
Вот пример моего файла настроек главного конфигурационного файла Nginx:
cat /etc/nginx/nginx.conf = вывод команды = user nginx; worker_processes auto; worker_cpu_affinity auto; worker_rlimit_nofile 30000; pid /var/run/nginx.pid; pcre_jit on; events { worker_connections 8192; multi_accept on; } http { # Basic ####################### sendfile on; tcp_nopush on; tcp_nodelay on; reset_timedout_connection on; keepalive_timeout 120; keepalive_requests 1000; types_hash_max_size 2048; server_tokens off; send_timeout 30; client_body_timeout 30; client_header_timeout 30; server_names_hash_max_size 4096; # Limits ###################### client_max_body_size 10m; client_body_buffer_size 128k; client_body_temp_path /var/cache/nginx/client_temp; proxy_connect_timeout 60; proxy_send_timeout 60; proxy_read_timeout 60; proxy_buffer_size 4k; proxy_buffers 8 16k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; proxy_temp_path /var/cache/nginx/proxy_temp; include /etc/nginx/mime.types; default_type application/octet-stream; # Logs ######################## log_format main '$remote_addr - $host [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"' 'rt=$request_time ut=$upstream_response_time ' 'cs=$upstream_cache_status'; log_format full '$remote_addr - $host [$time_local] "$request" ' 'request_length=$request_length ' 'status=$status bytes_sent=$bytes_sent ' 'body_bytes_sent=$body_bytes_sent ' 'referer=$http_referer ' 'user_agent="$http_user_agent" ' 'upstream_status=$upstream_status ' 'request_time=$request_time ' 'upstream_response_time=$upstream_response_time ' 'upstream_connect_time=$upstream_connect_time ' 'upstream_header_time=$upstream_header_time'; access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log; # Gzip ######################## gzip on; gzip_static on; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/x-icon image/svg+xml application/x-font-ttf; gzip_comp_level 9; gzip_proxied any; gzip_min_length 1000; gzip_disable "msie6"; gzip_vary on; etag off; # Cache ####################### #proxy_cache_valid 1m; #proxy_cache_key $scheme$proxy_host$request_uri$cookie_US; #proxy_cache_path /web/sites/nginx_cache levels=1:2 keys_zone=main:1000m; # Zone limits ################ limit_conn_zone $binary_remote_addr zone=perip:10m; limit_req_zone $binary_remote_addr zone=lim_5r:10m rate=5r/s; # lim for dynamic page limit_req_zone $binary_remote_addr zone=lim_1r:10m rate=1r/s; # lim for search page limit_req_zone $binary_remote_addr zone=lim_10r:10m rate=10r/s; # SSL ######################### ssl_session_cache shared:SSL:50m; ssl_session_timeout 1d; ssl_session_tickets on; ssl_protocols TLSv1.2 TLSv1.3; #ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers 'TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-256-GCM-SHA384:ECDHE:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; ssl_prefer_server_ciphers on; ssl_dhparam /etc/ssl/certs/dhparam.pem; ssl_stapling on; ssl_stapling_verify on; add_header Strict-Transport-Security max-age=15768000; resolver 8.8.8.8; include /etc/nginx/conf.d/*.conf; # For monitoring ########### server { listen 127.0.0.1:80; server_name status.localhost; keepalive_timeout 0; allow 127.0.0.1; deny all; access_log off; location /server-status { stub_status on; } location /status { access_log off; allow 127.0.0.1; deny all; include fastcgi_params; fastcgi_pass unix:/run/php-fpm/www.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } } }
В случае отсутствия /etc/ssl/certs/dhparam.pem генерируем ключ необходимый для настройки:
openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Процесс не быстрый. Ждите.
Получение бесплатного SSL-сертификата
Приведем к такому виду файл конфигурации сайта перед получением сертификата:
### ssl sevo44.ru #server { #listen 80; #server_name sevo44.ru; #return 301 https://$server_name$request_uri; # редирект обычных запросов на https #} server { #listen 443 ssl http2; listen 80; server_name sevo44.ru; ### ssl #ssl_certificate /etc/letsencrypt/live/sevo44.ru/fullchain.pem; #ssl_certificate_key /etc/letsencrypt/live/sevo44.ru/privkey.pem; location /.well-known/acme-challenge/ { root /etc/nginx/cert-renewal/; } location / { proxy_pass http://192.168.0.112:80; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #client_max_body_size 10m; #client_body_buffer_size 128k; proxy_connect_timeout 90; proxy_send_timeout 6000; proxy_read_timeout 6000; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } }
В этом файле два блока server. Первый отвечающий за работы http мы закомментировали, второй отвечающий за https перевели на работу по http и закомментировали пути к сертификату.
Обязательно проверяем правильность настроек 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 -s reload
Все предварительные подготовки сделаны. Переходим к непосредственному получению сертификата.
Не знаю какие ограничения на установку, но я спокойно установил SSL сертификат на домен и 5 его поддоменов.
Пример получения сертификата SSL:
certbot certonly = вывод команды с действиями = Saving debug log to /var/log/letsencrypt/letsencrypt.log How would you like to authenticate with the ACME CA? ------------------------------------------------------------------------------- 1: Spin up a temporary webserver (standalone) 2: Place files in webroot directory (webroot) ------------------------------------------------------------------------------- Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2 Please enter in your domain name(s) (comma and/or space separated) (Enter 'c' to cancel):sevo44.ru Requesting a certificate for sevo44.ru Input the webroot for sevo44.ru: (Enter 'c' to cancel):/etc/nginx/cert-renewal Waiting for verification... Cleaning up challenges Generating key (2048 bits): /etc/letsencrypt/keys/0014_key-certbot.pem Creating CSR: /etc/letsencrypt/csr/0014_csr-certbot.pem IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/sevo44.ru/fullchain.pem. Your cert will expire on 2021-12-14. 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 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
Сертификат успешно получен и указан период его действия.
Получение одного сертификата на домен с WWW и без
При попытке зайти по ссылке https://www.sevo44.ru мы получим сообщение об ошибке сертификата:
curl -I https://www.sevo44.ru
= вывод команды =
curl: (51) SSL: no alternative certificate subject name matches target host name 'www.sevo44.ru'
В настройках DNS для домена обязательно должен быть прописаны параметры его работы по адресу www.sevo44.ru!
Для исправление этой ошибки необходимо получить сертификат на домен с www и без.
Команда выглядит следующим образом:
certbot certonly --webroot --expand -d sevo44.ru -d www.sevo44.ru
Где параметры имеют следующие значения:
- certbot certonly — команда на получение сертификата;
- webroot — способ получения сертификата;
- expand — ключ для получения на один сертификат несколько доменов.
После успешного получения выполняется проверка следующей командой:
curl -I https://www.sevo44.ru
= вывод команды =
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Tue, 06 Aug 2019 20:26:56 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/7.2.20
Vary: Accept-Encoding, Cookie
X-Redirect-By: WordPress
Location: https://sevo44.ru/
Ошибок больше нет.
Установка SSL-сертификата на сайт c Nginx
Вся установка сертификата на сайте под управлением Nginx заключается в правке файла настройки виртуального хоста.
Все полученные сертификаты будут лежать в папке /etc/letsencrypt/live/ согласно доменным именам вводимым при получении.
Приведем к такому виду файл конфигурации сайта после получением сертификата:
### ssl sevo44.ru
server {
listen 80;
server_name sevo44.ru;
return 301 https://$server_name$request_uri; # редирект обычных запросов на https
}
server {
listen 443 ssl http2;
#listen 80;
server_name sevo44.ru;
### ssl
ssl_certificate /etc/letsencrypt/live/sevo44.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sevo44.ru/privkey.pem;
location /.well-known/acme-challenge/ {
root /etc/nginx/cert-renewal/;
}
location / {
proxy_pass http://192.168.0.112:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#client_max_body_size 10m;
#client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 6000;
proxy_read_timeout 6000;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}
Мы разкоментировали все строчки что ранее закомментировали и переключили второй блок на работу по https с указанием путей к сертификатам. Как вы заметил http2 протокол включается простым добавлением этой записи.
Сделаем проверку настроек и обновим настройки Nginx:
nginx -t
nginx -s reload
Ресурсы проверки SSL и Http2 сайта
Проверим сторонними ресурсами как установился наш SSL-сертификат.
- SSLChecker — cервис проверки настройки SSL,
- SSLReport — сервис проверки SSL но более детальный.
Проверим работу http2 протокола:
- HTTP/2 Test — сервис показывающий проверяющий работу http2.
Продление SSL-сертификата
Есть возможность производить обновления в ручную и в автоматическом режиме.
Ручной режим
Проверим автоматическое продление сертификатов, выполнив эту команду:
certbot renew --dry-run = вывод команды = Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Processing /etc/letsencrypt/renewal/sevo44.ru.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cert not due for renewal, but simulating renewal for dry run Plugins selected: Authenticator webroot, Installer None Simulating renewal of an existing certificate for sevo44.ru Performing the following challenges: http-01 challenge for sevo44.ru Waiting for verification... Cleaning up challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - new certificate deployed without reload, fullchain is /etc/letsencrypt/live/sevo44.ru/fullchain.pem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/sevo44.ru/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Видим что все хорошо.
Для обновления всех сертификатов достаточно запустить команду:
certbot renew = вывод команды = Saving debug log to /var/log/letsencrypt/letsencrypt.log ------------------------------------------------------------------------------- Processing /etc/letsencrypt/renewal/sevo44.ru.conf ------------------------------------------------------------------------------- Cert not yet due for renewal The following certs are not due for renewal yet: /etc/letsencrypt/live/sevo44.ru/fullchain.pem (skipped) No renewals were attempted.
Обновлять ничего.
Автоматический режим
Для автоматического обновления нам необходимо добавить параметры в crontab:
vim /etc/crontab = необходимое варианты добавление = # Cert Renewal # запись в лог файл 30 2 0 * * root /usr/bin/certbot renew --post-hook "nginx -s reload" >> /var/log/letsencrypt/cron-renew.log === или === # без записи в лог файл 30 2 0 * * root /usr/bin/certbot renew --post-hook "nginx -s reload" >> /dev/null 2>&1
Согласно этой настройке команда будет выполняться по воскресеньям в 2:30 после выполнения произойдёт reload nginx.
Удаление сертификата
Удаление сертификата состоит из двух частей:
- Аннулирование сертификатов на серверах Let`s Enscrypt;
- Удаление сертификатов на сервере.
Аннулируем сертификат:
certbot revoke --cert-path /etc/letsencrypt/archive/sevo44.ru/cert1.pem = вывод команды = Saving debug log to /var/log/letsencrypt/letsencrypt.log An unexpected error occurred: The client lacks sufficient authorization :: Certificate is expired Please see the logfiles in /var/log/letsencrypt for more details.
В выводе говориться что сертификат просрочен и удалять нечего.
Удалим сертификат на сервере:
certbot delete --cert-name sevo44.ru = вывод команды = Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The following certificate(s) are selected for deletion: * sevo44.ru Are you sure you want to delete the above certificate(s)? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: Y - подтверждаем удаление Deleted all files relating to certificate sevo44.ru.
Принудительное обновление сертификата
Бывает ситуации когда надо принудительно обновить сертификат по разным причинам.
Вот варианты команд которые можно использовать:
= Для принудительного обновления всех сертификатов = certbot --force-renewal = Выборочное принудительное обновление сертификатов = = через запятую указываются все необходимые доменные имена = certbot --force-renewal -d www.itsecforu.ru,itsecforu.ru
Заключение
Не сразу я пришел к такому механизму настройки получения сертификатов. Мне кажется такой вариант удобен и понятен. Использую эту инструкцию на рабочих серверах. Проблем с автоматическим обновлением сертификатов и программы не возникало.
Если захочется посмотреть более подробно инструкцию выполните команду:
certbot --help certbot --help all
certbot --help all | grep -i force
certbot --help all | egrep -i 'renewal|force'
Получить сертификат без реального домена и в dns сделанной записи «А» невозможно?
Не могу сказать. В практике такое не использую.
Здравствуйте. У меня такой вопрос. Стоит отдельный сервер с NGINX на него со шлюза перенаправляю запросы на 80 и 443 порты. За NGINX крутятся виртуалки с чатом mattermost, облаком nextcloud и web сервер с joomla. Как лучше сделать сертификаты? Можно инструкцию или ссылку?
Вот тут найдете ответы.
Здравствуйте, Алексей! Есть небольшой вопрос: при получении сертификата нужно отдельно указывать домен с www и без www ? Если не указать домен с www (при условии что он реально создан и работает — в dns есть запись «A» для него), разный защитный софт, типа антивирусов, которые прогоняют весь трафик через себя, могут ругаться что сертификат недействительный.
Допускаю, что его нужно где-то тоже указать или использовать редирект как-то по-другому, но как.?
Пример того, что имею ввиду (на примере Вашего сайта): https://cdn1.savepice.ru/uploads/2019/8/4/f6c7d0aba63a2fa5a13d68b5d9fda520-full.jpg
Такого, по идее, быть не должно. Сам думаю что это именно из-за того, что сертификат на www есть и получен он отдельно от основного, т.е. отличается в конфиге и при этом нигде не указан в nginx. (Могу ошибаться).
Буду благодарен, если подскажите, как это дело корректно «разрулить». 99% что рядовой пользователь увидев подобную портянку закроет вкладку и пойдёт искать инфу далее.
С http если вводить что с www что без стоит редирект на https://sevo44.ru
Ошибка сертификата получается если в браузере набрать конкретно https://www.sevo44.ru
Вариантов решения несколько как все попробую отпишу тут и откорректирую статью.
Ок.! Ещё сразу бы тогда для статьи по этой же теме дополнить инфу по поводу запроса сайта по ip адресу. Моё мнение — должен быть заблокирован переход или отдавать код 444. Для http проблем нет. Беда в том, что для https всегда будет ругань браузера на сертификат, а отдельно на ip от Lets`Encrypt сертификат не получить вроде бы. В любом случае было бы интересно посмотреть на Ваш подход в реализации.
Спасибо за обратную связь!.
Информацию в статью как получить один сертификат для домена с www и без добавил.
По поводу запроса по ip. Считаю бессмысленным все эти манипуляции с «прятками». Реальной безопасности они не дают и убеждался в этом не раз. Один раз как то настроил все эти блокировки скрытия и был очень удивлен когда какая то программа хакерская вывела мне всю информацию.
Лучшее решение по безопасности это своевременное обновление и правильный мониторинг.
Спасибо! Все доходчиво
Пожалуйста. Рад что получается писать понятным языком.