Назад | Перейти на главную страницу

Dockerized Nginx + Certbot + вызов tls-sni не работает при продлении

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

Я хотел добавить сертификаты SSL как для api, так и для веб-сайта. Итак, я использовал certbot/certbot docker container, чтобы сделать это без каких-либо проблем.

Я создал сертификаты, используя dns вызов, выполнив следующую команду (с моего локального компьютера):

docker run --rm -it \
  --name certbot \
  -v $(pwd)/letsencrypt:/etc/letsencrypt \
  certbot/certbot \
    certonly --manual -d api.mydomain.com --preferred-challenges dns --renew-by-default --email xxx@xxxx --agree-tos --manual-public-ip-logging-ok

Меня попросили ввести запись TXT dns для _acme-challenge.api.mydomain.com что я и сделал, и получил сертификаты без каких-либо проблем.

Затем я обновил конфигурацию Nginx (/etc/nginx/nginx.conf/api.conf):

upstream api {
  server node-api:5000 max_fails=3;
}

map $http_upgrade $connection_upgrade {
  default       "upgrade";
  ""            "";
}

# Force HTTPS
server {
  listen 80;
  server_name api.domain.com;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;
  server_name       api.domain.com;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_certificate   /etc/nginx/certificates/api.domain.com/fullchain.pem;
  ssl_certificate_key /etc/nginx/certificates/api.domain.com/privkey.pem;
  ssl_trusted_certificate /etc/nginx/certificates/api.domain.com/chain.pem;

  access_log /var/log/nginx/api-domain.access.log main;
  error_log  /var/log/nginx/api-domain.error.log error;

  location / {
    proxy_pass         http://api;
    proxy_redirect     off;

    proxy_set_header   Connection $connection_upgrade;
    proxy_set_header   Upgrade $http_upgrade;
    proxy_set_header   Host $host;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

И все хорошо, перезапустил мой сервер и теперь отлично работает с сертификатами letsencrypt! Потрясающие!


Эта проблема

А теперь проверка обновления сертификатов ... И вот неприятности. Сначала я просто попытался запустить renew --dry-run команда без особого успеха.

Попытка обновить сертификат (api.mydomain.com) с /etc/letsencrypt/renewal/api.mydomain.com.conf вызвала непредвиденную ошибку: ручной подключаемый модуль не работает; могут быть проблемы с вашей существующей конфигурацией. Ошибка была: PluginError ('Сценарий аутентификации должен быть предоставлен с --manual-auth-hook при неинтерактивном использовании подключаемого модуля вручную.',). Пропуская.

Итак, я пробовал использовать автономный вариант:

docker run --rm -it \
  --name certbot \
  -v $(pwd)/letsencrypt:/etc/letsencrypt \
  certbot/certbot \
    renew --dry-run --standalone --preferred-challenges dns

и получил эту ошибку:

Попытка обновить сертификат (api.mydomain.com) из /etc/letsencrypt/renewal/api.mydomain.com.conf вызвала непредвиденную ошибку: выбранный плагин не поддерживает ни одну из предпочтительных задач. Пропуская.

Итак, я вычитаю, что не могу использовать dns проблемы для продления сертификата, достаточно справедливые.

Давай попробуем с tls-sni что Nginx поддерживает (я проверил, он включен)

docker run --rm -it \
  --name certbot \
  -v $(pwd)/letsencrypt:/etc/letsencrypt \
  certbot/certbot \
    renew --dry-run --standalone --preferred-challenges tls-sni

И теперь у меня такая ошибка:

Попытка обновить сертификат (api.mydomain.com) с /etc/letsencrypt/renewal/api.mydomain.com.conf вызвала непредвиденную ошибку: Неудачная процедура авторизации. api.mydomain.com (tls-sni-01): urn: acme: error: unauthorized :: У клиента нет достаточной авторизации :: Неверный сертификат проверки для вызова tls-sni-01. Запрошен e0fd03ddade6d902d5947028985253ba.63b177f317335bf9297f0bb963135fee.acme.invalid с 13.210.106.2:443. Получено 2 сертификата (ов), первый сертификат имел имена «api.mydomain.com». Пропуская.

Мне интересно, нужно ли мне включать что-то конкретное на стороне Nginx, например OCSP, ssl_stapling или ssl_dhparam

Я также заметил, что если я пытаюсь повторно запустить certonly на другом сервере, чем я получил сертификаты, dns значение задачи не то же самое.


Итак, у меня есть 2 вопроса:

Заранее большое спасибо

Спасибо maxwell2022! Вот как выглядит мое окончательное решение, основанное на вашем ответе. Проверено на CentOS 7. Я вручную создал каталог / etc / letsencrypt / acme-challenge.

Серверный блок NGINX

server {
    listen 80;
    server_name MY_DOMAIN;

    location /.well-known/acme-challenge/ {
        root /etc/letsencrypt/acme-challenge;
    }
}

Создать сертификат

docker run -it --rm --name certbot -v /etc/letsencrypt:/etc/letsencrypt -v /var/lib/letsencrypt:/var/lib/letsencrypt certbot/certbot certonly --webroot -w /etc/letsencrypt/acme-challenge/ --domain MY_DOMAIN --agree-tos --email MY_EMAIL

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

docker run -it --rm --name certbot -v /etc/letsencrypt:/etc/letsencrypt -v /var/lib/letsencrypt:/var/lib/letsencrypt certbot/certbot renew --webroot -w /etc/letsencrypt/acme-challenge/
docker kill --signal=HUP proxy

На ServerFault не так много активности, поэтому вот ответ:

https://github.com/certbot/certbot/issues/5252#issuecomment-346500852

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

Проблемы TLS-SNI постепенно устраняются, поскольку они небезопасны для многих распространенных хостинговых платформ. Если вы в настоящее время полагаетесь на сертификаты, выпущенные таким образом, вам нужно будет перейти на запросы на основе HTTP или DNS.