diff --git a/README.md b/README.md index c53de03..b98f04a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,14 @@ -# ACME Server as a Registration Authority +# About `acme-proxy` is a standalone ACME server built on [step-ca](https://github.com/smallstep/certificates) that operates in [registration authority (RA)](https://smallstep.com/docs/registration-authorities/) mode. It accepts certificate orders and validates certificate requests using the ACME protocol (RFC 8555), but does **NOT** sign certificates or store private keys. +## Documentation + +Checkout our [documentation site](https://software.es.net/acme-proxy) for detailed examples on usage, installation instructions, configuration etc. + ## How It Works -`acme-proxy` runs as an ACME server inside your enterprise environment, acting as an intermediary between your internal infrastructure and an external certificate authority service (such as Sectigo). When a client successfully completes an ACME challenge, `acme-proxy` forwards the certificate signing request to an external certificate authority (CA) that supports External Account Binding (EAB). The external CA signs the certificate and returns it to the client through `acme-proxy`. +`acme-proxy` runs as an ACME server inside your trusted network, acting as an intermediary between your internal infrastructure and an external certificate authority service (such as Sectigo). When a client successfully completes an ACME challenge, `acme-proxy` forwards the certificate signing request to an external certificate authority (CA) that supports External Account Binding (EAB). The external CA signs the certificate and returns it to the client through `acme-proxy`. **Certificate Request Flow:** @@ -31,25 +35,11 @@ This architecture addresses typical enterprise constraints that prevent direct c - Legacy DNS infrastructure lacks REST API support or ACME client integration - Security policies restrict distribution of API tokens or TSIG keys for large DNS zones -For more information on DNS-01 security considerations: +For more information on security considerations when using DNS-01 challenge: - [EFF: Technical Deep Dive on ACME DNS Challenge Validation](https://www.eff.org/deeplinks/2018/02/technical-deep-dive-securing-automation-acme-dns-challenge-validation) - [LetsEncrypt: DNS-01 Challenge](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge) -## Benefits - -Using ACME with commercial CAs in enterprise environments provides several advantages: - -**Trusted Certificates:** - -- Certificates are signed by publicly trusted CAs are already in system trust stores -- Eliminates the operational burden of distributing and maintaining custom root certificates across endpoints, servers, and client devices - -**Automation and Self-Service:** - -- Leverage standard ACME clients (Certbot, acme.sh, cert-manager.io) for certificate issuance, automatic renewals. -- Enable self-service certificate requests for development teams - ## Quick Start ```sh @@ -83,17 +73,6 @@ Requirements: Go >= 1.25 ❯ cd acme-proxy && make ``` -### Using Docker - -You can either use our [pre-built container images](https://github.com/esnet/acme-proxy/pkgs/container/acme-proxy) or you can build the image yourself. - -**DIY - Build docker image** - -```sh -❯ git clone https://github.com/esnet/acme-proxy.git -❯ cd acme-proxy && docker build -t acme-proxy:latest . -``` - ## Usage Review and update configuration options in [ca.json](./ca.json) before starting the acme-proxy server. @@ -102,7 +81,7 @@ Review and update configuration options in [ca.json](./ca.json) before starting vim ca.json ``` -The most important parts of the config are - +Checkout our [official docs](https://software.es.net/acme-proxy/install/#configuration) for full set of configuration options. For quick start the most relevant config bits are: ```json "dnsNames": ["acmeproxy.example.com"], @@ -117,7 +96,7 @@ The most important parts of the config are - "metrics": { "enabled": true, "port": 9234, - "dataSource": "db/metrics" + "dataSource": "/opt/acme-proxy/db/metrics" } }, ... @@ -166,41 +145,6 @@ badger 2025/07/15 22:12:24 INFO: Replay took: 5.99µs 2025/07/15 22:12:33 Serving HTTPS on proxy.example.com:443 ... ``` -When using acme-proxy with docker take a note of the bind mount and port - -```sh -$ docker run -itd -p 443:443 -v ./ca-dev.json:/acme-proxy/config/ca.json --name acme-proxy acme-proxy:latest -29c1ca374832dc50d3215b404f620c2a08d988c30f630464bf9d7d35aa44345f - -$ docker logs acme-proxy -2026/03/17 23:04:06 Building new tls configuration using step-ca x509 Signer Interface -2026/03/17 23:04:07 [INFO] acme: Registering account for certadmin@example.com -2026/03/17 23:04:07 INFO processing certificate request domains=[proxy.example.com] -2026/03/17 23:04:07 [INFO] [proxy.example.com] acme: Obtaining bundled SAN certificate given a CSR -2026/03/17 23:04:08 [INFO] [proxy.example.com] AuthURL: https://acme.sectigo.com/v2/InCommonRSAOV/authz/jQJHRdd-0kKdm-JVQVhjHQ -2026/03/17 23:04:08 [INFO] [proxy.example.com] acme: authorization already valid; skipping challenge -2026/03/17 23:04:08 [INFO] [proxy.example.com] acme: Validations succeeded; requesting certificates -2026/03/17 23:04:08 [INFO] Wait for certificate [timeout: 30s, interval: 500ms] -2026/03/17 23:04:13 [INFO] [proxy.example.com] Server responded with a certificate. -2026/03/17 23:04:13 INFO obtained certificate from external CA domains=[proxy.example.com] -2026/03/17 23:04:13 Starting Smallstep CA/0000000-dev (linux/amd64) -2026/03/17 23:04:13 Documentation: https://u.step.sm/docs/ca -2026/03/17 23:04:13 Community Discord: https://u.step.sm/discord -2026/03/17 23:04:13 Config file: /acme-proxy/config/ca.json -2026/03/17 23:04:13 The primary server URL is https://proxy.example.com:443 -2026/03/17 23:04:13 Root certificates are available at https://proxy.example.com:443/roots.pem -2026/03/17 23:04:13 Serving HTTPS on :443 ... - -$ curl -s https://proxy.example.com/acme/acme/directory | jq . -{ - "newNonce": "https://proxy.example.com/acme/acme/new-nonce", - "newAccount": "https://proxy.example.com/acme/acme/new-account", - "newOrder": "https://proxy.example.com/acme/acme/new-order", - "revokeCert": "https://proxy.example.com/acme/acme/revoke-cert", - "keyChange": "https://proxy.example.com/acme/acme/key-change" -} -``` - ### Obtaining a certificate While the example below uses `acme.sh` as the ACME client, we've also tested using `certbot` with equal success. @@ -283,11 +227,11 @@ Certificate: ``` -We have our certificate signed by InCommon 🎉 +We have our certificate signed by our certificate authority i.e InCommon 🎉 ### Renewing a certificate -Issuing a certificate is *generally* not a problem in enterprise environments. But the ability to reliably renew certificates and reload services gracefully post renewal is. I am using the `--force` flag for renewal only because the default configuration in ACME clients only performs automatic renewal `1 < N < 30` number of days before certificate expiration. +Issuing a certificate is *generally* not a problem in enterprise environments. But the ability to automatically renew certificates and reload services gracefully post renewal is. I am using the `--force` flag for renewal only because the default configuration in ACME clients only performs automatic renewal `1 < N < 30` number of days before certificate expiration. ```sh $ ./acme.sh --renew --domain myserver.example.com --force @@ -342,3 +286,17 @@ N+c9XyDLAiEAkbrRKBsYc8YSgYviREF9u+gz7jK5JY2dsaRatEfb8Eg= ``` Cert renewal was a success! ✨ + +## Benefits + +Using ACME with commercial CAs in enterprise environments provides several advantages: + +**Trusted Certificates:** + +- Certificates are signed by publicly trusted CAs are already in system trust stores +- Eliminates the operational burden of distributing and maintaining custom root certificates across endpoints, servers, and client devices + +**Automation and Self-Service:** + +- Leverage standard ACME clients (Certbot, acme.sh, cert-manager.io) for certificate issuance, automatic renewals. +- Enable self-service certificate requests for development teams diff --git a/develop/contribute.md b/develop/contribute.md index 336b7b8..74bd35f 100644 --- a/develop/contribute.md +++ b/develop/contribute.md @@ -1,8 +1,3 @@ -+++ -title = 'Contributing' -weight = 50 -+++ - # Setup development environment 1. Install `go >= 1.25` @@ -14,5 +9,5 @@ weight = 50 1. Fork the repo 2. In your fork, create a new branch for your work -3. Commit & push changes to your fork +3. Add changes in your branch, Commit & push changes to your forked repo 4. Submit a pull request diff --git a/develop/externalcas.md b/develop/externalcas.md index 71ffb3c..abc9f12 100644 --- a/develop/externalcas.md +++ b/develop/externalcas.md @@ -1,9 +1,3 @@ -+++ -title = 'External CAs' -weight = 30 -BookToC = true -+++ - # ACME server as Registration Authority See [upstream docs](#upstream-docs) section for more background on what registration authority, CAS are and how those concepts fits into step-ca architecture. diff --git a/develop/maintenance.md b/develop/maintenance.md index a43e091..47f9440 100644 --- a/develop/maintenance.md +++ b/develop/maintenance.md @@ -1,9 +1,3 @@ -+++ -title = 'Maintenance' -weight = 40 -BookToC = true -+++ - # Guide to patching upstream related changes - While smallstep/certifiates is meant to serve as the upstream Go module for acme-proxy, we have to maintain some patches/fixes ourselves until they get merged upstream. Our patched version of step-ca is currently maintained in a forked repo [esnet/certificates](https://github.com/esnet/certificates). diff --git a/docs/config/_default/hugo.toml b/docs/config/_default/hugo.toml index 005ea4f..622df63 100644 --- a/docs/config/_default/hugo.toml +++ b/docs/config/_default/hugo.toml @@ -1,5 +1,5 @@ -baseURL = 'http://docs.acme-proxy.es.net' -title = 'ACME Proxy' +baseURL = 'http://docs.acme-proxy.es.net/' +title = 'acme-proxy' theme = 'hugo-book' # Book configuration diff --git a/docs/content/_index.md b/docs/content/_index.md index f253f08..9df87e9 100644 --- a/docs/content/_index.md +++ b/docs/content/_index.md @@ -1,14 +1,14 @@ +++ -title = 'ACME Proxy' +title = 'acme-proxy' +++ -# What is ACME Proxy? +## What is acme-proxy? -`acme-proxy` is a standalone ACME server built on [step-ca](https://github.com/smallstep/certificates) that operates in [registration authority (RA)](https://smallstep.com/docs/registration-authorities/) mode. It runs as a standalone server inside your enterprise environment, acting as an intermediary between your internal infrastructure and an external certificate authority service (such as Sectigo). It accepts certificate orders and validates certificate requests using the ACME protocol (RFC 8555), but does **NOT** sign certificates or store private keys. +`acme-proxy` is a standalone ACME server built on [step-ca](https://github.com/smallstep/certificates) that operates in [registration authority (RA)](https://smallstep.com/docs/registration-authorities/) mode. It runs as a standalone server inside your enterprise environment, acting as an intermediary between your internal infrastructure and an external certificate authority service (such as Sectigo, DigiCert or ZeroSSL). It accepts certificate orders and validates certificate requests using the ACME protocol (RFC 8555), but does **NOT** sign certificates or store private keys. {{< image src="/assets/highlevel-flow.png" alt="sequence" >}} -# Certificate Request Flow +## Certificate issuance flow 1. Your internal server (behind a firewall perimeter) requests a certificate from `acme-proxy` using standard ACME clients like certbot, acme.sh or cert-manager.io if you're using Kubernetes. 2. `acme-proxy` presents cryptographic challenges to verify domain ownership @@ -17,3 +17,29 @@ title = 'ACME Proxy' 5. `acme-proxy` retrieves the certificate bundle and returns it to your server {{< image src="/assets/sequence.png" alt="sequence" >}} + +## Connectivity Requirements + +For the ACME certificate request issuance, renewal flow to work correctly, make sure your any internal firewalls, ACLs, IPtables rules permit the following traffic. + +**Client to acme-proxy (HTTPS/443)** + +Your servers running certbot must be able to connect to acme-proxy over HTTPS. + +``` +Source myserver.example.com +Destination acme-proxy.example.com +Protocol https (443) +Action allow +``` + +**acme-proxy to Client (HTTP/80)** + +`acme-proxy` validates HTTP-01 challenges by connecting to your servers directly on port 80. Your servers must allow inbound HTTP/80 from acme-proxy's IP — not from the public internet. This is the key security benefit: HTTP/80 exposure is limited to a trusted internal host rather than the global internet which is the case when using LetsEncrypt. + +``` +Source acme-proxy.example.com +Destination myserver.example.com +Protocol http (80) +Action allow +``` diff --git a/docs/content/client.md b/docs/content/client.md index 1f50e0b..4f41c68 100644 --- a/docs/content/client.md +++ b/docs/content/client.md @@ -23,8 +23,8 @@ For certificate issuance commands and per-scenario usage, see [user.md](./user.m ## Installing ACME Clients -### Certbot - +{{< tabs >}} +{{% tab "Certbot" %}} > **Note:** Certbot's actively maintained distribution is via Snap. The `.deb` packages available in apt repositories are no longer maintained by the Certbot project and ship outdated versions. Install via Snap: @@ -49,11 +49,9 @@ For the Apache plugin: sudo snap set certbot trust-plugin-with-root=ok sudo snap install certbot-apache ``` +{{% /tab %}} ---- - -### acme.sh - +{{% tab "acme.sh" %}} **Debian / Ubuntu:** ```bash @@ -71,11 +69,9 @@ sudo dnf install -y acme.sh socat The package installs the binary to `/usr/bin/acme.sh`. Use `/etc/acme.sh` as the configuration home for system-wide installations (passed via `--home` in all commands). > **`socat` is required for standalone mode.** acme.sh uses `socat` to bind port 80 for HTTP-01 challenges in standalone mode. It is installed above alongside acme.sh. This is not required if you use NGINX or Apache plugin mode. +{{% /tab %}} ---- - -### Lego - +{{% tab "Lego" %}} Lego has no official packages in major Linux distribution repositories. Install the release binary directly: ```bash @@ -88,6 +84,8 @@ lego --version ``` > Verify the checksum from the [GitHub releases page](https://github.com/go-acme/lego/releases) before deploying to production. Pin `LEGO_VERSION` in your configuration management tool and treat upgrades as a deliberate change. +{{% /tab %}} +{{< /tabs >}} --- @@ -95,22 +93,24 @@ lego --version Each ACME client must register an account with acme-proxy before any certificates can be issued. This is a one-time step per host. -### Certbot - +{{< tabs >}} +{{% tab "Certbot" %}} Certbot registers automatically on first use. No separate registration step is required. +{{% /tab %}} -### acme.sh - +{{% tab "acme.sh" %}} ```bash sudo acme.sh --register-account \ --server https://acme-proxy.example.com/acme/acme/directory \ --email admin@example.com \ --home /etc/acme.sh ``` +{{% /tab %}} -### Lego - +{{% tab "Lego" %}} Lego registers automatically on the first `run` invocation. No separate registration step is required. +{{% /tab %}} +{{< /tabs >}} --- @@ -124,10 +124,8 @@ Replacing cron-based renewal with systemd timers provides: All service units below set `SyslogIdentifier` so logs can be filtered by tag regardless of which syslog daemon is in use. ---- - -### Certbot - +{{< tabs >}} +{{% tab "Certbot" %}} The Snap-installed certbot ships `certbot.timer` and `certbot.service` units automatically. Enable the timer and confirm it is active: ```bash @@ -153,11 +151,9 @@ sudo systemctl daemon-reload ```bash sudo certbot renew --dry-run ``` +{{% /tab %}} ---- - -### acme.sh - +{{% tab "acme.sh" %}} acme.sh's `--cron` flag iterates over all configured certificates and renews those expiring within 30 days. A single service and timer unit covers all certificates on the host. **Create the service unit:** @@ -209,11 +205,9 @@ sudo systemctl enable --now acme-renewal.timer systemctl status acme-renewal.timer systemctl list-timers acme-renewal.timer ``` +{{% /tab %}} ---- - -### Lego - +{{% tab "Lego" %}} Lego has no built-in renewal scheduling. Create service and timer units manually. Unlike acme.sh and certbot, lego's `renew` command targets one domain at a time. If you manage multiple certificates, use a wrapper script. @@ -297,6 +291,8 @@ sudo systemctl enable --now lego-renewal.timer systemctl status lego-renewal.timer systemctl list-timers lego-renewal.timer ``` +{{% /tab %}} +{{< /tabs >}} --- diff --git a/docs/content/firewall.md b/docs/content/firewall.md deleted file mode 100644 index 86b0bb4..0000000 --- a/docs/content/firewall.md +++ /dev/null @@ -1,5 +0,0 @@ -+++ -title = 'Port Requirements' -weight = 60 -BookToC = true -+++ diff --git a/docs/content/install.md b/docs/content/install.md index 4d4804d..43febd7 100644 --- a/docs/content/install.md +++ b/docs/content/install.md @@ -42,9 +42,7 @@ Example — custom paths and user: ```sh curl -fsSL https://raw.githubusercontent.com/esnet/acme-proxy/main/install.sh | \ - sudo INSTALL_DIR=/usr/local/acme-proxy \ - SERVICE_USER=acmeservice \ - sh + sudo INSTALL_DIR=/usr/local/acme-proxy SERVICE_USER=acmeservice sh ``` ### What the script installs @@ -236,6 +234,7 @@ All install methods use the same `ca.json` configuration format. The install scr "account_email": "certadmin@example.com", "eab_kid": "your-eab-key-id", "eab_hmac_key": "your-eab-hmac-key", + "certlifetime": 30, "metrics": { "enabled": true, "port": 9234, @@ -275,6 +274,7 @@ All install methods use the same `ca.json` configuration format. The install scr | `authority.config.account_email` | Yes | Email registered with the upstream CA. | | `authority.config.eab_kid` | Yes | External Account Binding Key ID, obtained from your CA's account portal. | | `authority.config.eab_hmac_key` | Yes | External Account Binding HMAC key, obtained from your CA's account portal. | +| `authority.config.certlifetime` | No | Request certificate with a max lifetime period if supported by upstream CA | | `authority.config.metrics.enabled` | No | Expose Prometheus metrics. Default: `true`. | | `authority.config.metrics.port` | No | Metrics port. Default: `9234`. | | `db.dataSource` | Yes | Path to the bbolt KV store directory. Must be writable by the service user. | @@ -287,7 +287,9 @@ All install methods use the same `ca.json` configuration format. The install scr | Sectigo / InCommon RSA OV | `https://acme.sectigo.com/v2/InCommonRSAOV` | | ZeroSSL | `https://acme.zerossl.com/v2/DV90` | -> LetsEncrypt does not support External Account Binding and cannot be used as an upstream CA with acme-proxy. +>[!IMPORTANT] +>**Note**
+LetsEncrypt as a public certificate authority does not support ACME accounts via External Account Binding and hence it cannot be used as an upstream CA with acme-proxy. --- @@ -337,6 +339,14 @@ docker logs -f acme-proxy ```sh curl -s https://acmeproxy.example.com/acme/acme/directory | jq . + +{ + "newNonce": "https://proxy.example.com/acme/acme/new-nonce", + "newAccount": "https://proxy.example.com/acme/acme/new-account", + "newOrder": "https://proxy.example.com/acme/acme/new-order", + "revokeCert": "https://proxy.example.com/acme/acme/revoke-cert", + "keyChange": "https://proxy.example.com/acme/acme/key-change" +} ``` -A JSON object with `newNonce`, `newAccount`, `newOrder` keys confirms the server is running and accepting ACME requests. +A JSON object with `newNonce`, `newAccount`, `newOrder` keys confirms the ACME server is running and accepting requests. diff --git a/docs/content/quickstart.md b/docs/content/quickstart.md index c4ec806..2acf2ec 100644 --- a/docs/content/quickstart.md +++ b/docs/content/quickstart.md @@ -174,6 +174,6 @@ openssl x509 \ ## Next Steps -- **Set up ACME clients system-wide with auto-renewal** — [Admin Guide](admin.md) +- **Set up ACME clients system-wide with auto-renewal** — [Client Guide](client.md) - **Issue certificates for NGINX, Apache, Docker workloads** — [User Guide](user.md) - **Alternative install methods** (binary, source, Docker, full config reference) — [Install](install.md) diff --git a/docs/content/troubleshoot.md b/docs/content/troubleshoot.md deleted file mode 100644 index d111324..0000000 --- a/docs/content/troubleshoot.md +++ /dev/null @@ -1,5 +0,0 @@ -+++ -title = 'Troubleshoot' -weight = 20 -BookToC = true -+++ diff --git a/docs/content/user.md b/docs/content/user.md index 348ed9c..b4563f0 100644 --- a/docs/content/user.md +++ b/docs/content/user.md @@ -22,7 +22,7 @@ Replace `acme-proxy.example.com` with your organization's actual acme-proxy host - [1. NGINX on Linux VM / Baremetal](#1-nginx-on-linux-vm--baremetal) - [2. Apache on Linux VM / Baremetal](#2-apache-on-linux-vm--baremetal) -- [3. Standalone Mode](#3-standalone-mode-databases-redis-kafka-etc) +- [3. Standalone Mode (Databases, Redis, Kafka etc.)](#3-standalone-mode-databases-redis-kafka-etc) - [4. Docker and Docker Compose](#4-docker-and-docker-compose) - [5. Kubernetes (cert-manager)](#5-kubernetes-cert-manager) @@ -30,7 +30,7 @@ Replace `acme-proxy.example.com` with your organization's actual acme-proxy host ## Prerequisites -- The ACME client must be installed and an account registered with acme-proxy before running any commands in this guide. See [admin.md](./admin.md) for installation instructions and systemd renewal timer setup. +- The ACME client must be installed and an account registered with acme-proxy before running any commands in this guide. See [client.md](./client.md) for installation instructions and systemd renewal timer setup. - Port 80 must be reachable from the acme-proxy server (used for HTTP-01 challenge validation). - Your domain's DNS must resolve to the host where the ACME client runs. - Replace the following placeholders throughout this guide: @@ -42,8 +42,8 @@ Replace `acme-proxy.example.com` with your organization's actual acme-proxy host ## 1. NGINX on Linux VM / Baremetal -### 1a. acme.sh - +{{< tabs >}} +{{% tab "acme.sh" %}} **Register and issue a certificate (single domain):** ```bash @@ -78,12 +78,10 @@ acme.sh --install-cert -d myserver.example.com \ --reloadcmd "systemctl reload nginx" ``` -**Auto-renewal:** The systemd timer configured in [admin.md](./admin.md) drives renewal. acme.sh executes the `--reloadcmd` above after each successful renewal. - ---- - -### 1b. Certbot +**Auto-renewal:** The systemd timer configured in [client.md](./client.md) drives renewal. acme.sh executes the `--reloadcmd` above after each successful renewal. +{{% /tab %}} +{{% tab "Certbot" %}} **Register and issue a certificate (single domain):** ```bash @@ -108,12 +106,10 @@ sudo certbot --nginx \ -d api.myserver.example.com ``` -**Auto-renewal:** Managed by the certbot systemd timer. See [admin.md](./admin.md) for timer setup and log configuration. - ---- - -### 1c. Lego +**Auto-renewal:** Managed by the certbot systemd timer. See [client.md](./client.md) for timer setup and log configuration. +{{% /tab %}} +{{% tab "Lego" %}} Lego uses webroot mode with NGINX — the ACME challenge files are written to NGINX's document root and served over port 80. **Ensure NGINX serves the challenge path** — add this to your NGINX server block if not already present: @@ -161,14 +157,16 @@ ssl_certificate /root/.lego/certificates/myserver.example.com.crt; ssl_certificate_key /root/.lego/certificates/myserver.example.com.key; ``` -**Auto-renewal:** Managed by the systemd timer configured in [admin.md](./admin.md). Ask your admin to add `--renew-hook 'systemctl reload nginx'` to the lego renewal script for this domain. +**Auto-renewal:** Managed by the systemd timer configured in [client.md](./client.md). Ask your admin to add `--renew-hook 'systemctl reload nginx'` to the lego renewal script for this domain. +{{% /tab %}} +{{< /tabs >}} --- ## 2. Apache on Linux VM / Baremetal -### 2a. acme.sh - +{{< tabs >}} +{{% tab "acme.sh" %}} **Register and issue a certificate (single domain):** ```bash @@ -205,12 +203,10 @@ acme.sh --install-cert -d myserver.example.com \ > On RHEL-based systems use `httpd` instead of `apache2`. -**Auto-renewal:** The systemd timer configured in [admin.md](./admin.md) drives renewal. acme.sh executes the `--reloadcmd` above after each successful renewal. - ---- - -### 2b. Certbot +**Auto-renewal:** The systemd timer configured in [client.md](./client.md) drives renewal. acme.sh executes the `--reloadcmd` above after each successful renewal. +{{% /tab %}} +{{% tab "Certbot" %}} **Register and issue a certificate (single domain):** ```bash @@ -235,12 +231,10 @@ sudo certbot --apache \ -d api.myserver.example.com ``` -**Auto-renewal:** Managed by the certbot systemd timer. See [admin.md](./admin.md) for timer setup and log configuration. - ---- - -### 2c. Lego +**Auto-renewal:** Managed by the certbot systemd timer. See [client.md](./client.md) for timer setup and log configuration. +{{% /tab %}} +{{% tab "Lego" %}} Ensure Apache serves the challenge path. Add this to your VirtualHost configuration: ```apache @@ -287,7 +281,9 @@ SSLCertificateFile /root/.lego/certificates/myserver.example.com.crt SSLCertificateKeyFile /root/.lego/certificates/myserver.example.com.key ``` -**Auto-renewal:** Managed by the systemd timer configured in [admin.md](./admin.md). Ask your admin to add `--renew-hook 'systemctl reload apache2'` (or `httpd` on RHEL-based systems) to the lego renewal script for this domain. +**Auto-renewal:** Managed by the systemd timer configured in [client.md](./client.md). Ask your admin to add `--renew-hook 'systemctl reload apache2'` (or `httpd` on RHEL-based systems) to the lego renewal script for this domain. +{{% /tab %}} +{{< /tabs >}} --- @@ -295,17 +291,19 @@ SSLCertificateKeyFile /root/.lego/certificates/myserver.example.com.key Standalone mode runs a temporary HTTP server on port 80 to answer the ACME challenge. Use this when there is no existing web server — typical for backend services such as Databases, Redis, Kafka, etc. -> Port 80 must be temporarily available on the host. If IPtables or network firewall is in place, they must allow incoming http traffic from acme-proxy to the host. - -### 3a. acme.sh +> [!IMPORTANT] +> **Important** +Port 80 must be temporarily available on the host. If IPtables or network firewall is in place, they must allow incoming http traffic from acme-proxy to the host. See [Connectivity Requirements](_index.md/#connectivity-requirements) +{{< tabs >}} +{{% tab "acme.sh" %}} > acme.sh's standalone mode requires `socat`. The deb/rpm package may not install it on all distributions. Verify it is present before proceeding: > > ```bash > socat -V 2>/dev/null || echo "socat not found — install with: apt-get install socat / dnf install socat" > ``` > -> Certbot and lego (sections 3b and 3c) use their own built-in HTTP servers and do not require socat. +> Certbot and lego use their own built-in HTTP servers and do not require socat. **Register and issue a certificate (single domain):** @@ -340,12 +338,10 @@ acme.sh --install-cert -d myserver.example.com \ --reloadcmd "systemctl reload " ``` -**Auto-renewal:** The systemd timer configured in [admin.md](./admin.md) drives renewal. During each renewal attempt, acme.sh will again bind port 80 briefly — ensure no other process occupies it at the scheduled renewal time. - ---- - -### 3b. Certbot +**Auto-renewal:** The systemd timer configured in [client.md](./client.md) drives renewal. During each renewal attempt, acme.sh will again bind port 80 briefly — ensure no other process occupies it at the scheduled renewal time. +{{% /tab %}} +{{% tab "Certbot" %}} **Register and issue a certificate (single domain):** ```bash @@ -375,7 +371,7 @@ Certificates are stored in `/etc/letsencrypt/live/myserver.example.com/`. **Configure your service** to load certificates from: -``` +```text /etc/letsencrypt/live/myserver.example.com/fullchain.pem /etc/letsencrypt/live/myserver.example.com/privkey.pem ``` @@ -391,12 +387,10 @@ EOF sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-service.sh ``` -Certbot executes this script after each successful renewal. The systemd timer that triggers renewal is configured in [admin.md](./admin.md). - ---- - -### 3c. Lego +Certbot executes this script after each successful renewal. The systemd timer that triggers renewal is configured in [client.md](./client.md). +{{% /tab %}} +{{% tab "Lego" %}} **Issue a certificate (single domain):** ```bash @@ -424,7 +418,9 @@ lego \ Certificates are saved to `~/.lego/certificates/`. -**Auto-renewal:** Managed by the systemd timer configured in [admin.md](./admin.md). Ask your admin to add `--renew-hook 'systemctl reload '` to the lego renewal script for this domain. +**Auto-renewal:** Managed by the systemd timer configured in [client.md](./client.md). Ask your admin to add `--renew-hook 'systemctl reload '` to the lego renewal script for this domain. +{{% /tab %}} +{{< /tabs >}} --- @@ -432,7 +428,7 @@ Certificates are saved to `~/.lego/certificates/`. This section covers the pattern for services already running as Docker containers or Docker Compose stacks. The ACME client runs on the **host** — not inside a container. Certificates are stored on the host filesystem and projected into running containers as read-only volume mounts. After renewal, the host-side renewal hook signals the affected containers to reload or restart. -``` +```text Host ACME client → /etc/ssl/acme// → volume mount → container ↓ renewal hook → docker compose exec / docker compose restart @@ -508,7 +504,8 @@ Configure your application to load the TLS certificate from `/etc/ssl/app/` insi After each renewal, the certificate files on the host are updated. The container must either reload its TLS configuration or restart to pick them up. Configure the appropriate hook for each ACME client. -#### acme.sh +{{< tabs >}} +{{% tab "acme.sh" %}} ```bash acme.sh --install-cert -d myserver.example.com \ @@ -532,7 +529,9 @@ export Le_PostHook="docker compose -f /path/to/docker-compose.yml start myapp" acme.sh --renew -d myserver.example.com ``` -#### Certbot +{{% /tab %}} + +{{% tab "Certbot" %}} Create a deploy hook script that restarts the container after renewal: @@ -567,7 +566,9 @@ Enable the systemd timer as usual: sudo systemctl enable --now certbot.timer ``` -#### Lego +{{% /tab %}} + +{{% tab "Lego" %}} Use `--renew-hook` to restart the container after each successful renewal. Wrap the stop/start around the `renew` call in your cron entry: @@ -586,6 +587,9 @@ sudo tee /etc/cron.d/lego-docker-renewal <<'EOF' EOF ``` +{{% /tab %}} +{{< /tabs >}} + --- ## 5. Kubernetes (cert-manager) @@ -601,7 +605,7 @@ cert-manager is a Kubernetes-native certificate controller that speaks ACME nati **Network requirement:** acme-proxy must be able to reach **port 80** on the cluster's Gateway. The domain must resolve to the Gateway's external IP. -### Prerequisites +### cert-manager Prerequisites - cert-manager v1.15+ — Gateway API support is enabled by default; earlier versions require `--feature-gates=ExperimentalGatewayAPISupport=true` - Gateway API CRDs installed (`gateway.networking.k8s.io/v1`) @@ -681,7 +685,7 @@ kubectl get clusterissuer acme-proxy Expected output: -``` +```text NAME READY AGE acme-proxy True 30s ``` @@ -818,7 +822,7 @@ kubectl get secret myserver-tls \ --- -### Troubleshooting +### Diagnosing Certificate Issues If the certificate stays in `False` or `Issuing` state, follow the cert-manager object chain — each level narrows down where the failure occurred: @@ -835,7 +839,7 @@ kubectl describe challenge -n default The `Challenge` object's status message identifies the exact failure: | Symptom | Likely cause | -|---------|-------------| +| ------- | ------------ | | `ClusterIssuer` not ready | acme-proxy unreachable from cert-manager pods; wrong ACME directory URL | | Challenge stays `pending` | acme-proxy cannot reach the Gateway on port 80; domain DNS not pointing at the Gateway's external IP | | Challenge `HTTPRoute` not attached | Gateway HTTP listener `allowedRoutes` does not include the namespace where the `Certificate` lives | @@ -856,14 +860,15 @@ The three clients use different hook mechanisms. ### Hook phases | Phase | When it runs | Purpose | -|-------|-------------|---------| +| ----- | ------------ | ------- | | Pre-hook | Before the challenge attempt | Free port 80, drain connections | | Post-hook | After the challenge, regardless of outcome | Restore services stopped by pre-hook | | Deploy / renew hook | Only on successful issuance or renewal | Reload or restart the service using the certificate | --- -### acme.sh +{{< tabs >}} +{{% tab "acme.sh" %}} acme.sh supports hooks via command-line flags or by setting environment variables that it persists in the per-domain config file (`~/.acme.sh//.conf`). @@ -896,14 +901,14 @@ acme.sh --renew -d myserver.example.com grep -E 'Le_PreHook|Le_PostHook|Le_ReloadCmd' ~/.acme.sh/myserver.example.com/myserver.example.com.conf ``` ---- +{{% /tab %}} -### Certbot +{{% tab "Certbot" %}} Certbot uses a directory-based hook model. Any executable script placed in these directories runs for all certificates: | Directory | Phase | -|-----------|-------| +| --------- | ----- | | `/etc/letsencrypt/renewal-hooks/pre/` | Before challenge | | `/etc/letsencrypt/renewal-hooks/post/` | After challenge, regardless of outcome | | `/etc/letsencrypt/renewal-hooks/deploy/` | On successful renewal only | @@ -956,9 +961,9 @@ sudo certbot renew \ --deploy-hook "systemctl reload myapp" ``` ---- +{{% /tab %}} -### Lego +{{% tab "Lego" %}} Lego supports hooks via `--run-hook` (runs after successful initial issuance) and `--renew-hook` (runs after successful renewal). There is no persistent hook state — you must pass hooks in every invocation or via a wrapper script. @@ -1017,18 +1022,21 @@ sudo chmod 0700 /usr/local/sbin/lego-renew-myserver.sh Lego passes the following environment variables to hook scripts: | Variable | Value | -|----------|-------| +| -------- | ----- | | `LEGO_ACCOUNT_EMAIL` | Account email | | `LEGO_CERT_PATH` | Path to the certificate file | | `LEGO_CERT_KEY_PATH` | Path to the private key file | | `LEGO_CERT_DOMAIN` | Primary domain on the certificate | +{{% /tab %}} +{{< /tabs >}} + --- ## Troubleshooting | Symptom | Likely cause | Fix | -|---------|-------------|-----| +| ------- | ------------ | --- | | `connection refused` on port 80 | Firewall blocking challenge traffic | Open port 80 from acme-proxy host | | `no route to host` to acme-proxy | DNS not resolving or network ACL | Confirm the proxy hostname resolves and port 443 is reachable | | Certificate issued but service won't reload | `--reloadcmd` / deploy hook misconfigured | Run the reload command manually; check service name | diff --git a/docs/public/404.html b/docs/public/404.html index 4a73272..4fa0452 100644 --- a/docs/public/404.html +++ b/docs/public/404.html @@ -12,7 +12,7 @@ - + @@ -20,7 +20,7 @@ -404 Page not found | ACME Proxy +404 Page not found | acme-proxy @@ -28,7 +28,7 @@ - + @@ -115,7 +115,7 @@

