Files
jarl/contrib/acme.sh/dns_jarl.sh
T
abrown38andClaude Opus 5.5 bd6b8778e4 Jarl 0.1.0: manage BIND through a web UI, REST API and CLI
Jarl keeps a BIND 9.20 server's whole configuration (views, ACLs, TSIG
keys, zones of every type, records, named.conf options) in SQLite and
renders named.conf, keys.conf and zone files from it.

Every change goes through one changeset pipeline: whole-configuration
validation, named-checkconf -z and named-checkzone in a staging
directory, atomic install, rndc reconfig/reload, serial verification
with rndc zonestatus, and rollback if named does not load the change.
Changes apply one at a time by default or are bundled and applied
together. Applied changesets can be reverted.

- jarld: the daemon with the REST API and an embedded web UI, plus import,
  adopt, check, resync, backup and local user recovery commands
- jarl: the CLI, including ACME DNS-01 hooks for certbot and acme.sh
- users with argon2id passwords and CSRF-protected sessions; hashed API
  tokens with granular grants and roles; an audit log
- systemd unit, sysusers.d/tmpfiles.d files, Makefile
- unit tests, integration tests against a real named, scripts/e2e.sh
- docs/ guides, README and CHANGELOG

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 15:03:13 +00:00

67 lines
2.4 KiB
Bash
Executable File

#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_jarl_info='Jarl (BIND manager)
Publishes DNS-01 challenge records through the jarl CLI.
Install: copy this file to ~/.acme.sh/dnsapi/dns_jarl.sh, then
acme.sh --issue --dns dns_jarl -d example.com -d "*.example.com"
Options:
JARL_SERVER Jarl server URL, e.g. https://ns1.example.com:8053 (optional if the jarl CLI is configured)
JARL_TOKEN API token, ideally one with the "acme" role (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")
'
dns_jarl_add() {
fulldomain=$1
txtvalue=$2
_jarl_setup || return 1
_info "Jarl: adding TXT record for $fulldomain"
if ! _jarl acme set --exact "$fulldomain" "$txtvalue"; then
_err "Jarl: could not add the TXT record for $fulldomain"
return 1
fi
return 0
}
dns_jarl_rm() {
fulldomain=$1
txtvalue=$2
_jarl_setup || return 1
_info "Jarl: removing TXT record for $fulldomain"
if ! _jarl acme unset --exact "$fulldomain" "$txtvalue"; then
_err "Jarl: could not remove the TXT record for $fulldomain"
return 1
fi
return 0
}
#################### private functions ####################
_jarl_setup() {
JARL_SERVER="${JARL_SERVER:-$(_readaccountconf_mutable JARL_SERVER)}"
JARL_TOKEN="${JARL_TOKEN:-$(_readaccountconf_mutable JARL_TOKEN)}"
JARL_VIEW="${JARL_VIEW:-$(_readaccountconf_mutable JARL_VIEW)}"
JARL_BIN="${JARL_BIN:-$(_readaccountconf_mutable JARL_BIN)}"
JARL_BIN="${JARL_BIN:-jarl}"
if ! command -v "$JARL_BIN" >/dev/null 2>&1; then
_err "Jarl: the jarl CLI ($JARL_BIN) was not found; set JARL_BIN"
return 1
fi
# Remember the settings for renewals.
[ -n "$JARL_SERVER" ] && _saveaccountconf_mutable JARL_SERVER "$JARL_SERVER"
[ -n "$JARL_TOKEN" ] && _saveaccountconf_mutable JARL_TOKEN "$JARL_TOKEN"
[ -n "$JARL_VIEW" ] && _saveaccountconf_mutable JARL_VIEW "$JARL_VIEW"
[ "$JARL_BIN" != "jarl" ] && _saveaccountconf_mutable JARL_BIN "$JARL_BIN"
return 0
}
_jarl() {
# jarl reads JARL_SERVER and JARL_TOKEN from the environment, and falls
# back to its own configuration file when they are empty.
if [ -n "$JARL_VIEW" ]; then
JARL_SERVER="$JARL_SERVER" JARL_TOKEN="$JARL_TOKEN" "$JARL_BIN" -q "$@" --view "$JARL_VIEW"
else
JARL_SERVER="$JARL_SERVER" JARL_TOKEN="$JARL_TOKEN" "$JARL_BIN" -q "$@"
fi
}