For an introduction to the ACME protocol and its DNS verification part, you can refer to our beta release blog post.
Agnos is a single-binary program allowing you to easily obtain certificates (including wildcards) from Let's Encrypt using DNS-01 challenges. It answers Let's Encrypt DNS queries on its own, bypassing the need for API calls to your DNS provider.
DNS-01 is summarized by Let's Encrypt documentation as such:
Pros
- You can use this challenge to issue certificates containing wildcard domain names.
- It works well even if you have multiple web servers.
Cons
- Keeping API credentials on your web server is risky.
- Your DNS provider might not offer an API.
- Your DNS API may not provide information on propagation times.
By serving its own DNS answers, agnos:
Hence, agnos removes virtually all downsides of dns-01 challenges.
Agnos leverages let's encrypt capability to follow DNS NS
records. It requires you to add to your DNS zone:
A
(or AAAA
) record pointing to the public facing IP address of the server on which agnos will run. On this server, UDP port 53 (the one used by DNS) should be open and free.NS
record for the corresponding _acme-challenge
sub-domain, indicating that agnos should be used as a name server for this specific domain.This instructions are given for a Linux system but a similar process will likely work on all Unixes, and maybe windows.
Pre-compiled binaries for (relatively recent) Linux/amd64 are available for every tagged release.
Agnos is available in the AUR. You can install it using: yay -S agnos
.
Agnos is written in Rust. To build it you will need to have the rust toolchain installed.
Once you have obtained the source, the following command will build the binary and put it in the root directory of the repo.
bash
cd agnos/
cargo build --release
mv target/release/agnos agnos
Because agnos listen on the low-numbered port 53, it requires special privileges. Running it as root will do, but if you (understandably) don't want to do that, the following command is for you:
```bash
setcap 'capnetbind_service=+ep' agnos
```
Let's Encrypt accounts are identified by an e-mail address and a private RSA key. To generate such a key use the following command:
shell
openssl genrsa 2048 > /path/to/store/the/key.pem
or if you prefer a larger key:
shell
openssl genrsa 4096 > /path/to/store/the/key.pem
Agnos is configured via a single TOML file. A commented example is available in config_example.toml.
It is advised to use absolute rather than relative paths in the configuration file.
There are three "levels" in the configuration:
The general configuration level is where the IP address to listen on is provided.
toml
dns_listen_adr = "1.2.3.4:53"
Several Let's Encrypt accounts can be specified. For each account, an e-mail address and the path to the account RSA private key must be provided.
toml
[[accounts]]
email= "contact@doma.in"
private_key_path = "priv_key.pem"
For each account, several certificates can be ordered. Each certificate can cover multiple domains. On disk, a certificate is represented by two files: the full certificate chain, and the private key of the certificate (generated by agnos and different from the account private key).
toml
[[accounts.certificates]]
domains = ["doma.in","*.doma.in"]
fullchain_output_file = "fullchain_A.pem"
key_output_file = "cert_key_A.pem"
Say that we have the following domains we want to obtain a certificate (or multiple certificates) for:
- doma.in
- its wildcard variant: *.doma.in
- examp.le
- and another.examp.le
.
Notice here that we are not requesting a certificate for *.examp.le
but only for one subdomain: another.examp.le
.
Let's encrypt DNS-01 challenge is going to ask for TXT DNS records on the following three domains:
- _acme-challenge.doma.in
(for both doma.in
and its wildcard)
- _acme-challenge.examp.le
- _acme-challenge.another.examp.le
Let's assume that agnos is going to run on a server whose public facing IP address is 1.2.3.4
. The goal is to indicate that the three _acme_challenge
domains cited above are managed by agnos using NS
DNS records. NS
records usually point to domain names, so we will also set an A
record on agnos-ns.doma.in
to point to 1.2.3.4
(here agnos-ns.doma.in
is entirely arbitrary, it could be another, completely independent domain, you control, like my-agnos.com
).
We create the following records:
In the zone of doma.in
agnos-ns.doma.in A 1.2.3.4
_acme-challenge.doma.in NS agnos-ns.doma.in
In the zone of examp.le
_acme-challenge.examp.le NS agnos-ns.doma.in
_acme-challenge.another.examp.le NS agnos-ns.doma.in
Note: Though it may seem cumbersome, this must only be done once from your DNS provider web interface. Once it is done, you will never have to touch a TXT
record.
agnos
takes a single command line argument, the path to its configuration file, and two optional flags: --no-staging
to use Let's Encrypt production server, and --debug
to display more debug information. Help is available via agnos --help
.
When running, it checks whether the certificates of the full chain are going to expire in the next 30 days, and only renew them in that case, so it is suitable to be used in a cron job.
PRs and issues are very welcome.
Build using usual cargo
commands.
The Makefile is for integration testing in a docker compose. At the root, run sudo make
(sudo is required to use docker) to test agnos using pebble.