Found

- ACME Proxy + acme-proxy

diff --git a/docs/public/admin/index.html b/docs/public/admin/index.html deleted file mode 100644 index 8862e4e..0000000 --- a/docs/public/admin/index.html +++ /dev/null @@ -1,573 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - -Administration Guide | ACME Proxy - - - - - - - - - - - - - - - - - - -
- - - - -
- - - - -

ACME Client Administration Guide#

-

This guide covers installation and system-level configuration of ACME clients for use with acme-proxy. It is intended for system administrators deploying certificate automation on behalf of end users.

-

For certificate issuance commands and per-scenario usage, see user.md.

-
- -

acme.sh is the recommended ACME client. Reasons:

-
    -
  • Distributed as native .deb and .rpm packages through standard Linux distribution repositories — no curl-pipe-to-shell installation.
  • -
  • Certbot’s only actively maintained distribution channel is Snap. The .deb packages in apt repositories are unmaintained and ship outdated versions. If your organization prohibits Snap packages, certbot is not viable.
  • -
  • acme.sh’s --cron mode renews all configured certificates in a single invocation, making a single systemd timer sufficient regardless of how many certificates are managed.
  • -
  • Lego has no maintained packages in major distribution repositories and requires manual binary management.
  • -
-
-

Table of Contents#

