feat: CERTBOT_DOMAIN may name several domains
Build docker image and push to registry.bitdeals.org / main-build-job (push) Successful in 30s
Build docker image and push to registry.bitdeals.org / main-build-job (push) Successful in 30s
certbot's own -d already takes a comma-separated list and puts every name
in the certificate's Subject Alternative Names, so `-d "$CERTBOT_DOMAIN"`
needed no change at all. What assumed a single domain was everything that
treated the variable as a *file name*: --cert-name, and the two scripts
that address the lineage under /etc/letsencrypt/live. Certbot names a
lineage after the first domain of the list, so all three now take
${CERTBOT_DOMAIN%%,*} instead of the whole string -- otherwise a two-domain
value asks for a lineage literally called "a.org,b.org" and the renewal
pass looks for a directory nobody made.
One certificate with several names rather than several lineages: HAProxy
binds a single site.pem, and a second lineage would have nowhere to go.
Adding a domain to CERTBOT_DOMAIN on a machine that already holds a
certificate still needs one manual issuance -- `certbot renew` reads the
names off the certificate it has and never looks at the variable. The
README says so, and gives the command.
This commit is contained in:
@@ -42,7 +42,7 @@ services:
|
|||||||
image: registry.bitdeals.org/certbot
|
image: registry.bitdeals.org/certbot
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
- CERTBOT_DOMAIN=example.org
|
- CERTBOT_DOMAIN=example.org,www.example.org
|
||||||
- CERTBOT_EMAIL=admin@example.org # optional, for expiry notices
|
- CERTBOT_EMAIL=admin@example.org # optional, for expiry notices
|
||||||
volumes:
|
volumes:
|
||||||
- certificates:/etc/certificates # shared with haproxy
|
- certificates:/etc/certificates # shared with haproxy
|
||||||
@@ -62,7 +62,7 @@ the one that writes it.
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker run -d \
|
docker run -d \
|
||||||
-e CERTBOT_DOMAIN=example.org \
|
-e CERTBOT_DOMAIN=example.org,www.example.org \
|
||||||
-v certificates:/etc/certificates \
|
-v certificates:/etc/certificates \
|
||||||
-v letsencrypt:/etc/letsencrypt \
|
-v letsencrypt:/etc/letsencrypt \
|
||||||
-v letsencrypt_work:/var/lib/letsencrypt \
|
-v letsencrypt_work:/var/lib/letsencrypt \
|
||||||
@@ -103,7 +103,7 @@ Container images are configured using parameters passed at runtime.
|
|||||||
|
|
||||||
|Parameter|Function|
|
|Parameter|Function|
|
||||||
|:--------|:-------|
|
|:--------|:-------|
|
||||||
|-e CERTBOT_DOMAIN|The domain to certify. Default: empty — no certificate is requested and the site keeps the self-signed placeholder, silently. One domain only; the scripts pass a single `-d`|
|
|-e CERTBOT_DOMAIN|The domain to certify, or several comma-separated (`a.org,b.org`) — certbot's own `-d` grammar, giving one certificate that carries every name as a Subject Alternative Name. The first domain names the certificate under `/etc/letsencrypt/live`. Default: empty — no certificate is requested and the site keeps the self-signed placeholder, silently|
|
||||||
|-e CERTBOT_EMAIL|Address for Let's Encrypt expiry notices. Default: empty, which registers with `--register-unsafely-without-email` and leaves you without warnings — see Notes|
|
|-e CERTBOT_EMAIL|Address for Let's Encrypt expiry notices. Default: empty, which registers with `--register-unsafely-without-email` and leaves you without warnings — see Notes|
|
||||||
|-v /etc/certificates|Shared with HAProxy. Holds `site.pem`: the concatenated certificate and private key HAProxy binds to|
|
|-v /etc/certificates|Shared with HAProxy. Holds `site.pem`: the concatenated certificate and private key HAProxy binds to|
|
||||||
|-v /etc/letsencrypt|Certbot's config directory: the ACME account key, the issued certificates and the renewal configuration. Losing it means re-registering and re-issuing|
|
|-v /etc/letsencrypt|Certbot's config directory: the ACME account key, the issued certificates and the renewal configuration. Losing it means re-registering and re-issuing|
|
||||||
@@ -162,6 +162,11 @@ Container images are configured using parameters passed at runtime.
|
|||||||
by cron, means a new certbot release reaches the registry — and through
|
by cron, means a new certbot release reaches the registry — and through
|
||||||
Watchtower, production — without anyone triggering a build. Pin a version tag
|
Watchtower, production — without anyone triggering a build. Pin a version tag
|
||||||
for reproducible builds.
|
for reproducible builds.
|
||||||
|
- **Adding a domain to `CERTBOT_DOMAIN` does not reissue by itself.** The loop
|
||||||
|
calls `certbot renew`, which takes the names from the certificate it already
|
||||||
|
holds and never reads `CERTBOT_DOMAIN`. On a machine that has one, issue the
|
||||||
|
new set once by hand and the loop keeps it from then on:
|
||||||
|
`certbot certonly --standalone -n --agree-tos --http-01-port=380 --cert-name <first-domain> --expand -d <the,new,list>`.
|
||||||
- **Let's Encrypt enforces rate limits.** Repeated failed issuance against the
|
- **Let's Encrypt enforces rate limits.** Repeated failed issuance against the
|
||||||
same domain counts against them; test changes against
|
same domain counts against them; test changes against
|
||||||
`--server https://acme-staging-v02.api.letsencrypt.org/directory` before
|
`--server https://acme-staging-v02.api.letsencrypt.org/directory` before
|
||||||
|
|||||||
+9
-3
@@ -43,7 +43,7 @@ services:
|
|||||||
image: registry.bitdeals.org/certbot
|
image: registry.bitdeals.org/certbot
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
- CERTBOT_DOMAIN=example.org
|
- CERTBOT_DOMAIN=example.org,www.example.org
|
||||||
- CERTBOT_EMAIL=admin@example.org # необязательно, для уведомлений об истечении
|
- CERTBOT_EMAIL=admin@example.org # необязательно, для уведомлений об истечении
|
||||||
volumes:
|
volumes:
|
||||||
- certificates:/etc/certificates # общий с haproxy
|
- certificates:/etc/certificates # общий с haproxy
|
||||||
@@ -63,7 +63,7 @@ volumes:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker run -d \
|
docker run -d \
|
||||||
-e CERTBOT_DOMAIN=example.org \
|
-e CERTBOT_DOMAIN=example.org,www.example.org \
|
||||||
-v certificates:/etc/certificates \
|
-v certificates:/etc/certificates \
|
||||||
-v letsencrypt:/etc/letsencrypt \
|
-v letsencrypt:/etc/letsencrypt \
|
||||||
-v letsencrypt_work:/var/lib/letsencrypt \
|
-v letsencrypt_work:/var/lib/letsencrypt \
|
||||||
@@ -103,7 +103,7 @@ docker push registry.bitdeals.org/certbot
|
|||||||
|
|
||||||
|Параметр|Назначение|
|
|Параметр|Назначение|
|
||||||
|:--------|:-------|
|
|:--------|:-------|
|
||||||
|-e CERTBOT_DOMAIN|Домен, на который выпускается сертификат. По умолчанию: пусто — сертификат не запрашивается и сайт молча остаётся с самоподписанной заглушкой. Домен только один: скрипты передают единственный `-d`|
|
|-e CERTBOT_DOMAIN|Домен, на который выпускается сертификат, либо несколько через запятую (`a.org,b.org`) — это собственный синтаксис `-d` у certbot: получается один сертификат, несущий все имена в Subject Alternative Names. По первому домену назван каталог сертификата под `/etc/letsencrypt/live`. По умолчанию: пусто — сертификат не запрашивается и сайт молча остаётся с самоподписанной заглушкой|
|
||||||
|-e CERTBOT_EMAIL|Адрес для уведомлений Let's Encrypt об истечении срока. По умолчанию: пусто, регистрация идёт с `--register-unsafely-without-email`, и предупреждений не будет — см. «Замечания»|
|
|-e CERTBOT_EMAIL|Адрес для уведомлений Let's Encrypt об истечении срока. По умолчанию: пусто, регистрация идёт с `--register-unsafely-without-email`, и предупреждений не будет — см. «Замечания»|
|
||||||
|-v /etc/certificates|Общий с HAProxy. Содержит `site.pem` — склеенные сертификат и приватный ключ, которые загружает HAProxy|
|
|-v /etc/certificates|Общий с HAProxy. Содержит `site.pem` — склеенные сертификат и приватный ключ, которые загружает HAProxy|
|
||||||
|-v /etc/letsencrypt|Каталог конфигурации certbot: ключ учётной записи ACME, выпущенные сертификаты и настройки перевыпуска. Его потеря означает повторную регистрацию и повторный выпуск|
|
|-v /etc/letsencrypt|Каталог конфигурации certbot: ключ учётной записи ACME, выпущенные сертификаты и настройки перевыпуска. Его потеря означает повторную регистрацию и повторный выпуск|
|
||||||
@@ -166,6 +166,12 @@ docker push registry.bitdeals.org/certbot
|
|||||||
еженедельной пересборкой по cron означает, что новый выпуск certbot попадает в
|
еженедельной пересборкой по cron означает, что новый выпуск certbot попадает в
|
||||||
реестр, а через Watchtower и в продуктив, без того чтобы кто-либо запускал
|
реестр, а через Watchtower и в продуктив, без того чтобы кто-либо запускал
|
||||||
сборку. Для воспроизводимых сборок фиксируйте версию тегом.
|
сборку. Для воспроизводимых сборок фиксируйте версию тегом.
|
||||||
|
- **Добавленный в `CERTBOT_DOMAIN` домен сам по себе не приводит к
|
||||||
|
перевыпуску.** Цикл вызывает `certbot renew`, а тот берёт имена из уже
|
||||||
|
выданного сертификата и в `CERTBOT_DOMAIN` не заглядывает. Если сертификат на
|
||||||
|
машине уже есть, выпустите новый набор имён один раз вручную — дальше цикл
|
||||||
|
будет его поддерживать:
|
||||||
|
`certbot certonly --standalone -n --agree-tos --http-01-port=380 --cert-name <первый-домен> --expand -d <новый,список>`.
|
||||||
- **У Let's Encrypt есть ограничения частоты.** Повторяющиеся неудачные попытки
|
- **У Let's Encrypt есть ограничения частоты.** Повторяющиеся неудачные попытки
|
||||||
выпуска на один домен в них засчитываются; проверяйте изменения на
|
выпуска на один домен в них засчитываются; проверяйте изменения на
|
||||||
`--server https://acme-staging-v02.api.letsencrypt.org/directory`, прежде чем
|
`--server https://acme-staging-v02.api.letsencrypt.org/directory`, прежде чем
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ if [ -n "$CERTBOT_DOMAIN" ]; then
|
|||||||
certbot certonly --standalone \
|
certbot certonly --standalone \
|
||||||
--non-interactive --agree-tos --http-01-port=380 \
|
--non-interactive --agree-tos --http-01-port=380 \
|
||||||
"$@" \
|
"$@" \
|
||||||
--cert-name "$CERTBOT_DOMAIN" \
|
--cert-name "${CERTBOT_DOMAIN%%,*}" \
|
||||||
-d "$CERTBOT_DOMAIN"
|
-d "$CERTBOT_DOMAIN"
|
||||||
|
|
||||||
# Concatenate certificates
|
# Concatenate certificates
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Certificates exist
|
# Certificates exist
|
||||||
if [ -n "$CERTBOT_DOMAIN" -a -d /etc/letsencrypt/live/"$CERTBOT_DOMAIN" ]; then
|
if [ -n "$CERTBOT_DOMAIN" -a -d /etc/letsencrypt/live/"${CERTBOT_DOMAIN%%,*}" ]; then
|
||||||
# Check certificates and renew them
|
# Check certificates and renew them
|
||||||
certbot renew --http-01-port=380
|
certbot renew --http-01-port=380
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
# the tests below looking for fullchain.pem in whatever directory the caller
|
# the tests below looking for fullchain.pem in whatever directory the caller
|
||||||
# happened to be in.
|
# happened to be in.
|
||||||
|
|
||||||
live="/etc/letsencrypt/live/$CERTBOT_DOMAIN"
|
live="/etc/letsencrypt/live/${CERTBOT_DOMAIN%%,*}"
|
||||||
|
|
||||||
if [ -f "$live/fullchain.pem" ] && [ -f "$live/privkey.pem" ]; then
|
if [ -f "$live/fullchain.pem" ] && [ -f "$live/privkey.pem" ]; then
|
||||||
# Through a temporary file, then an atomic rename: HAProxy reads site.pem at
|
# Through a temporary file, then an atomic rename: HAProxy reads site.pem at
|
||||||
|
|||||||
Reference in New Issue
Block a user