docs: explain internal CA onboarding and client trust setup
- commit
- ef180bceb03d2aa26102396ee5d147fd682ceeac
- author
- brice · · 2026-04-01 09:44 UTC
- parent
- 956a990
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
3 files · +137 -1
A docs/cli/ca.md +124 -0
| @@ -0,0 +1,124 @@ | |||
| 1 | + | # CA Commands | |
| 2 | + | ||
| 3 | + | Manage Gordon's internal Certificate Authority. | |
| 4 | + | ||
| 5 | + | ## gordon ca | |
| 6 | + | ||
| 7 | + | ### Subcommands | |
| 8 | + | ||
| 9 | + | | Subcommand | Description | | |
| 10 | + | |------------|-------------| | |
| 11 | + | | `export` | Export the root CA certificate in PEM format | | |
| 12 | + | | `info` | Show CA status (root CN, fingerprint, intermediate expiry) | | |
| 13 | + | | `install` | Install/uninstall the root CA in system trust stores | | |
| 14 | + | ||
| 15 | + | All subcommands require `server.tls_port` to be non-zero in the Gordon configuration. | |
| 16 | + | ||
| 17 | + | --- | |
| 18 | + | ||
| 19 | + | ## gordon ca export | |
| 20 | + | ||
| 21 | + | Export the root CA certificate for manual trust installation on clients. | |
| 22 | + | ||
| 23 | + | ```bash | |
| 24 | + | gordon ca export # Print PEM to stdout | |
| 25 | + | gordon ca export --out ca.pem # Write to file | |
| 26 | + | ``` | |
| 27 | + | ||
| 28 | + | ### Options | |
| 29 | + | ||
| 30 | + | | Option | Description | | |
| 31 | + | |--------|-------------| | |
| 32 | + | | `--out` | Write certificate to file instead of stdout | | |
| 33 | + | ||
| 34 | + | --- | |
| 35 | + | ||
| 36 | + | ## gordon ca info | |
| 37 | + | ||
| 38 | + | Show CA status information: root common name, SHA-256 fingerprint, and intermediate certificate expiry. | |
| 39 | + | ||
| 40 | + | ```bash | |
| 41 | + | gordon ca info | |
| 42 | + | gordon ca info --json | |
| 43 | + | ``` | |
| 44 | + | ||
| 45 | + | ### Options | |
| 46 | + | ||
| 47 | + | | Option | Description | | |
| 48 | + | |--------|-------------| | |
| 49 | + | | `--json` | Output as JSON | | |
| 50 | + | ||
| 51 | + | ### JSON Output | |
| 52 | + | ||
| 53 | + | ```json | |
| 54 | + | { | |
| 55 | + | "root_cn": "Gordon Internal Root CA", | |
| 56 | + | "fingerprint": "SHA256:AB:CD:...", | |
| 57 | + | "intermediate_expiry": "2026-07-01T12:00:00Z", | |
| 58 | + | "intermediate_ttl": "2160h0m0s" | |
| 59 | + | } | |
| 60 | + | ``` | |
| 61 | + | ||
| 62 | + | --- | |
| 63 | + | ||
| 64 | + | ## gordon ca install | |
| 65 | + | ||
| 66 | + | Install or uninstall the root CA certificate in system, Firefox, and Java trust stores on the **Gordon host machine**. Requires root privileges. | |
| 67 | + | ||
| 68 | + | ```bash | |
| 69 | + | sudo gordon ca install | |
| 70 | + | sudo gordon ca install --uninstall | |
| 71 | + | ``` | |
| 72 | + | ||
| 73 | + | ### Options | |
| 74 | + | ||
| 75 | + | | Option | Description | | |
| 76 | + | |--------|-------------| | |
| 77 | + | | `--uninstall` | Remove the CA from trust stores instead of installing | | |
| 78 | + | | `--json` | Output as JSON | | |
| 79 | + | ||
| 80 | + | > **Important:** This command is for the machine running Gordon, not for arbitrary clients. Remote users should import the certificate through one of the methods below. | |
| 81 | + | ||
| 82 | + | --- | |
| 83 | + | ||
| 84 | + | ## Client Trust Setup | |
| 85 | + | ||
| 86 | + | Clients that connect directly to Gordon's HTTPS port need the root CA certificate in their trust store. Gordon provides the certificate through a browser-accessible onboarding page at `https://<gordon-host>:<tls_port>/ca`, or over plain HTTP at `http://<gordon-host>:<port>/ca` for first-time setup. | |
| 87 | + | ||
| 88 | + | ### Firefox / Zen (NSS certificate store) | |
| 89 | + | ||
| 90 | + | Firefox and Zen use their own certificate store, separate from the OS. | |
| 91 | + | ||
| 92 | + | 1. Open `https://<gordon-host>:<tls_port>/ca.crt` — Firefox will prompt to import the certificate. | |
| 93 | + | 2. Check **Trust this CA to identify websites** and confirm. | |
| 94 | + | ||
| 95 | + | Alternatively, import manually: **Settings > Privacy & Security > Certificates > View Certificates > Import**. | |
| 96 | + | ||
| 97 | + | ### Linux System Trust Store | |
| 98 | + | ||
| 99 | + | ```bash | |
| 100 | + | # Download the certificate | |
| 101 | + | curl -k https://<gordon-host>:<tls_port>/ca.crt -o gordon-ca.pem | |
| 102 | + | ||
| 103 | + | # Debian / Ubuntu | |
| 104 | + | sudo cp gordon-ca.pem /usr/local/share/ca-certificates/gordon-ca.crt | |
| 105 | + | sudo update-ca-certificates | |
| 106 | + | ||
| 107 | + | # Fedora / RHEL | |
| 108 | + | sudo cp gordon-ca.pem /etc/pki/ca-trust/source/anchors/gordon-ca.pem | |
| 109 | + | sudo update-ca-trust | |
| 110 | + | ``` | |
| 111 | + | ||
| 112 | + | ### Mobile Devices (iOS / Android) | |
| 113 | + | ||
| 114 | + | Visit `http://<gordon-host>:<port>/ca` from the device browser. The onboarding page offers: | |
| 115 | + | ||
| 116 | + | - **iOS:** Download the `.mobileconfig` profile, then install it in **Settings > General > VPN & Device Management**. | |
| 117 | + | - **Android:** Download `ca.crt`, then install it in **Settings > Security > Encryption & credentials > Install a certificate**. | |
| 118 | + | ||
| 119 | + | --- | |
| 120 | + | ||
| 121 | + | ## Related | |
| 122 | + | ||
| 123 | + | - [Server Configuration](../config/server.md) — `tls_port`, `force_https_redirect`, and internal CA settings | |
| 124 | + | - [CLI Commands](./index.md) | |
| @@ -0,0 +1,124 @@ | |||||
| 1 | + | # CA Commands | |||
| 2 | + | ||||
| 3 | + | Manage Gordon's internal Certificate Authority. | |||
| 4 | + | ||||
| 5 | + | ## gordon ca | |||
| 6 | + | ||||
| 7 | + | ### Subcommands | |||
| 8 | + | ||||
| 9 | + | | Subcommand | Description | | |||
| 10 | + | |------------|-------------| | |||
| 11 | + | | `export` | Export the root CA certificate in PEM format | | |||
| 12 | + | | `info` | Show CA status (root CN, fingerprint, intermediate expiry) | | |||
| 13 | + | | `install` | Install/uninstall the root CA in system trust stores | | |||
| 14 | + | ||||
| 15 | + | All subcommands require `server.tls_port` to be non-zero in the Gordon configuration. | |||
| 16 | + | ||||
| 17 | + | --- | |||
| 18 | + | ||||
| 19 | + | ## gordon ca export | |||
| 20 | + | ||||
| 21 | + | Export the root CA certificate for manual trust installation on clients. | |||
| 22 | + | ||||
| 23 | + | ```bash | |||
| 24 | + | gordon ca export # Print PEM to stdout | |||
| 25 | + | gordon ca export --out ca.pem # Write to file | |||
| 26 | + | ``` | |||
| 27 | + | ||||
| 28 | + | ### Options | |||
| 29 | + | ||||
| 30 | + | | Option | Description | | |||
| 31 | + | |--------|-------------| | |||
| 32 | + | | `--out` | Write certificate to file instead of stdout | | |||
| 33 | + | ||||
| 34 | + | --- | |||
| 35 | + | ||||
| 36 | + | ## gordon ca info | |||
| 37 | + | ||||
| 38 | + | Show CA status information: root common name, SHA-256 fingerprint, and intermediate certificate expiry. | |||
| 39 | + | ||||
| 40 | + | ```bash | |||
| 41 | + | gordon ca info | |||
| 42 | + | gordon ca info --json | |||
| 43 | + | ``` | |||
| 44 | + | ||||
| 45 | + | ### Options | |||
| 46 | + | ||||
| 47 | + | | Option | Description | | |||
| 48 | + | |--------|-------------| | |||
| 49 | + | | `--json` | Output as JSON | | |||
| 50 | + | ||||
| 51 | + | ### JSON Output | |||
| 52 | + | ||||
| 53 | + | ```json | |||
| 54 | + | { | |||
| 55 | + | "root_cn": "Gordon Internal Root CA", | |||
| 56 | + | "fingerprint": "SHA256:AB:CD:...", | |||
| 57 | + | "intermediate_expiry": "2026-07-01T12:00:00Z", | |||
| 58 | + | "intermediate_ttl": "2160h0m0s" | |||
| 59 | + | } | |||
| 60 | + | ``` | |||
| 61 | + | ||||
| 62 | + | --- | |||
| 63 | + | ||||
| 64 | + | ## gordon ca install | |||
| 65 | + | ||||
| 66 | + | Install or uninstall the root CA certificate in system, Firefox, and Java trust stores on the **Gordon host machine**. Requires root privileges. | |||
| 67 | + | ||||
| 68 | + | ```bash | |||
| 69 | + | sudo gordon ca install | |||
| 70 | + | sudo gordon ca install --uninstall | |||
| 71 | + | ``` | |||
| 72 | + | ||||
| 73 | + | ### Options | |||
| 74 | + | ||||
| 75 | + | | Option | Description | | |||
| 76 | + | |--------|-------------| | |||
| 77 | + | | `--uninstall` | Remove the CA from trust stores instead of installing | | |||
| 78 | + | | `--json` | Output as JSON | | |||
| 79 | + | ||||
| 80 | + | > **Important:** This command is for the machine running Gordon, not for arbitrary clients. Remote users should import the certificate through one of the methods below. | |||
| 81 | + | ||||
| 82 | + | --- | |||
| 83 | + | ||||
| 84 | + | ## Client Trust Setup | |||
| 85 | + | ||||
| 86 | + | Clients that connect directly to Gordon's HTTPS port need the root CA certificate in their trust store. Gordon provides the certificate through a browser-accessible onboarding page at `https://<gordon-host>:<tls_port>/ca`, or over plain HTTP at `http://<gordon-host>:<port>/ca` for first-time setup. | |||
| 87 | + | ||||
| 88 | + | ### Firefox / Zen (NSS certificate store) | |||
| 89 | + | ||||
| 90 | + | Firefox and Zen use their own certificate store, separate from the OS. | |||
| 91 | + | ||||
| 92 | + | 1. Open `https://<gordon-host>:<tls_port>/ca.crt` — Firefox will prompt to import the certificate. | |||
| 93 | + | 2. Check **Trust this CA to identify websites** and confirm. | |||
| 94 | + | ||||
| 95 | + | Alternatively, import manually: **Settings > Privacy & Security > Certificates > View Certificates > Import**. | |||
| 96 | + | ||||
| 97 | + | ### Linux System Trust Store | |||
| 98 | + | ||||
| 99 | + | ```bash | |||
| 100 | + | # Download the certificate | |||
| 101 | + | curl -k https://<gordon-host>:<tls_port>/ca.crt -o gordon-ca.pem | |||
| 102 | + | ||||
| 103 | + | # Debian / Ubuntu | |||
| 104 | + | sudo cp gordon-ca.pem /usr/local/share/ca-certificates/gordon-ca.crt | |||
| 105 | + | sudo update-ca-certificates | |||
| 106 | + | ||||
| 107 | + | # Fedora / RHEL | |||
| 108 | + | sudo cp gordon-ca.pem /etc/pki/ca-trust/source/anchors/gordon-ca.pem | |||
| 109 | + | sudo update-ca-trust | |||
| 110 | + | ``` | |||
| 111 | + | ||||
| 112 | + | ### Mobile Devices (iOS / Android) | |||
| 113 | + | ||||
| 114 | + | Visit `http://<gordon-host>:<port>/ca` from the device browser. The onboarding page offers: | |||
| 115 | + | ||||
| 116 | + | - **iOS:** Download the `.mobileconfig` profile, then install it in **Settings > General > VPN & Device Management**. | |||
| 117 | + | - **Android:** Download `ca.crt`, then install it in **Settings > Security > Encryption & credentials > Install a certificate**. | |||
| 118 | + | ||||
| 119 | + | --- | |||
| 120 | + | ||||
| 121 | + | ## Related | |||
| 122 | + | ||||
| 123 | + | - [Server Configuration](../config/server.md) — `tls_port`, `force_https_redirect`, and internal CA settings | |||
| 124 | + | - [CLI Commands](./index.md) | |||
M docs/cli/index.md +1 -0
| @@ -16,6 +16,7 @@ Commands are organized by where they run: | |||
| 16 | 16 | |---------|-------------|---------------| | |
| 17 | 17 | | `gordon serve` | Start the Gordon server | [serve](./serve.md) | | |
| 18 | 18 | | `gordon auth` | Manage Gordon server authentication | [auth](./auth.md) | | |
| 19 | + | | `gordon ca` | Manage the internal Certificate Authority | [ca](./ca.md) | | |
| 19 | 20 | ||
| 20 | 21 | ## Management Commands (local or remote) | |
| 21 | 22 | ||
| @@ -16,6 +16,7 @@ Commands are organized by where they run: | |||||
| 16 | |---------|-------------|---------------| | 16 | |---------|-------------|---------------| | ||
| 17 | | `gordon serve` | Start the Gordon server | [serve](./serve.md) | | 17 | | `gordon serve` | Start the Gordon server | [serve](./serve.md) | | ||
| 18 | | `gordon auth` | Manage Gordon server authentication | [auth](./auth.md) | | 18 | | `gordon auth` | Manage Gordon server authentication | [auth](./auth.md) | | ||
| 19 | + | | `gordon ca` | Manage the internal Certificate Authority | [ca](./ca.md) | | |||
| 19 | 20 | ||||
| 20 | ## Management Commands (local or remote) | 21 | ## Management Commands (local or remote) | ||
| 21 | 22 | ||||
M docs/config/server.md +12 -1
| @@ -81,9 +81,20 @@ tls_key_file = "/etc/gordon/tls/key.pem" | |||
| 81 | 81 | ||
| 82 | 82 | The static certificate is served for SNI-matching domains (including wildcards). All other domains get on-demand certs from the internal CA. | |
| 83 | 83 | ||
| 84 | + | #### Direct HTTP Onboarding | |
| 85 | + | ||
| 86 | + | When `tls_port` is non-zero, direct HTTP clients (those not arriving through a trusted proxy) are restricted to CA onboarding paths only: | |
| 87 | + | ||
| 88 | + | - `/`, `/ca`, `/ca.crt`, `/ca.mobileconfig` — serve the onboarding page and CA certificate downloads | |
| 89 | + | - All other paths return `403 Forbidden` | |
| 90 | + | ||
| 91 | + | This lets new clients discover and trust the internal CA over plain HTTP without exposing the full application. Trusted proxy traffic (e.g. from Cloudflare) continues through the normal HTTP proxy path unaffected. | |
| 92 | + | ||
| 93 | + | The onboarding page is also available on HTTPS at `/ca`. | |
| 94 | + | ||
| 84 | 95 | #### HTTP to HTTPS redirect | |
| 85 | 96 | ||
| 86 | - | When clients connect directly (no Cloudflare or reverse proxy in front), enable `force_https_redirect` to redirect all HTTP traffic to the HTTPS port: | |
| 97 | + | When clients connect directly (no Cloudflare or reverse proxy in front), enable `force_https_redirect` to redirect all HTTP traffic to the HTTPS port. Direct HTTP onboarding paths are still served even with this flag enabled. | |
| 87 | 98 | ||
| 88 | 99 | ```toml | |
| 89 | 100 | [server] | |
| @@ -81,9 +81,20 @@ tls_key_file = "/etc/gordon/tls/key.pem" | |||||
| 81 | 81 | ||||
| 82 | The static certificate is served for SNI-matching domains (including wildcards). All other domains get on-demand certs from the internal CA. | 82 | The static certificate is served for SNI-matching domains (including wildcards). All other domains get on-demand certs from the internal CA. | ||
| 83 | 83 | ||||
| 84 | + | #### Direct HTTP Onboarding | |||
| 85 | + | ||||
| 86 | + | When `tls_port` is non-zero, direct HTTP clients (those not arriving through a trusted proxy) are restricted to CA onboarding paths only: | |||
| 87 | + | ||||
| 88 | + | - `/`, `/ca`, `/ca.crt`, `/ca.mobileconfig` — serve the onboarding page and CA certificate downloads | |||
| 89 | + | - All other paths return `403 Forbidden` | |||
| 90 | + | ||||
| 91 | + | This lets new clients discover and trust the internal CA over plain HTTP without exposing the full application. Trusted proxy traffic (e.g. from Cloudflare) continues through the normal HTTP proxy path unaffected. | |||
| 92 | + | ||||
| 93 | + | The onboarding page is also available on HTTPS at `/ca`. | |||
| 94 | + | ||||
| 84 | #### HTTP to HTTPS redirect | 95 | #### HTTP to HTTPS redirect | ||
| 85 | 96 | ||||
| 86 | - | When clients connect directly (no Cloudflare or reverse proxy in front), enable `force_https_redirect` to redirect all HTTP traffic to the HTTPS port: | 97 | + | When clients connect directly (no Cloudflare or reverse proxy in front), enable `force_https_redirect` to redirect all HTTP traffic to the HTTPS port. Direct HTTP onboarding paths are still served even with this flag enabled. |
| 87 | 98 | ||||
| 88 | ```toml | 99 | ```toml | ||
| 89 | [server] | 100 | [server] | ||