- -
-

Installing ACME Clients#

- -

Debian / Ubuntu:

-
sudo apt-get update
-sudo apt-get install -y acme.sh

RHEL / Rocky / AlmaLinux — requires EPEL:

-
sudo dnf install -y epel-release
-sudo dnf install -y acme.sh

The package installs the binary to /usr/bin/acme.sh. Use /etc/acme.sh as the configuration home for system-wide installations (passed via --home in all commands).

-
-

Standalone mode requires socat. acme.sh uses socat to bind port 80 for HTTP-01 challenges in standalone mode. Package dependencies vary by distribution — verify it is present before using standalone mode:

-
socat -V 2>/dev/null || echo "socat not found"

Install if missing: sudo apt-get install -y socat (Debian/Ubuntu) or sudo dnf install -y socat (RHEL/Rocky). This is not required if you use NGINX or Apache plugin mode.

-

-

Certbot#

-
-

Note: Certbot’s actively maintained distribution is via Snap. The .deb packages available in apt repositories are no longer maintained by the Certbot project and ship outdated versions. If your organization prohibits Snap, use acme.sh instead.

-

Install via Snap:

-
sudo snap install --classic certbot
-sudo ln -s /snap/bin/certbot /usr/local/bin/certbot

The Snap package installs certbot.timer and certbot.service systemd units automatically.

