andrico21/acme-client-rs

By andrico21

Updated 17 days ago

A single-binary ACME client implementing RFC 8555 ARI and DNS-PERSIST-01 support

Image
Security
Web servers
0

1.2K

andrico21/acme-client-rs repository overview

Quickstart

All examples below assume a rootless podman scenario (net.ipv4.ip_unprivileged_port_start = 80). Full documentation is available here in English and Russian.

Get a new certificate for somesite.example.org (LE staging directory)

For demo purposes and convenience, set these variables first:

export SITEFQDN="somesite.example.org"
export ACME_DIR="https://acme-staging-v02.api.letsencrypt.org/directory"
export EMAIL="[email protected]"
Run
podman run --rm --env SITEFQDN=${SITEFQDN} --env ACME_DIR=${ACME_DIR} --env EMAIL=${EMAIL} \
--read-only --security-opt no-new-privileges --cap-drop ALL \
--cap-add CAP_NET_BIND_SERVICE --publish 80:80/tcp \
--mount type=volume,source=acme-data,destination=/data,noexec,nosuid,nodev,ro=false \
docker.io/andrico21/acme-client-rs \
--directory ${ACME_DIR} --account-key /data/account-${SITEFQDN}.key run --generate-account-key-if-missing --contact ${EMAIL} --challenge-type http-01 --cert-output /data/${SITEFQDN}.crt --key-output /data/${SITEFQDN}.key ${SITEFQDN}
Result
2026-06-05T13:27:56.601321Z  INFO acme_client_rs::handlers::run_flow::account_step: Step 1: Creating / looking up account
2026-06-05T13:27:56.606914Z  INFO acme_client_rs::client::acme: Fetching ACME directory from https://acme-staging-v02.api.letsencrypt.org/directory
2026-06-05T13:27:57.051290Z  INFO acme_client_rs::client::acme: Creating/looking-up ACME account
Account status: valid
2026-06-05T13:27:57.367145Z  INFO acme_client_rs::client::acme: Account URL: https://acme-staging-v02.api.letsencrypt.org/acme/acct/111222333
2026-06-05T13:27:57.367209Z  INFO acme_client_rs::handlers::run_flow::order_step: Step 2: Placing order
2026-06-05T13:27:57.367220Z  INFO acme_client_rs::client::acme: Creating new order
2026-06-05T13:27:57.526017Z  INFO acme_client_rs::client::acme: Order URL: https://acme-staging-v02.api.letsencrypt.org/acme/order/111222333/99998888777
Order URL:  https://acme-staging-v02.api.letsencrypt.org/acme/order/111222333/99998888777
Order status: ready
2026-06-05T13:27:57.527083Z  INFO acme_client_rs::handlers::run_flow::authorize: Step 3: Completing authorizations
Authorization for somesite.example.org - status: valid
  Already valid, skipping
2026-06-05T13:27:57.672525Z  INFO acme_client_rs::handlers::run_flow::finalize: Step 4: Finalizing order
2026-06-05T13:27:57.674202Z  INFO acme_client_rs::client::acme: Finalizing order
Order status: processing
2026-06-05T13:27:57.824778Z  INFO acme_client_rs::handlers::run_flow::finalize: Step 5: Waiting for certificate issuance
  Order status: processing
  Order status: valid
2026-06-05T13:28:01.124595Z  INFO acme_client_rs::handlers::run_flow::finalize: Step 6: Downloading certificate
2026-06-05T13:28:01.124614Z  INFO acme_client_rs::client::acme: Downloading certificate from https://acme-staging-v02.api.letsencrypt.org/acme/cert/80aa6ab1f303245d60103c6773001fa95fc0
Private key saved to /data/somesite.example.org.key
Certificate saved to /data/somesite.example.org.crt
Confirmation
podman unshare openssl x509 -in .local/share/containers/storage/volumes/acme-data/_data/somesite.example.com.crt -text -noout | grep "Issuer\|DNS"
        Issuer: C = US, O = Let's Encrypt, CN = (STAGING) Baloney Bulgur YE2
                CA Issuers - URI:http://stg-ye2.i.lencr.org/
                DNS:somesite.example.com.crt

Check renewal via ARI

Checks whether renewal is advised by the ACME directory.

Run
podman run --rm --env SITEFQDN=${SITEFQDN} --env ACME_DIR=${ACME_DIR} --env EMAIL=${EMAIL} \
--read-only --security-opt no-new-privileges --cap-drop ALL \
--cap-add CAP_NET_BIND_SERVICE --publish 80:80/tcp \
--mount type=volume,source=acme-data,destination=/data,noexec,nosuid,nodev,ro=false \
docker.io/andrico21/acme-client-rs \
--directory ${ACME_DIR} --account-key /data/account-${SITEFQDN}.key run --contact ${EMAIL} --challenge-type http-01 --ari --days 30 --cert-output /data/${SITEFQDN}.crt --key-output /data/${SITEFQDN}.key ${SITEFQDN} ${SITEFQDN}
Result

No renewal window yet - just info output:

2026-06-05T14:03:51.832308Z  INFO acme_client_rs::client::acme: Fetching ACME directory from https://acme-staging-v02.api.letsencrypt.org/directory
2026-06-05T14:03:52.273230Z  INFO acme_client_rs::client::acme: Fetching ARI renewal info: https://acme-staging-v02.api.letsencrypt.org/acme/renewal-info/Lv75sUwePugraX-ItXqrDH3Qf3N.59nxK9GDOu2ejLCosaUhElPX
ARI: renewal window starts 2026-08-03T15:48:41Z - skipping renewal

Tag summary

Content type

Image

Digest

sha256:68db107d6

Size

4.1 MB

Last updated

17 days ago

docker pull andrico21/acme-client-rs