{"slug": "acme-sh", "name": "acme.sh", "category": "other", "category_name": "Other software", "description": "Shell-script ACME client for issuing and renewing TLS certificates, e.g. from Let's Encrypt.", "recommenders": 5, "commenters": 6, "warners": 0, "score": 4.833, "rising": -0.31, "first": "2025-12-03", "latest": "2026-09-04", "why": "Recommended for getting Let's Encrypt certificates on personal and on-prem servers, especially via DNS validation for wildcard and private or split-DNS setups.", "why_is_quote": false, "has_verdict": true, "sentiment": {"recommend": 5, "neutral": 1, "compare": 0, "warn": 0}, "spark": [0, 1, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0], "listed": true, "loved": ["DNS validation", "Self-hosted certs"], "caveat": "ZeroSSL default", "short_quote": "I personally use acme.sh which can be configured to use email, XMPP, or HTTP(S) requests with prebuilt templates for most popular webhooks", "icon": true, "domain": null, "github_repo": "github.com/acmesh-official/acme.sh", "official_url": "https://github.com/acmesh-official/acme.sh", "pricing": "open source", "aliases": ["acme.sh"], "verdict": [{"text": "Recommended for getting Let's Encrypt certificates on personal and on-prem servers", "cites": [{"id": 793051457, "item_id": 49565716, "url": "https://news.ycombinator.com/item?id=49565716", "by": "8by3", "date": "2026-09-04", "stance": "recommend", "quote": "Use Acme.sh / lets encrypt for certs.", "excerpt": "I refuse to give my data, to yet another company trying to control and centralize the internet. For their \"Free\" service. Instead, I pay money to run a VM with DDOS protection on vultr, to guard my infrastructure I run on prem. Use Acme.sh / lets encrypt for certs. Use bunny.net for CDN which also has some basic protections.", "context": "runs on-prem infrastructure", "use_case": "TLS certificates", "switched_from": "", "story": "Ask HN: Do all of you use Cloudflare for preventing DDoS, Bot and more attacks?"}, {"id": 777520144, "item_id": 48595009, "url": "https://news.ycombinator.com/item?id=48595009", "by": "polpo", "date": "2026-06-18", "stance": "recommend", "quote": "I use acme.sh for certs on my personal server", "excerpt": "I use acme.sh for certs on my personal server and was a little surprised when it started using ZeroSSL by default. Despite being more \"corporate\" I decided to roll with it and it's worked just fine.", "context": "runs personal server", "use_case": "certificate issuance", "switched_from": "", "story": "Let's Encrypt has been down most of today"}, {"id": 738156896, "item_id": 46134806, "url": "https://news.ycombinator.com/item?id=46134806", "by": "wolrah", "date": "2025-12-03", "stance": "recommend", "quote": "I personally use acme.sh which can be configured to use email, XMPP, or HTTP(S) requests with prebuilt templates for most popular webhooks", "excerpt": "> I'm talking about managing two certificates so I can share a static site with a handful of friends. Each one takes about 10 minutes a year to update. The personal site I started with is one certificate for a static site that I use for basically the same thing. It took me 10 minutes to set up in 2016 and I haven't thought about it for a second since then. It just works. > Adding automation means I have to set up a p", "context": "runs personal site and work systems", "use_case": "automated certificate renewal", "switched_from": "", "story": "Decreasing Certificate Lifetimes to 45 Days"}]}, {"text": ", especially via DNS validation for wildcard and private or split-DNS setups.", "cites": [{"id": 781562512, "item_id": 48847657, "url": "https://news.ycombinator.com/item?id=48847657", "by": "Hamuko", "date": "2026-07-09", "stance": "recommend", "quote": "put it on some public DNS that can do DNS validation with acme.sh", "excerpt": "I use a registered domain with DNS validation and then CNAMEs that I resolve locally. Basically: 1. Register a domain (\"server.com\") and put it on some public DNS that can do DNS validation with acme.sh. 2. Use DNS validation to get a certificate on your domain from Let's Encrypt. You can just grab a wildcard one (\"*.server.com\"). 3. CNAME all of your services on a public DNS to an internal address (\"email.server.com", "context": "", "use_case": "DNS-validated TLS certificates", "switched_from": "", "story": "TLS certificates for internal services done right"}, {"id": 781676528, "item_id": 48854783, "url": "https://news.ycombinator.com/item?id=48854783", "by": "Walf", "date": "2026-07-09", "stance": "neutral", "quote": "I use acme.sh with DNS validation", "excerpt": ">Don't use split DNS So what's your solution when you have a wholly private service that will never have a public v4 address, nor a publicly routable v6? How do clients get the address for a nice domain name without the addresses in public DNS? I use acme.sh with DNS validation, and use common domains that have both public and private services on subdomains. I use split horizon so private.domain.example resolves only", "context": "", "use_case": "TLS certificate issuance", "switched_from": "", "story": "TLS certificates for internal services done right"}, {"id": 781564784, "item_id": 48847799, "url": "https://news.ycombinator.com/item?id=48847799", "by": "throw0101d", "date": "2026-07-09", "stance": "recommend", "quote": "See also perhaps DNS aliasing in case you are not able to dynamically update your 'primary' domain", "excerpt": "> I use the acme dns-1 challenge on my public domain. See also perhaps DNS aliasing in case you are not able to dynamically update your 'primary' domain, but can update a secondary or sub-domain: * https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mode So if \"example.com\" is control by Corporate IT, and they don't want 'random' folks fiddling with it, then you can create a \"dnsauth.example.com\" and point the ", "context": "", "use_case": "ACME DNS alias challenge", "switched_from": "", "story": "TLS certificates for internal services done right"}]}, {"text": " The only caveat raised is that it switched to ZeroSSL as the default CA, which surprised one user, though it worked fine for them.", "cites": [{"id": 777520144, "item_id": 48595009, "url": "https://news.ycombinator.com/item?id=48595009", "by": "polpo", "date": "2026-06-18", "stance": "recommend", "quote": "I use acme.sh for certs on my personal server", "excerpt": "I use acme.sh for certs on my personal server and was a little surprised when it started using ZeroSSL by default. Despite being more \"corporate\" I decided to roll with it and it's worked just fine.", "context": "runs personal server", "use_case": "certificate issuance", "switched_from": "", "story": "Let's Encrypt has been down most of today"}]}], "praise": [{"label": "DNS validation", "summary": "Commenters use its DNS validation for wildcard certificates and private services, and point to its DNS alias mode for domains they can't update.", "quotes": [{"id": 781562512, "item_id": 48847657, "url": "https://news.ycombinator.com/item?id=48847657", "by": "Hamuko", "date": "2026-07-09", "stance": "recommend", "quote": "put it on some public DNS that can do DNS validation with acme.sh", "excerpt": "I use a registered domain with DNS validation and then CNAMEs that I resolve locally. Basically: 1. Register a domain (\"server.com\") and put it on some public DNS that can do DNS validation with acme.sh. 2. Use DNS validation to get a certificate on your domain from Let's Encrypt. You can just grab a wildcard one (\"*.server.com\"). 3. CNAME all of your services on a public DNS to an internal address (\"email.server.com", "context": "", "use_case": "DNS-validated TLS certificates", "switched_from": "", "story": "TLS certificates for internal services done right"}, {"id": 781676528, "item_id": 48854783, "url": "https://news.ycombinator.com/item?id=48854783", "by": "Walf", "date": "2026-07-09", "stance": "neutral", "quote": "I use acme.sh with DNS validation", "excerpt": ">Don't use split DNS So what's your solution when you have a wholly private service that will never have a public v4 address, nor a publicly routable v6? How do clients get the address for a nice domain name without the addresses in public DNS? I use acme.sh with DNS validation, and use common domains that have both public and private services on subdomains. I use split horizon so private.domain.example resolves only", "context": "", "use_case": "TLS certificate issuance", "switched_from": "", "story": "TLS certificates for internal services done right"}, {"id": 781564784, "item_id": 48847799, "url": "https://news.ycombinator.com/item?id=48847799", "by": "throw0101d", "date": "2026-07-09", "stance": "recommend", "quote": "See also perhaps DNS aliasing in case you are not able to dynamically update your 'primary' domain", "excerpt": "> I use the acme dns-1 challenge on my public domain. See also perhaps DNS aliasing in case you are not able to dynamically update your 'primary' domain, but can update a secondary or sub-domain: * https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mode So if \"example.com\" is control by Corporate IT, and they don't want 'random' folks fiddling with it, then you can create a \"dnsauth.example.com\" and point the ", "context": "", "use_case": "ACME DNS alias challenge", "switched_from": "", "story": "TLS certificates for internal services done right"}]}, {"label": "Self-hosted certs", "summary": "Used to get certificates for personal and on-prem servers without relying on a third-party service.", "quotes": [{"id": 793051457, "item_id": 49565716, "url": "https://news.ycombinator.com/item?id=49565716", "by": "8by3", "date": "2026-09-04", "stance": "recommend", "quote": "Use Acme.sh / lets encrypt for certs.", "excerpt": "I refuse to give my data, to yet another company trying to control and centralize the internet. For their \"Free\" service. Instead, I pay money to run a VM with DDOS protection on vultr, to guard my infrastructure I run on prem. Use Acme.sh / lets encrypt for certs. Use bunny.net for CDN which also has some basic protections.", "context": "runs on-prem infrastructure", "use_case": "TLS certificates", "switched_from": "", "story": "Ask HN: Do all of you use Cloudflare for preventing DDoS, Bot and more attacks?"}, {"id": 777520144, "item_id": 48595009, "url": "https://news.ycombinator.com/item?id=48595009", "by": "polpo", "date": "2026-06-18", "stance": "recommend", "quote": "I use acme.sh for certs on my personal server", "excerpt": "I use acme.sh for certs on my personal server and was a little surprised when it started using ZeroSSL by default. Despite being more \"corporate\" I decided to roll with it and it's worked just fine.", "context": "runs personal server", "use_case": "certificate issuance", "switched_from": "", "story": "Let's Encrypt has been down most of today"}]}, {"label": "Notification hooks", "summary": "Can send notifications by email, XMPP, or HTTP(S) requests, with templates for popular webhooks.", "quotes": [{"id": 738156896, "item_id": 46134806, "url": "https://news.ycombinator.com/item?id=46134806", "by": "wolrah", "date": "2025-12-03", "stance": "recommend", "quote": "I personally use acme.sh which can be configured to use email, XMPP, or HTTP(S) requests with prebuilt templates for most popular webhooks", "excerpt": "> I'm talking about managing two certificates so I can share a static site with a handful of friends. Each one takes about 10 minutes a year to update. The personal site I started with is one certificate for a static site that I use for basically the same thing. It took me 10 minutes to set up in 2016 and I haven't thought about it for a second since then. It just works. > Adding automation means I have to set up a p", "context": "runs personal site and work systems", "use_case": "automated certificate renewal", "switched_from": "", "story": "Decreasing Certificate Lifetimes to 45 Days"}]}], "caveats": [{"label": "ZeroSSL default", "summary": "One user was surprised it started using ZeroSSL by default, though it worked fine.", "quotes": [{"id": 777520144, "item_id": 48595009, "url": "https://news.ycombinator.com/item?id=48595009", "by": "polpo", "date": "2026-06-18", "stance": "recommend", "quote": "I use acme.sh for certs on my personal server", "excerpt": "I use acme.sh for certs on my personal server and was a little surprised when it started using ZeroSSL by default. Despite being more \"corporate\" I decided to roll with it and it's worked just fine.", "context": "runs personal server", "use_case": "certificate issuance", "switched_from": "", "story": "Let's Encrypt has been down most of today"}]}], "who": [{"by": "8by3", "context": "runs on-prem infrastructure", "url": "https://news.ycombinator.com/item?id=49565716", "date": "2026-09-04"}, {"by": "polpo", "context": "runs personal server", "url": "https://news.ycombinator.com/item?id=48595009", "date": "2026-06-18"}, {"by": "wolrah", "context": "runs personal site and work systems", "url": "https://news.ycombinator.com/item?id=46134806", "date": "2025-12-03"}], "tags": ["for self-hosters", "for wildcard certs", "for split-horizon DNS", "for locked-down domains"], "use_cases": ["tls certificates", "tls certificate issuance", "acme dns alias challenge", "dns-validated tls certificates", "certificate issuance", "automated certificate renewal"], "compared": [{"slug": "let-s-encrypt", "name": "Let's Encrypt", "co": 4, "switched_from": 0, "switched_to": 0}], "makers": [], "threads": [{"url": "https://news.ycombinator.com/item?id=48846995", "title": "TLS certificates for internal services done right", "mentions": 3}, {"url": "https://news.ycombinator.com/item?id=49565526", "title": "Ask HN: Do all of you use Cloudflare for preventing DDoS, Bot and more attacks?", "mentions": 1}, {"url": "https://news.ycombinator.com/item?id=48594715", "title": "Let's Encrypt has been down most of today", "mentions": 1}, {"url": "https://news.ycombinator.com/item?id=46117126", "title": "Decreasing Certificate Lifetimes to 45 Days", "mentions": 1}], "sentiment_by_month": {"2025-11": {}, "2025-12": {"recommend": 1}, "2026-01": {}, "2026-02": {}, "2026-03": {}, "2026-04": {}, "2026-05": {}, "2026-06": {"recommend": 1}, "2026-07": {"recommend": 2, "neutral": 1}, "2026-08": {}, "2026-09": {"recommend": 1}, "2026-10": {}}, "quotes": [{"id": 793051457, "item_id": 49565716, "url": "https://news.ycombinator.com/item?id=49565716", "by": "8by3", "date": "2026-09-04", "stance": "recommend", "quote": "Use Acme.sh / lets encrypt for certs.", "excerpt": "I refuse to give my data, to yet another company trying to control and centralize the internet. For their \"Free\" service. Instead, I pay money to run a VM with DDOS protection on vultr, to guard my infrastructure I run on prem. Use Acme.sh / lets encrypt for certs. Use bunny.net for CDN which also has some basic protections.", "context": "runs on-prem infrastructure", "use_case": "TLS certificates", "switched_from": "", "story": "Ask HN: Do all of you use Cloudflare for preventing DDoS, Bot and more attacks?"}, {"id": 781676528, "item_id": 48854783, "url": "https://news.ycombinator.com/item?id=48854783", "by": "Walf", "date": "2026-07-09", "stance": "neutral", "quote": "I use acme.sh with DNS validation", "excerpt": ">Don't use split DNS So what's your solution when you have a wholly private service that will never have a public v4 address, nor a publicly routable v6? How do clients get the address for a nice domain name without the addresses in public DNS? I use acme.sh with DNS validation, and use common domains that have both public and private services on subdomains. I use split horizon so private.domain.example resolves only", "context": "", "use_case": "TLS certificate issuance", "switched_from": "", "story": "TLS certificates for internal services done right"}, {"id": 781564784, "item_id": 48847799, "url": "https://news.ycombinator.com/item?id=48847799", "by": "throw0101d", "date": "2026-07-09", "stance": "recommend", "quote": "See also perhaps DNS aliasing in case you are not able to dynamically update your 'primary' domain", "excerpt": "> I use the acme dns-1 challenge on my public domain. See also perhaps DNS aliasing in case you are not able to dynamically update your 'primary' domain, but can update a secondary or sub-domain: * https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mode So if \"example.com\" is control by Corporate IT, and they don't want 'random' folks fiddling with it, then you can create a \"dnsauth.example.com\" and point the ", "context": "", "use_case": "ACME DNS alias challenge", "switched_from": "", "story": "TLS certificates for internal services done right"}, {"id": 781562512, "item_id": 48847657, "url": "https://news.ycombinator.com/item?id=48847657", "by": "Hamuko", "date": "2026-07-09", "stance": "recommend", "quote": "put it on some public DNS that can do DNS validation with acme.sh", "excerpt": "I use a registered domain with DNS validation and then CNAMEs that I resolve locally. Basically: 1. Register a domain (\"server.com\") and put it on some public DNS that can do DNS validation with acme.sh. 2. Use DNS validation to get a certificate on your domain from Let's Encrypt. You can just grab a wildcard one (\"*.server.com\"). 3. CNAME all of your services on a public DNS to an internal address (\"email.server.com", "context": "", "use_case": "DNS-validated TLS certificates", "switched_from": "", "story": "TLS certificates for internal services done right"}, {"id": 777520144, "item_id": 48595009, "url": "https://news.ycombinator.com/item?id=48595009", "by": "polpo", "date": "2026-06-18", "stance": "recommend", "quote": "I use acme.sh for certs on my personal server", "excerpt": "I use acme.sh for certs on my personal server and was a little surprised when it started using ZeroSSL by default. Despite being more \"corporate\" I decided to roll with it and it's worked just fine.", "context": "runs personal server", "use_case": "certificate issuance", "switched_from": "", "story": "Let's Encrypt has been down most of today"}, {"id": 738156896, "item_id": 46134806, "url": "https://news.ycombinator.com/item?id=46134806", "by": "wolrah", "date": "2025-12-03", "stance": "recommend", "quote": "I personally use acme.sh which can be configured to use email, XMPP, or HTTP(S) requests with prebuilt templates for most popular webhooks", "excerpt": "> I'm talking about managing two certificates so I can share a static site with a handful of friends. Each one takes about 10 minutes a year to update. The personal site I started with is one certificate for a static site that I use for basically the same thing. It took me 10 minutes to set up in 2016 and I haven't thought about it for a second since then. It just works. > Adding automation means I have to set up a p", "context": "runs personal site and work systems", "use_case": "automated certificate renewal", "switched_from": "", "story": "Decreasing Certificate Lifetimes to 45 Days"}]}