-

For the NGINX plugin:

-
sudo snap set certbot trust-plugin-with-root=ok
-sudo snap install certbot-nginx

For the Apache plugin:

-
sudo snap set certbot trust-plugin-with-root=ok
-sudo snap install certbot-apache

-

Lego#

-

Lego has no official packages in major Linux distribution repositories. Install the release binary directly:

-
LEGO_VERSION=4.33.0
-curl -fsSL "https://github.com/go-acme/lego/releases/download/v${LEGO_VERSION}/lego_v${LEGO_VERSION}_linux_amd64.tar.gz" \
-  | tar xz lego
-sudo install -o root -g root -m 0755 lego /usr/local/bin/lego
-rm lego
-lego --version
-

Verify the checksum from the GitHub releases page before deploying to production. Pin LEGO_VERSION in your configuration management tool and treat upgrades as a deliberate change.

-

-

Account Registration#

-

Each ACME client must register an account with acme-proxy before any certificates can be issued. This is a one-time step per host.

-

acme.sh#

-
sudo acme.sh --register-account \
-  --server https://acme-proxy.example.com/acme/acme/directory \
-  --email admin@example.com \
-  --home /etc/acme.sh

Certbot#

-

Certbot registers automatically on first use. No separate registration step is required.

-

Lego#

