Директива acme не работает с переменной $

resolver 8.8.8.8 1.1.1.1
acme_client hkrr https://acme-v02.api.letsencrypt.org/directory;

server {

set $acmesrv hkrr;

acme $acmesrv;

}

angie -t
angie: [emerg] no valid domain name defined for ACME client “hkrr” in /etc/angie/http.d/sitename.conf:6
angie: configuration file /etc/angie/angie.conf test failed

Ошибку при этом показывает в строке с директивой acme_client. Что наводит на мысль что проблема в ней.

dig, ping, netcat, curl с acme-v02.api.letsencrypt.org - ok

Хотя на самом деле директива acme не принимает аргумент в виде переменной. И если в ней указать название плагина, а не переменную - ошибка исчезает.

И если задать “server_name $srvname”, то в логе будет ошибка
[error] 26342#26342: *197 ACME server error message: Error creating new order :: Cannot issue for “$srvname”: Domain name contains an invalid character

В nginx в принципе и в Angie в том числе, директивы поддерживают указание переменных только если это явно прописано в документации. По умолчанию директивы переменные не поддерживают.

В директивах, которые переменные не поддерживают, знак $ является обычным символом и интерпретируется как обычный символ, т.е. клиент в принципе может иметь название $acmesrv. Это справедливо абсолютно для всех директив nginx, так работает его парсер.

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

  • для клиента с названием hkrr не указано ни одного домена
  • клиента с названием $acmesrv не существует в конфигурации

В процессе парсинга конфигурации выдается только одна ошибка, первая обнаруженная, которая привела к невозможности дальше продолжать работу. Если её исправить, то дальше будет следующая ошибка.

Директива acme в принципе никак не может работать с переменными, т.к. переменные существуют только в контексте запроса от клиента, а получение сертификата осуществляется асинхронно, без привязки к какому-либо запросу.

Более того, директива set - является командой rewrite-модуля и работает в фазе обработки виртуального сервера, т.е. уже после того, как запрос начал обрабатываться, TLS-хеншейк произошел, сертификат был предоставлен. Данная конструкция, даже если бы директива acme каким-то образом поддерживала переменные - все равно не могла бы работать корректно.

И если задать “server_name $srvname”, то в логе будет ошибка
[error] 26342#26342: *197 ACME server error message: Error creating new order :: Cannot issue for “$srvname”: Domain name contains an invalid character

Директива server_name также не поддерживает переменных и точно также интерпретирует $srvname как имя домена.

Т.е. данный сервер будет выбран в случае отправки заголовка: Host: $srvname. У nginx, опять же, в этом месте никаких специальных проверок нет, предполагается, что если пользователь так написал, то так нужно.

Есть где нибудь howto как настроить этот acme модуль на примере какого нить сайта ?

Спасибо за разъяснения. Ключевой информацией стало что не все директивы поддерживают переменные - не знал.

При отладке конфига запутало и съело время то, что парсер указал местом ошибки Номер строки с декларацией acme_client и такой текст:
“no valid domain name defined for ACME client”.

А понятнее было бы если бы отобразил об ошибке в строке с декларацией acme и текстом типа “в строке acme указан не задекларированный плагин $acmesrv”, раз парсер в этом месте конфига слово “$acmesrv” воспринял как имя плагина, а не как переменную.

По поводу приведенной конфигурации - это отрывок из работающей конфигурации на 130 строк, в которой и домен указан и всё остальное. Не сработали только директивы acme - отрывок конфига по ним и привёл.

Тут пример конфига.

А понятнее было бы если бы отобразил об ошибке в строке с декларацией acme и текстом типа “в строке acme указан не задекларированный плагин $acmesrv”, раз парсер в этом месте конфига слово “$acmesrv” воспринял как имя плагина, а не как переменную.

Да, очередность выдачи ошибок тут можно поменять. Это сделаем.

1 Like