feat: add ACME account management with validation pipeline
- Register, view, and deactivate ACME accounts via API and UI - 16-check validation framework for certificate issuance readiness - DNS resolution, port, nginx, and firewall pre-flight checks - External IP detection with NAT support and fallback providers - Account card and settings modal in certificates page - Guard certificate issuance behind account registration - Update modal CSS to overlay-based approach - 1000+ lines of tests for validation and account handlers
This commit is contained in:
@@ -167,6 +167,96 @@ The `ssl` block defines TLS parameters applied to all HTTPS server blocks via th
|
||||
| `ciphers` | string | No | nginx `ssl_ciphers` directive value. Default is a curated AEAD-only cipher string. |
|
||||
| `prefer_server_ciphers` | boolean | No | Whether to prefer server cipher order. Default: `false`. |
|
||||
|
||||
## ACME (Certificate) Configuration
|
||||
|
||||
**File**: `config/acme/config.json`
|
||||
|
||||
This file stores the ACME account settings used by acme.sh for certificate provisioning. Account registration, modification, and deactivation are performed through the WebUI at the Certificates page — not by editing this file directly.
|
||||
|
||||
```json
|
||||
{
|
||||
"email": "admin@example.com",
|
||||
"ca": "letsencrypt"
|
||||
}
|
||||
```
|
||||
|
||||
### ACME Fields
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|---|---|---|---|
|
||||
| `email` | string | No | Contact email for the ACME account. Used for certificate expiry notifications and recovery. Populated automatically when an account is registered via the WebUI. Default: `""`. |
|
||||
| `ca` | string | No | ACME CA provider. One of: `"letsencrypt"` (Let's Encrypt), `"zerossl"` (ZeroSSL). Populated automatically when an account is registered. Default: `""`. |
|
||||
|
||||
### Account Registration
|
||||
|
||||
ACME account registration is handled entirely through the WebUI. When the user registers an account:
|
||||
|
||||
1. The user navigates to the Certificates page and clicks "Register Account".
|
||||
2. Provides an email address and selects a CA provider (Let's Encrypt or ZeroSSL).
|
||||
3. The backend calls `acme.sh --register-account` with the provided parameters.
|
||||
4. On success, the `email` and `ca` fields in `config/acme/config.json` are populated, and acme.sh writes its `.account.conf` file under `data/acme/`.
|
||||
|
||||
Before any certificate can be issued, an ACME account must be registered. The certificate validation flow includes a blocking check (`account_registered`) that prevents issuance if no account exists.
|
||||
|
||||
### Account Management
|
||||
|
||||
After registration, the account can be managed from the WebUI:
|
||||
|
||||
- **Update email**: The Settings modal allows changing the contact email, which triggers an update via `acme.sh --register-account -u`.
|
||||
- **Deactivate account**: The Settings modal includes a button to deactivate the account via `acme.sh --deactivate-account`, which clears the `email` and `ca` fields and removes the ACME account.
|
||||
|
||||
### ACME Home Directory
|
||||
|
||||
acme.sh stores its state under `data/acme/` (the ACME home directory). Key files:
|
||||
|
||||
- `.account.conf` — ACME account credentials and settings (contains `ACME_LEEMAIL`, `ACME_MCA`).
|
||||
- `<domain>/` — Per-domain certificate and key files issued by acme.sh.
|
||||
|
||||
The application reads `.account.conf` to determine registration status. If the file is missing or lacks required keys, the account is considered unregistered.
|
||||
|
||||
## ACME Configuration
|
||||
|
||||
**File**: `config/acme/config.json`
|
||||
|
||||
This file stores the ACME account settings used by vacuum-wall for automatic certificate issuance via acme.sh. Account registration is performed exclusively through the WebUI — the Certificates page provides a "Register Account" modal where the user enters an email and selects a CA provider.
|
||||
|
||||
```json
|
||||
{
|
||||
"email": "",
|
||||
"ca": ""
|
||||
}
|
||||
```
|
||||
|
||||
### ACME Config Fields
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|---|---|---|---|
|
||||
| `email` | string | No (WebUI) | Contact email for the ACME account, used for certificate expiry notifications and recovery. Populated when the user registers an account via the WebUI. Default: `""`. |
|
||||
| `ca` | string | No (defaults to `letsencrypt`) | ACME CA provider. One of: `"letsencrypt"`, `"zerossl"`. Populated during account registration. Default: `""` (acme.sh defaults to Let's Encrypt if omitted). |
|
||||
|
||||
### Account Registration Flow
|
||||
|
||||
1. User navigates to the Certificates page in the WebUI.
|
||||
2. Clicks "Register Account" and provides an email address, optionally selecting a CA provider.
|
||||
3. The application calls `acme.sh --register-account -m <email> --server <ca>` as a privileged operation via the daemon.
|
||||
4. On success, `config/acme/config.json` is updated with the email and CA. acme.sh writes its own state to `data/acme/.account.conf`.
|
||||
5. The `account_registered` check in the certificate validation pipeline transitions from blocking to passing, enabling certificate issuance.
|
||||
|
||||
The `account_registered` check is **blocking** — certificate issuance and validation will fail until an ACME account is registered. The `email_configured` check is **non-blocking** — it produces a warning if the email is empty but does not prevent issuance.
|
||||
|
||||
### Account Management API
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
|---|---|---|
|
||||
| `/api/certs/account` | `GET` | Returns account status: registered, email, CA provider. |
|
||||
| `/api/certs/account/register` | `POST` | Registers a new ACME account. Body: `{ "email": "..." }`. Optional: `{ "server": "letsencrypt" }`. |
|
||||
| `/api/certs/account` | `DELETE` | Deactivates the ACME account via `acme.sh --deactivate-account`. Clears email and CA from config. |
|
||||
| `/api/certs/email` | `POST` | Updates the contact email on an existing account. Body: `{ "email": "..." }`. |
|
||||
|
||||
### ACME Home Directory
|
||||
|
||||
acme.sh stores its operational state under `data/acme/`. The application reads `data/acme/.account.conf` to determine whether an account is registered. Required keys: `ACME_LEEMAIL` and `ACME_MCA`. Their absence or the file's absence means the account is unregistered.
|
||||
|
||||
## WireGuard Configuration
|
||||
|
||||
**File**: `config/wireguard/config.json`
|
||||
|
||||
Reference in New Issue
Block a user