-

Lego registers automatically on the first run invocation. No separate registration step is required.

-
-

Configuring Auto-Renewal via Systemd#

-

Replacing cron-based renewal with systemd timers provides:

-
    -
  • Missed-run recovery via Persistent=true — if the system was off at the scheduled time, the timer fires on next boot.
  • -
  • Structured log output to the systemd journal, queryable and forwardable to syslog.
  • -
  • Visibility via systemctl list-timers.
  • -
-

All service units below set SyslogIdentifier so logs can be filtered by tag regardless of which syslog daemon is in use.

-
-

acme.sh#

-

acme.sh’s --cron flag iterates over all configured certificates and renews those expiring within 30 days. A single service and timer unit covers all certificates on the host.

-

Create the service unit:

-
sudo tee /etc/systemd/system/acme-renewal.service <<'EOF'
-[Unit]
-Description=Renew ACME certificates (acme.sh)
-After=network-online.target
-Wants=network-online.target
-
-[Service]
-Type=oneshot
-User=root
-ExecStart=/usr/bin/acme.sh --cron --home /etc/acme.sh
-StandardOutput=journal
-StandardError=journal
-SyslogIdentifier=acme-renewal
-EOF

Create the timer unit:

-
sudo tee /etc/systemd/system/acme-renewal.timer <<'EOF'
-[Unit]
-Description=Daily ACME certificate renewal check (acme.sh)
-
-[Timer]
-OnCalendar=daily
-RandomizedDelaySec=1h
-Persistent=true
-
-[Install]
-WantedBy=timers.target
-EOF

