LinuxCommandLibrary

acme.sh

Obtain and renew Let's Encrypt certificates

TLDR

Issue a certificate using webroot mode

$ acme.sh --issue [[-d|--domain]] [example.com] [[-w|--webroot]] /[path/to/webroot]
copy

Issue a certificate for multiple domains using standalone mode using port 80
$ acme.sh --issue --standalone [[-d|--domain]] [example.com] [[-d|--domain]] [www.example.com]
copy

Issue a certificate using standalone TLS mode using port 443
$ acme.sh --issue --alpn [[-d|--domain]] [example.com]
copy

Issue a certificate using a working nginx configuration
$ acme.sh --issue --nginx [[-d|--domain]] [example.com]
copy

Issue a certificate using a working Apache configuration
$ acme.sh --issue --apache [[-d|--domain]] [example.com]
copy

Issue a wildcard (\*) certificate using an automatic DNS API mode
$ acme.sh --issue --dns [dns_cf] [[-d|--domain]] [*.example.com]
copy

Install certificate files into the specified locations (useful for automatic certificate renewal)
$ acme.sh [[-i|--install-cert]] [[-d|--domain]] [example.com] --key-file /[path/to/example.com.key] --fullchain-file /[path/to/example.com.cer] --reloadcmd "[systemctl force-reload nginx]"
copy

SYNOPSIS

acme.sh [--issue|-d domain[,domain...]] [--webroot|-w path | --standalone | --dns|--dnsapi provider] [--keylength bits] [--test|--force|--debug] | --renew[-all] | --install-cert|-i | --list | --uninstall | --cron | --upgrade | --help

PARAMETERS

--issue
    Issue a new certificate for specified domain(s).

--renew
    Renew a specific certificate.

--renew-all
    Renew all issued certificates.

-d, --domain
    Main domain name (required for --issue).

-D, --domain-alias
    Additional domain alias for cert.

--domains
    File with list of domains for multi-domain cert.

-w, --webroot
    Webroot path for HTTP-01 challenge.

--standalone
    HTTP-01 challenge with built-in standalone server.

--alpn
    TLS-ALPN-01 challenge.

--dns
    Enable DNS-01 challenge.

--dnsapi
    DNS provider API (e.g., dns_cf for Cloudflare).

--keylength
    RSA key length: 2048|3072|4096 (default 2048).

--ecc
    Use ECC key (P-256 or P-384).

--install-cert, -i
    Install cert to specified paths.

--deploy
    Deploy hook (e.g., --deploy-hook nginx).

--reloadcmd
    Custom reload command post-install.

--cron
    Install daily cron job for renewals.

--force
    Force action (e.g., renew non-expired cert).

--test
    Use Let's Encrypt staging server.

--debug
    Enable debug output (1=verbose, 2=trace).

--home
    Set acme.sh base directory.

--list
    List all issued certificates.

DESCRIPTION

acme.sh is a lightweight, pure Unix shell implementation of the ACME protocol, enabling issuance and renewal of free SSL/TLS certificates from Let's Encrypt and other ACME CAs. Written entirely in POSIX-compliant shell (sh, bash, zsh), it has minimal dependencies: only curl, openssl, and optionally socat or nc. This makes it highly portable across Linux distributions, embedded systems, and even some BSDs.

Supports challenge types like HTTP-01 (standalone mode starts its own server, webroot integrates with existing webservers), DNS-01 (automated via 100+ DNS providers like Cloudflare, Route53), and TLS-ALPN-01. Features include wildcard certs, ECDSA/RSA keys (up to 4096-bit), auto-renewal via cron, deployment hooks (Nginx, Apache reload), custom hooks, and multi-domain SAN certs.

Ideal for servers without Python/Rust dependencies (unlike Certbot/Lego), it's actively maintained on GitHub with 30k+ stars. Installs as ~/.acme.sh/acme.sh under user home for security. Usage emphasizes non-root execution to avoid privilege issues.

CAVEATS

Must run as non-root user for security; DNS-01 requires API credentials/tokens; standalone mode needs port 80 free; no Windows native support (WSL ok); high-traffic sites need rate-limit awareness.

INSTALLATION

curl https://get.acme.sh | sh -s [email protected]
Then: source ~/.bashrc; acme.sh --install-cert -d example.com

EXAMPLE USAGE

acme.sh --issue -d example.com --standalone --keylength 2048
acme.sh --issue -d '*.example.com' --dns dns_cf --keylength ec-256

CRON RENEWAL

Run acme.sh --cron once to add /etc/cron.d/acme.sh job. Checks daily, renews if <30 days left.

HISTORY

Created by Neilpang in September 2015 as a bash alternative to Certbot. Gained popularity for zero-dependency design; v2.0 (2017) added DNS API support. By 2023, supports ACME v2, 100+ DNS providers, 30k+ GitHub stars, used in Docker, routers.

SEE ALSO

certbot(1), dehydrated(1), lego(1)

Copied to clipboard