A Rust port of acme-tiny, fully compatible with its CLI and ACME workflow.
acme-tiny-rs is a feature-equivalent Rust implementation of acme-tiny (Python):
| Aspect | acme-tiny (Python) | acme-tiny-rs (Rust) |
|---|---|---|
| Language | Python 2/3 | Rust |
| Dependencies | Python + OpenSSL CLI | Zero runtime dependencies (static linking) |
| Startup time | ~50ms interpreter | < 1ms |
| Binary size | Requires Python runtime | ~2.7MB single file |
| Key parsing | openssl rsa / openssl req subprocess |
Pure Rust (rsa / p256 / p384 / x509-parser) |
| HTTP/TLS | urllib + system CA |
reqwest + rustls (bundled root certs) |
| Cross-platform | Requires Python + OpenSSL install | Single binary, no runtime deps |
- Single-file deployment:
scpone binary to your server — no Python or OpenSSL needed - Key types: RSA + ECDSA P-256/P-384 + Ed25519 account keys (auto-detected from PEM)
⚠️ Let's Encrypt does not support Ed25519 or IP certificates- Ed25519 works for account keys only (JWS signing). Domain keys for CSR must be RSA or ECDSA.
- IP certificates (RFC 8738) are supported but require a CA that implements the extension (ZeroSSL, Google Trust).
- Challenge types: http-01, dns-01, tls-alpn-01, dns-persist-01, dns-account-01
- DNS providers: Cloudflare, Alibaba, Tencent, AWS Route53, Azure, GoDaddy, Google Cloud, DigitalOcean, OVH, and more — see DNS.md
- Standalone mode: Built-in HTTP server (
--standalone) and TLS-ALPN server (--challenge-type tls-alpn-01) - EAB support: External Account Binding for CAs that require it (ZeroSSL, Google Trust)
- Hooks: acme.sh-compatible pre/post/renew/deploy/notify hooks
- Subcommands:
revoke,inspect,dump,ari,version - DNS CNAME delegation: Auto-follow
_acme-challengeCNAME chain (no manual--challenge-aliasneeded) - ARI renewal (RFC 9773):
--ariwith--certfor CA-scheduled renewal;arisubcommand for manual inspection - ACMEE Profiles: Pass
-P/--profileto select certificate profile (classic, shortlived, tlsserver) - Statically linked:
x86_64-unknown-linux-muslbuilds have zero.sodependencies — runs on any Linux kernel - Drop-in compatible: CLI arguments match
acme-tinyexactly
Download the appropriate binary from Releases:
VER=$(curl -s https://api.github.com/repos/dyrnq/acme-tiny-rs/releases/latest | grep tag_name | cut -d'"' -f4) && \
curl -L -o acme-tiny-rs "https://github.com/dyrnq/acme-tiny-rs/releases/download/${VER}/acme-tiny-rs-${VER}-x86_64-unknown-linux-musl"
chmod +x acme-tiny-rsgit clone https://github.com/dyrnq/acme-tiny-rs.git
cd acme-tiny-rs
cargo build --release
# binary at ./target/release/acme-tiny-rsStatic build (musl):
rustup target add x86_64-unknown-linux-musl
cargo build --release --target x86_64-unknown-linux-musl# RSA
openssl genrsa 4096 > account.key
# ECDSA P-256
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 > account.key
# ECDSA P-384
openssl ecparam -genkey -name secp384r1 > account.key# Generate a domain private key
openssl genrsa 4096 > domain.key
# Single domain
openssl req -new -sha256 -key domain.key -subj "/CN=yoursite.com" > domain.csr
# Multiple domains
openssl req -new -sha256 -key domain.key -subj "/" \
-addext "subjectAltName = DNS:yoursite.com, DNS:www.yoursite.com" > domain.csr
# Multiple domains (openssl < 1.1.1)
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN \
-config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:yoursite.com,DNS:www.yoursite.com")) \
> domain.csrmkdir -p /var/www/challenges/# nginx example
server {
listen 80;
server_name yoursite.com www.yoursite.com;
location /.well-known/acme-challenge/ {
alias /var/www/challenges/;
try_files $uri =404;
}
}acme-tiny-rs \
--account-key ./account.key \
--csr ./domain.csr \
--acme-dir /var/www/challenges/ \
> signed_chain.crtStaging environment (test):
# Using preset name
acme-tiny-rs \
--server letsencrypt-staging \
--account-key ./account.key \
--csr ./domain.csr \
--acme-dir /var/www/challenges/ \
> signed_chain.crt
# Or using full URL
acme-tiny-rs \
--directory-url https://acme-staging-v02.api.letsencrypt.org/directory \
--account-key ./account.key \
--csr ./domain.csr \
--acme-dir /var/www/challenges/ \
> signed_chain.crtView all available CA presets:
acme-tiny-rs --list-caserver {
listen 443 ssl;
server_name yoursite.com www.yoursite.com;
ssl_certificate /path/to/signed_chain.crt;
ssl_certificate_key /path/to/domain.key;
}#!/bin/sh
# renew_cert.sh
acme-tiny-rs \
--account-key /path/to/account.key \
--csr /path/to/domain.csr \
--acme-dir /var/www/challenges/ \
> /path/to/signed_chain.crt.tmp \
|| exit
mv /path/to/signed_chain.crt.tmp /path/to/signed_chain.crt
service nginx reload# crontab (runs once per month)
0 0 1 * * /path/to/renew_cert.sh 2>> /var/log/acme_tiny.log--account-key <PATH> Path to account private key (RSA, ECDSA P-256/P-384, Ed25519)
--csr <PATH> Path to CSR file
--acme-dir <PATH> Path to .well-known/acme-challenge/ directory (http-01)
--quiet Suppress output except for errors
--disable-check Skip self-check of challenge file (http-01)
--directory-url <URL> CA directory URL (overrides --server)
--server <NAME|URL> CA server preset name or URL [default: letsencrypt]
Presets: letsencrypt, letsencrypt-staging, zerossl,
buypass, sslcom, google, step, pebble, pebble-eab
--ca <URL> DEPRECATED, use --server or --directory-url instead
--contact <CONTACT>... Contact details (e.g. mailto:admin@example.com)
--check-port <PORT> Port for http-01 self-check [default: 80]
--challenge-type <TYPE> http-01 (default), dns-01, tls-alpn-01, dns-persist-01, or dns-account-01
--dns-provider <NAME> DNS provider for DNS challenges [default: manual]
--standalone Use built-in HTTP server on port 80 (no disk writes)
--agree-tos Agree to CA Terms of Service [default: true]
--eab-kid <KID> EAB Key Identifier (for CAs requiring EAB)
--eab-hmac-key <KEY> EAB HMAC Key (base64url-encoded)
--output, -o <PATH> Write certificate to file instead of stdout
--pre-hook <CMD> Command/script before certificate issuance
--post-hook <CMD> Command/script after issuance (success or failure)
--renew-hook <CMD> Command/script after successful renewal
--deploy-hook <CMD> Command/script to deploy the certificate
--notify-hook <CMD> Command/script for notifications
--ca-bundle <PATH> Additional CA certificate bundle for TLS verification
Subcommands:
version Print version, git hash, build time
ari --cert <PATH> Check ARI renewal info (RFC 9773), outputs JSON
revoke --cert <PATH> Revoke a certificate (RFC 8555 §7.6)
inspect -d <DOMAIN> TLS certificate info (table or --json)
dump <DOMAIN> Dump TLS certificate chain
list-ca List known CA presets (--json, --no-header)
inspect-ca --server <ID> Fetch and pretty-print CA directory JSON
thumbprint --account-key Output JWK thumbprint (RFC 7638)
See also: ARI.md (ARI renewal), DNS.md, EAB.md.
MIT — same as acme-tiny.