Enable and start:

-
sudo systemctl daemon-reload
-sudo systemctl enable --now acme-renewal.timer

Verify:

-
systemctl status acme-renewal.timer
-systemctl list-timers acme-renewal.timer

-

Certbot#

-

The Snap-installed certbot ships certbot.timer and certbot.service units automatically. Enable the timer and confirm it is active:

-
sudo systemctl enable --now certbot.timer
-systemctl status certbot.timer

Configure the SyslogIdentifier so certbot’s renewal logs are tagged consistently alongside other ACME clients:

-
sudo mkdir -p /etc/systemd/system/certbot.service.d
-sudo tee /etc/systemd/system/certbot.service.d/logging.conf <<'EOF'
-[Service]
-StandardOutput=journal
-StandardError=journal
-SyslogIdentifier=certbot-renewal
-EOF
-sudo systemctl daemon-reload

Test renewal without issuing:

-
sudo certbot renew --dry-run

-

Lego#

-

Lego has no built-in renewal scheduling. Create service and timer units manually.

-

Unlike acme.sh and certbot, lego’s renew command targets one domain at a time. If you manage multiple certificates, use a wrapper script.

-

Wrapper script for multiple certificates:

-
sudo tee /usr/local/sbin/lego-renew-all.sh <<'EOF'
-#!/bin/bash
-set -euo pipefail
-
-LEGO=/usr/local/bin/lego
-SERVER=https://acme-proxy.example.com/acme/acme/directory
-EMAIL=admin@example.com
-
-# Add each managed domain below
-domains=(
-  myserver.example.com
-  anotherserver.example.com
-)
-
-for domain in "${domains[@]}"; do
-  "$LEGO" \
-    --server "$SERVER" \
-    --accept-tos \
-    --email "$EMAIL" \
-    --http \
-    -d "$domain" \
-    renew
-done
-EOF
-sudo chmod 0700 /usr/local/sbin/lego-renew-all.sh

