Skip to main content

acme

acme.sh is an ACME protocol client written purely in shell script.

https://github.com/acmesh-official/acme.sh

Installation

curl https://get.acme.sh | sh -s email=my@example.com
# OR
wget -O - https://get.acme.sh | sh -s email=my@example.com

Use a specific CA

acme.sh supports multiple ACME servers. The default CA is zerossl. To use a specific CA, you need to tell acme.sh to communicate with that CA’s ACME server by setting the --server flag.

acme.sh --set-server zerossl
acme.sh --set-server buypass

Issue Certificate

  1. HTTP challenge

HTTP challenge is straightforward method. Using HTTP challenge you need to have a web server that can serve a special verification file that acme.sh creates to prove domain ownership. Specify the webroot directory using -w or --webroot flag. Specify the domain with -d flag

acme.sh --issue -d example.com -d www.example.com -w /home/wwwroot/example.com
  1. Standalone mode

If you do not have a web server or want to use a manual HTTP-o1 challenge, you can use standalone mode

acme.sh --issue --standalone -d example.com -d www.example.com -d cp.example.com
  1. Use acme.sh with Cloudflare

This is the best practice.

An API Token with permissions to manage DNS settings for your domain is needed.

Steps to create a Cloudflare API Token:

  1. Log in to your Cloudflare Dashboard.
  2. Go to My Profile (top-right corner), then select API Tokens.
  3. Click Create Token.
  4. Select the "Edit zone DNS" template or create a custom token with the following permissions:
  5. Zone: DNS: Edit (under Permissions)

After creation, copy the API Token and set up acme.sh with Cloudflare API credentials

export CF_Token="wQxBql5xxx"

To request a certification, use the following command.

acme.sh --issue --dns dns_cf -d yourdomain.com -d www.yourdomain.com

Example

# /root/.acme.sh/acme.sh --issue -d example.com --dns dns_cf
[Tue Feb 18 15:55:23 UTC 2025] Using CA: https://acme.zerossl.com/v2/DV90
[Tue Feb 18 15:55:23 UTC 2025] Creating domain key
[Tue Feb 18 15:55:23 UTC 2025] The domain key is here: /root/.acme.sh/example.com_ecc/example.com.key
[Tue Feb 18 15:55:23 UTC 2025] Single domain='example.com'
[Tue Feb 18 15:55:29 UTC 2025] Getting webroot for domain='example.com'
[Tue Feb 18 15:55:29 UTC 2025] Adding TXT value: aMLN230nOlgL8WQLWzQ9GTHu4baz9NZym3D2UU8VQNM for domain: _acme-challenge.example.com
[Tue Feb 18 15:55:30 UTC 2025] Adding record
[Tue Feb 18 15:55:30 UTC 2025] Added, OK
[Tue Feb 18 15:55:30 UTC 2025] The TXT record has been successfully added.
[Tue Feb 18 15:55:30 UTC 2025] Let's check each DNS record now. Sleeping for 20 seconds first.
[Tue Feb 18 15:55:52 UTC 2025] You can use '--dnssleep' to disable public dns checks.
[Tue Feb 18 15:55:52 UTC 2025] See: https://github.com/acmesh-official/acme.sh/wiki/dnscheck
[Tue Feb 18 15:55:52 UTC 2025] Checking example.com for _acme-challenge.example.com
[Tue Feb 18 15:55:54 UTC 2025] Success for domain example.com '_acme-challenge.example.com'.
[Tue Feb 18 15:55:54 UTC 2025] All checks succeeded
[Tue Feb 18 15:55:54 UTC 2025] Verifying: example.com
[Tue Feb 18 15:55:55 UTC 2025] Processing. The CA is processing your order, please wait. (1/30)
[Tue Feb 18 15:55:59 UTC 2025] Success
[Tue Feb 18 15:55:59 UTC 2025] Removing DNS records.
[Tue Feb 18 15:55:59 UTC 2025] Removing txt: aMLN230nOlgL8WQLWzQ9GTHu4baz9NZym3D2UU8VQNM for domain: _acme-challenge.example.com
[Tue Feb 18 15:56:02 UTC 2025] Successfully removed
[Tue Feb 18 15:56:02 UTC 2025] Verification finished, beginning signing.
[Tue Feb 18 15:56:02 UTC 2025] Let's finalize the order.
[Tue Feb 18 15:56:02 UTC 2025] Le_OrderFinalize='https://acme.zerossl.com/v2/DV90/order/UP-Kq7BS_UTLUoqRhGiBBw/finalize'
[Tue Feb 18 15:56:04 UTC 2025] Order status is 'processing', let's sleep and retry.
[Tue Feb 18 15:56:04 UTC 2025] Sleeping for 15 seconds then retrying
[Tue Feb 18 15:56:20 UTC 2025] Polling order status: https://acme.zerossl.com/v2/DV90/order/UP-Kq7BS_UTLUoqRhGiBBw
[Tue Feb 18 15:56:23 UTC 2025] Downloading cert.
[Tue Feb 18 15:56:23 UTC 2025] Le_LinkCert='https://acme.zerossl.com/v2/DV90/cert/ThZ-6HDdSXHWWk-b4KKfQg'
[Tue Feb 18 15:56:23 UTC 2025] Cert success.
-----BEGIN CERTIFICATE-----
MIID/TCCA4SgAwIBAgIRALt0SxDy+obJYKXaS4fZqzIwCgYIKoZIzj0EAwMwSzEL
...
-----END CERTIFICATE-----
[Tue Feb 18 15:56:23 UTC 2025] Your cert is in: /root/.acme.sh/example.com_ecc/example.com.cer
[Tue Feb 18 15:56:23 UTC 2025] Your cert key is in: /root/.acme.sh/example.com_ecc/example.com.key
[Tue Feb 18 15:56:23 UTC 2025] The intermediate CA cert is in: /root/.acme.sh/example.com_ecc/ca.cer
[Tue Feb 18 15:56:23 UTC 2025] And the full-chain cert is in: /root/.acme.sh/example.com_ecc/fullchain.cer