Add a program for lego's exec DNS provider
contrib/lego/jarl-lego.sh turns lego's "present|cleanup FQDN VALUE" calls into jarl acme set|unset --exact, so lego (and CNAME delegation to a dedicated ACME zone) works with Jarl. docs/acme.md explains the setup. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5cb8602a7f
commit
0221c78c8a
6 files changed
+88
-4
No files matched your search
@@ -24,6 +24,9 @@ The first version, to be released as 0.1.0.
|
||||
the web UI. Networks smaller than a /24 explain that they belong in the
|
||||
enclosing /24's zone.
|
||||
- docs/operations.md: setting up a secondary server with its own jarld.
|
||||
- lego support: `contrib/lego/jarl-lego.sh` is a program for lego's `exec`
|
||||
DNS provider that publishes DNS-01 challenges through `jarl acme`,
|
||||
including challenge names reached through a CNAME (docs/acme.md).
|
||||
- docs/concepts.md: what each zone type does, what to enter as a new zone's
|
||||
name servers (and when glue addresses are needed), how reverse zones map
|
||||
to networks, and why dynamic updates give way to API tokens.
|
||||
|
||||
@@ -48,9 +48,10 @@ install: build
|
||||
install -D -m 0644 deploy/tmpfiles.d/jarl.conf $(DESTDIR)$(TMPFILESDIR)/jarl.conf
|
||||
install -D -m 0644 README.md $(DESTDIR)$(DOCDIR)/README.md
|
||||
install -D -m 0644 CHANGELOG.md $(DESTDIR)$(DOCDIR)/CHANGELOG.md
|
||||
install -d $(DESTDIR)$(DOCDIR)/docs $(DESTDIR)$(DOCDIR)/contrib/acme.sh
|
||||
install -d $(DESTDIR)$(DOCDIR)/docs $(DESTDIR)$(DOCDIR)/contrib/acme.sh $(DESTDIR)$(DOCDIR)/contrib/lego
|
||||
install -m 0644 docs/*.md $(DESTDIR)$(DOCDIR)/docs/
|
||||
install -m 0644 contrib/acme.sh/dns_jarl.sh $(DESTDIR)$(DOCDIR)/contrib/acme.sh/
|
||||
install -m 0755 contrib/lego/jarl-lego.sh $(DESTDIR)$(DOCDIR)/contrib/lego/
|
||||
@if [ ! -e $(DESTDIR)/etc/jarl/jarl.yaml ]; then \
|
||||
install -d -m 0750 $(DESTDIR)/etc/jarl; \
|
||||
bin/jarld config --example > $(DESTDIR)/etc/jarl/jarl.yaml; \
|
||||
|
||||
@@ -46,7 +46,7 @@ error: www.adbraun.lol has a CNAME, so it can't have any other records (found A)
|
||||
queries, record types, cache hit rate. Shown in the web UI and the CLI,
|
||||
and exportable as JSON. Stored as aggregates in a separate database with
|
||||
retention you set.
|
||||
* **Let's Encrypt DNS-01** built in: `jarl acme` plus certbot and acme.sh
|
||||
* **Let's Encrypt DNS-01** built in: `jarl acme` plus certbot, acme.sh and lego
|
||||
hooks, including CNAME delegation to a dedicated ACME zone.
|
||||
* **Adopts an existing server**: imports named.conf and zone files
|
||||
(comments included), then switches named over with an automatic
|
||||
@@ -88,7 +88,7 @@ in `/etc/jarl/jarl.yaml` to reach it from your management network.
|
||||
| [docs/api.md](docs/api.md) | REST API reference |
|
||||
| [docs/permissions.md](docs/permissions.md) | Users, tokens, grants and roles |
|
||||
| [docs/views.md](docs/views.md) | Split DNS: adding views to a server that has none |
|
||||
| [docs/acme.md](docs/acme.md) | Let's Encrypt DNS-01 with certbot and acme.sh |
|
||||
| [docs/acme.md](docs/acme.md) | Let's Encrypt DNS-01 with certbot, acme.sh and lego |
|
||||
| [docs/stats.md](docs/stats.md) | Query statistics: enabling, what is collected, retention |
|
||||
| [docs/validation.md](docs/validation.md) | Every check Jarl makes |
|
||||
| [docs/operations.md](docs/operations.md) | Backups, drift, failures, recovery, monitoring |
|
||||
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env sh
|
||||
# Jarl (BIND manager): a program for lego's "exec" DNS provider.
|
||||
#
|
||||
# lego runs it as "jarl-lego present FQDN VALUE" and "jarl-lego cleanup
|
||||
# FQDN VALUE", where FQDN is the challenge name after lego has followed
|
||||
# any CNAME. It publishes and removes the TXT record through the jarl CLI.
|
||||
#
|
||||
# Install it, then:
|
||||
# EXEC_PATH=/usr/local/bin/jarl-lego JARL_TOKEN=@/etc/jarl/lego.token \
|
||||
# lego --email you@example.com --dns exec -d example.com -d '*.example.com' run
|
||||
#
|
||||
# Options (environment):
|
||||
# JARL_SERVER Jarl server URL, e.g. https://ns1.example.com:8053 (optional if the jarl CLI is configured)
|
||||
# JARL_TOKEN API token, or @FILE (optional if the jarl CLI is configured)
|
||||
# JARL_VIEW Only write into this view (optional; default every view that has the zone)
|
||||
# JARL_BIN Path of the jarl binary (optional; default "jarl")
|
||||
|
||||
JARL_BIN="${JARL_BIN:-jarl}"
|
||||
|
||||
if [ "$2" = "--" ]; then
|
||||
echo "jarl-lego: EXEC_MODE=RAW is not supported; unset EXEC_MODE" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
present) action="set" ;;
|
||||
cleanup) action="unset" ;;
|
||||
*)
|
||||
echo "usage: jarl-lego present|cleanup FQDN VALUE" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -ne 3 ]; then
|
||||
echo "usage: jarl-lego present|cleanup FQDN VALUE" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# lego passes the full record name, so --exact keeps jarl from adding
|
||||
# _acme-challenge. again.
|
||||
if [ -n "$JARL_VIEW" ]; then
|
||||
exec "$JARL_BIN" -q acme "$action" --exact --view "$JARL_VIEW" "$2" "$3"
|
||||
fi
|
||||
exec "$JARL_BIN" -q acme "$action" --exact "$2" "$3"
|
||||
+36
-1
@@ -79,7 +79,36 @@ remembers `JARL_SERVER`, `JARL_TOKEN`, `JARL_VIEW` (optional) and `JARL_BIN`
|
||||
(path to jarl, optional) in acme.sh's account configuration for renewals.
|
||||
When they are unset, jarl's own configuration file is used.
|
||||
|
||||
## 5. A dedicated ACME zone (CNAME delegation)
|
||||
## 5. lego
|
||||
|
||||
lego's `exec` provider runs a program to publish and remove the record.
|
||||
Jarl ships one, `contrib/lego/jarl-lego.sh`, which calls the `jarl` CLI
|
||||
(so jarl must be installed on the same host):
|
||||
|
||||
```sh
|
||||
sudo install -m 0755 contrib/lego/jarl-lego.sh /usr/local/bin/jarl-lego # or from /usr/local/share/doc/jarl/contrib/
|
||||
export EXEC_PATH=/usr/local/bin/jarl-lego
|
||||
export JARL_SERVER=https://ns1.adbraun.lol:8053
|
||||
export JARL_TOKEN=@/etc/jarl/certbot.token
|
||||
lego --email you@adbraun.lol --dns exec -d adbraun.lol -d '*.adbraun.lol' run
|
||||
```
|
||||
|
||||
Renew with the same variables and `lego ... renew` in place of `run`.
|
||||
|
||||
* lego runs `jarl-lego present FQDN VALUE` and `jarl-lego cleanup FQDN VALUE`,
|
||||
and the script passes them to `jarl acme set|unset --exact`. FQDN is the
|
||||
full record name (`_acme-challenge.adbraun.lol.`), so `--exact` stops
|
||||
jarl from adding `_acme-challenge.` a second time.
|
||||
* `JARL_TOKEN` may be the token itself or `@FILE`. `JARL_VIEW` limits the
|
||||
record to one view, and `JARL_BIN` points at jarl if it isn't in `PATH`.
|
||||
When `JARL_SERVER` and `JARL_TOKEN` are unset, jarl's configuration file
|
||||
is used.
|
||||
* Leave `EXEC_MODE` unset: the script needs lego's default mode, not `RAW`.
|
||||
* lego waits until the record is visible on the zone's name servers
|
||||
(`EXEC_PROPAGATION_TIMEOUT`, 60 seconds by default). Jarl answers only
|
||||
once named serves the record, so this check passes on its first try.
|
||||
|
||||
## 6. A dedicated ACME zone (CNAME delegation)
|
||||
|
||||
Instead of letting a token write into your main zone, point each challenge
|
||||
name at a small zone that exists only for ACME. The token may then write
|
||||
@@ -112,6 +141,12 @@ target:
|
||||
|
||||
The hook passes acme.sh's full record name to `jarl acme --exact`, so both
|
||||
modes work.
|
||||
* **lego** follows the CNAME itself (unless `LEGO_DISABLE_CNAME_SUPPORT`
|
||||
is set) and passes the target to `jarl-lego`, which writes there with
|
||||
`--exact`. The `acme` role allows only names that start with
|
||||
`_acme-challenge`, so the token needs the grant above, not the role. lego
|
||||
uses the host's resolvers for the lookup; `--dns.resolvers
|
||||
ns1.adbraun.lol:53` asks the Jarl server instead.
|
||||
|
||||
A leaked ACME token can then only touch TXT records in the ACME zone, and
|
||||
the main zone is never modified by automation.
|
||||
|
||||
@@ -26,6 +26,7 @@ internal/
|
||||
config/ jarld's YAML configuration
|
||||
deploy/ systemd unit, sysusers.d and tmpfiles.d files
|
||||
contrib/acme.sh/ acme.sh DNS API hook
|
||||
contrib/lego/ program for lego's exec DNS provider
|
||||
scripts/e2e.sh end-to-end test against a real named
|
||||
```
|
||||
|
||||
|
||||
Reference in new issue
Block a user