Create the service unit:

-
sudo tee /etc/systemd/system/lego-renewal.service <<'EOF'
-[Unit]
-Description=Renew ACME certificates (lego)
-After=network-online.target
-Wants=network-online.target
-
-[Service]
-Type=oneshot
-User=root
-ExecStart=/usr/local/sbin/lego-renew-all.sh
-StandardOutput=journal
-StandardError=journal
-SyslogIdentifier=lego-renewal
-EOF

Create the timer unit:

-
sudo tee /etc/systemd/system/lego-renewal.timer <<'EOF'
-[Unit]
-Description=Daily ACME certificate renewal check (lego)
-
-[Timer]
-OnCalendar=daily
-RandomizedDelaySec=1h
-Persistent=true
-
-[Install]
-WantedBy=timers.target
-EOF

Enable and start:

-
sudo systemctl daemon-reload
-sudo systemctl enable --now lego-renewal.timer

Verify:

-
systemctl status lego-renewal.timer
-systemctl list-timers lego-renewal.timer

-

Log Management#

-

All service units above write to the systemd journal with a unique SyslogIdentifier. Logs are accessible via journalctl and forwarded to syslog if your system runs rsyslog or syslog-ng with journal forwarding enabled.

-

Filter renewal logs by client:

- - - - - - - - - - - - - - - - - - - - - -
ClientCommand
acme.shjournalctl -t acme-renewal
Certbotjournalctl -t certbot-renewal
Legojournalctl -t lego-renewal
-

Follow logs in real time:

-
journalctl -t acme-renewal -f

Forward to syslog — rsyslog:

-

Ensure the journal input module is loaded in /etc/rsyslog.conf or a drop-in under /etc/rsyslog.d/:

-
module(load="imjournal" StateFile="imjournal.state")

Forward to syslog — syslog-ng:

-

Ensure the systemd-journal source is present in your syslog-ng configuration:

-
source s_systemd { systemd-journal(); };

Log retention:

-

Journal retention is controlled by /etc/systemd/journald.conf. Set MaxRetentionSec and SystemMaxUse appropriate to your environment:

-
[Journal]
-SystemMaxUse=500M
-MaxRetentionSec=90day

Apply changes with:

