Obtain (wildcard) certificates from let's encrypt using dns-01 without the need for API access to your DNS provider.

Overview

Agnos

Presentation

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.

Why

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:

  • Nullify the need for API and API credentials
  • Nullify all concerns regarding propagation times

Hence, agnos removes virtually all downsides of dns-01 challenges.

How

Agnos leverages let's encrypt capability to follow DNS NS records. It requires you to add to your DNS zone:

  1. An 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.
  2. For each domain you will want to validate, a NS record for the corresponding _acme-challenge sub-domain, indicating that agnos should be used as a name server for this specific domain.

Installation

This instructions are given for a Linux system but a similar process will likely work on all Unixes, and maybe windows.

Released binary

Pre-compiled binaries for (relatively recent) Linux/amd64 are available for every tagged release.

Building

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.

cd agnos/
cargo build --release
mv target/release/agnos agnos

Setting capabilities to not run agnos as root

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:

# as root
setcap 'cap_net_bind_service=+ep' agnos
# agnos is the file of the binary as compiled above

Usage

Let's Encrypt accounts

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:

openssl genrsa 2048 > /path/to/store/the/key.pem

or if you prefer a larger key:

openssl genrsa 4096 > /path/to/store/the/key.pem

Agnos configuration

Agnos is configured via a single TOML file. A commented example is available in config_example.toml.

It is advised to absolute rather than relative paths in the configuration file.

There are three "levels" in the configuration:

1. General

The general configuration level is where the IP address to listen on is provided.

dns_listen_adr = "1.2.3.4:53"

2. Accounts

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.

[[accounts]]
email= "[email protected]"
private_key_path = "priv_key.pem"

3. Certificates

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).

[[accounts.certificates]]
domains =  ["doma.in","*.doma.in"]
fullchain_output_file = "fullchain_A.pem"
key_output_file = "cert_key_A.pem"

Configuration of your DNS provider

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.

Running agnos

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.

You might also like...
Utility for working with reverse DNS

RDNS RDNS is a small Rust CLI utility for performing single and bulk reverse DNS (PTR) lookups. Usage RDNS 0.1.0 Joe Banks [email protected] Utilities for

Dropping GFW DNS contaminated packets based on Rust + eBPF
Dropping GFW DNS contaminated packets based on Rust + eBPF

Dropping GFW DNS contaminated packets based on Rust + eBPF

Implementation of algorithms for Domain Name System (DNS) Cookies construction

DNS Cookie RFC7873 left the construction of Server Cookies to the discretion of the DNS Server (implementer) which has resulted in a gallimaufry of di

Third party Google DNS client for rust.

google-dns-rs Documentation Install Add the following line to your Cargo.toml file: google-dns-rs = "0.3.0" Usage use google_dns_rs::api::{Dns, DoH, R

A Rust based DNS client, server, and resolver

Trust-DNS A Rust based DNS client, server, and Resolver, built to be safe and secure from the ground up. This repo consists of multiple crates: Librar

Resolved - a simple DNS server for home networks

resolved resolved (pronounced "resolved", not "resolved") is a simple DNS server for home networks. To that end, it supports: Recursive and non-recurs

DNS resolver for split-horizon scenarios

polyresolver is a resolver for split-horizon scenarios polyresolver is used to root domain names to different nameservers for the purposes of resolvin

Flexible DNS hijacking and proxy tool.

kungfu Flexible DNS hijacking and proxy tool. Features Flexible rules e.g. glob pattern domain, static routes, response CIDR Host file include /etc/ho

Dns subdomain finding tool, based off of the c application of the same name

dnsmap-rs Tool for brute-forcing/scanning for existing subdomains in a domain. Based on dnsmap c application that is packaged in kali linux. Can query

Comments
  • No valid hostname while creating entry for NS

    No valid hostname while creating entry for NS "_acme-challenge.doma.in"

    Thank you for this project. I'm trying to create all necessary steps (which are mentioned in the readme).

    But I have an issue while setting the NS entry "_acme-challenge.mydomain.de":

    image

    It always says that is not a valid hostname. It seems that the underline as a first character does not work or rather is not valid in my configuration (at DomainFactory).

    Do you habe any suggestions?

    opened by dirkzado 1
  • Bump thread_local from 1.1.3 to 1.1.4

    Bump thread_local from 1.1.3 to 1.1.4

    Bumps thread_local from 1.1.3 to 1.1.4.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump regex from 1.5.4 to 1.5.5

    Bump regex from 1.5.4 to 1.5.5

    Bumps regex from 1.5.4 to 1.5.5.

    Changelog

    Sourced from regex's changelog.

    1.5.5 (2022-03-08)

    This releases fixes a security bug in the regex compiler. This bug permits a vector for a denial-of-service attack in cases where the regex being compiled is untrusted. There are no known problems where the regex is itself trusted, including in cases of untrusted haystacks.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
Releases(v.0.1.0-beta.1)
Owner
Arthur Carcano
This is our final cry on 500 khz before eternal silence.
Arthur Carcano
DNS Server written in Rust for fun, see https://dev.to/xfbs/writing-a-dns-server-in-rust-1gpn

DNS Fun Ever wondered how you can write a DNS server in Rust? No? Well, too bad, I'm telling you anyways. But don't worry, this is going to be a fun o

Patrick Elsen 26 Jan 13, 2023
An async, user-friendly Let's Encrypt/ACMEv2 library written in Rust

lers An async, user-friendly Let's Encrypt/ACMEv2 library written in Rust. The API and implementation were inspired by acme2, acme-micro, and lego. Fe

Alexander Krantz 20 Apr 3, 2023
Filen.io is a cloud storage provider with an open-source desktop client.

Library to call Filen.io API from Rust Filen.io is a cloud storage provider with an open-source desktop client. My goal is to write a library which ca

Konstantin Zakharov 5 Nov 15, 2022
Docker containers on a synthetic network. Run applications in a context that lets you manipulate their network conditions.

Synthetic Network Docker containers on a synthetic network. Run applications in a context that lets you manipulate their network conditions. Dependenc

Daily 58 Dec 15, 2022
A wrapper for the Google Cloud DNS API

cloud-dns is a crate providing a client to interact with Google Cloud DNS v1

Embark 5 May 24, 2022
Automatically updates your Cloudflare DNS records for specific zones. Especially useful if you have dynamic IP address

Cloudflare DNS updater What does it do? Cloudflare DNS updater updates specified dns records for specified zones effortlessly and automatically. It wa

Niko Huuskonen 8 Aug 30, 2022
Userspace libpcap-based tool to mirror your dns traffic

DNS traffic mirroring tool (dns-mirror) Description Userspace libpcap-based tool. dns-mirror sniffs dns packets on the given interface and proxies it

Timofey 1 Mar 15, 2022
Command-line DNS client using bitvec, nom and RFC 1035

Dingo Domain INformation Gatherer, Obviously. Installation Install cargo, see instructions on the Rust website Run ./install.sh (it just does cargo bu

Adam Chalmers 94 Oct 18, 2022
Modrinth API is a simple library for using Modrinth's API in Rust projects

Ferinth is a simple library for using the Modrinth API in Rust projects. It uses reqwest as its HTTP(S) client and deserialises responses to typed structs using serde.

null 20 Dec 8, 2022
Library + CLI-Tool to measure the TTFB (time to first byte) of HTTP requests. Additionally, this crate measures the times of DNS lookup, TCP connect and TLS handshake.

TTFB: CLI + Lib to Measure the TTFB of HTTP/1.1 Requests Similar to the network tab in Google Chrome or Mozilla Firefox, this crate helps you find the

Philipp Schuster 24 Dec 1, 2022