-
sudo systemctl restart systemd-journald
- - - -
- -
- -
- -
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - - - - - -
- - - - diff --git a/docs/public/assets/highlevel-flow.png b/docs/public/assets/highlevel-flow.png deleted file mode 100644 index 6528c56..0000000 Binary files a/docs/public/assets/highlevel-flow.png and /dev/null differ diff --git a/docs/public/assets/sequence.png b/docs/public/assets/sequence.png deleted file mode 100644 index 8397dbb..0000000 Binary files a/docs/public/assets/sequence.png and /dev/null differ diff --git a/docs/public/categories/index.html b/docs/public/categories/index.html index 9fc872e..eca4700 100644 --- a/docs/public/categories/index.html +++ b/docs/public/categories/index.html @@ -12,7 +12,7 @@ - + @@ -20,7 +20,7 @@ -Categories | ACME Proxy +Categories | acme-proxy @@ -28,12 +28,12 @@ - + - + - - - - - -
- - - - -
- - - - -
- - - -
- -
- -
- -
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/public/externalcas/index.html b/docs/public/externalcas/index.html deleted file mode 100644 index 5cf13ee..0000000 --- a/docs/public/externalcas/index.html +++ /dev/null @@ -1,368 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - -External CAs | ACME Proxy - - - - - - - - - - - - - - - - - - -
- - - - -
- - - - -

ACME server as Registration Authority#

-

See upstream docs section for more background on what registration authority, CAS are and how those concepts fits into step-ca architecture.

-

Certificate Authority Service (CAS)#

-

CAS provides a plugin based architecture that allows Step CA to delegate certificate signing to different backends - whether that’s Google Cloud, HashiCorp Vault, or in our case, external certificate authorities like Sectigo or ZeroSSL. ACME proxy can be run as a standalone ACME server in Registraiton Authority mode

-

ExternalCAS#

-

Step CA provides an interface called CertificateAuthorityService CAS to support external certificate authorities as the signing body. Our code in externalcas simply implements the CertificateAuthorityService interface.

-
type CertificateAuthorityService interface {
-    CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error)
-    RenewCertificate(req *RenewCertificateRequest) (*RenewCertificateResponse, error)
-    RevokeCertificate(req *RevokeCertificateRequest) (*RevokeCertificateResponse, error)
-}

The go package also defines a special type called ExternalCAS for this exact purpose. Which is why our ca.json file defines an authority of type: externalcas.

-
const (
-    // DefaultCAS is a CertificateAuthorityService using software.
-    DefaultCAS = ""
-    // SoftCAS is a CertificateAuthorityService using software.
-    SoftCAS = "softcas"
-    // CloudCAS is a CertificateAuthorityService using Google Cloud CAS.
-    CloudCAS = "cloudcas"
-    // StepCAS is a CertificateAuthorityService using another step-ca instance.
-    StepCAS = "stepcas"
-    // VaultCAS is a CertificateAuthorityService using Hasicorp Vault PKI.
-    VaultCAS = "vaultcas"
-    // ExternalCAS is a CertificateAuthorityService using an external injected CA implementation
-    ExternalCAS = "externalcas"
-)

Upstream docs#

-

Step CA github repo -https://github.com/smallstep/certificates/tree/master

-

Step CA Registration Authority (RA) -https://smallstep.com/docs/step-ca/registration-authority-ra-mode/

-

RA related github discussions

- -

Step CA full configuration options -https://smallstep.com/docs/step-ca/configuration/

-

Certificate issuance policy configuration -https://smallstep.com/docs/step-ca/policies/

-
- - - -
- -
- -
- -
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - - - - - -
- - - - diff --git a/docs/public/firewall/index.html b/docs/public/firewall/index.html deleted file mode 100644 index b8e1a15..0000000 --- a/docs/public/firewall/index.html +++ /dev/null @@ -1,323 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - -Port Requirements | ACME Proxy - - - - - - - - - - - - - - - - - - - -
- - - - -
- - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/public/index.html b/docs/public/index.html index b59cc4b..4ea4c25 100644 --- a/docs/public/index.html +++ b/docs/public/index.html @@ -1,7 +1,7 @@ - + - - - - - - - - - - - - - - - - - - -Maintenance | ACME Proxy - - - - - - - - - - - - - - - - - - -
- - - - -
- - - - -

Guide to patching upstream related changes#

-
    -
  • -

    While smallstep/certifiates is meant to serve as the upstream Go module for acme-proxy, we have to maintain some patches/fixes ourselves until they get merged upstream. Our patched version of step-ca is currently maintained in a forked repo esnet/certificates.

    -
  • -
  • -

    The branch naming scheme for our patches follow a pattern patch/upstream-version. For example: patches made against smallstep/certificates v0.30.2 are in a branch called patch/v0.30.2.

    -
  • -
  • -

    Once the patches have been applied and tested, we tag the commit using a naming scheme [upstream version]-patch.count. So if the patches have been applied against upstream v0.30.2 our go.mod in acme-proxy should contain

    -
  • -
-
replace github.com/smallstep/certificates => github.com/esnet/certificates v0.30.2-patch.2

Where the trailing patch.2 indicates total count of patches applied so far i.e two. Should we encounter another another bug in upstream v0.30.2 & have to maintain a third patch then we add our fix to github.com/esnet/certificates under branch patch/v0.30.2, test it & create a commit tag with v0.30.2-patch.3.

-
git tag -a v0.30.2-patch.3 -m "detailed commit message"
-git push --tags v0.30.2-patch.3
    -
  • Update the go.mod in acme-proxy repo to point to the new tag
  • -
-
replace github.com/smallstep/certificates => github.com/esnet/certificates v0.30.2-patch.3

As a best practice, use atomic commits for each patch with detailed commit message.

-
- - - -
- -
- -
- -
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - - - - - -
- - - - diff --git a/docs/public/manifest.json b/docs/public/manifest.json index 3994ae2..a278a62 100644 --- a/docs/public/manifest.json +++ b/docs/public/manifest.json @@ -1,6 +1,6 @@ { - "name": "ACME Proxy", - "short_name": "ACME Proxy", + "name": "acme-proxy", + "short_name": "acme-proxy", "start_url": "/", "scope": "/", "display": "standalone", diff --git a/docs/public/quickstart/index.html b/docs/public/quickstart/index.html index a20954b..e295b4f 100644 --- a/docs/public/quickstart/index.html +++ b/docs/public/quickstart/index.html @@ -16,7 +16,7 @@ - + -Quickstart | ACME Proxy +Quickstart | acme-proxy @@ -43,7 +43,7 @@ - + @@ -89,7 +89,7 @@