docs: document tailnet-only registry access and self-signed remote setup
- commit
- a8641690d5d21e5baf1c817566e85617ad8ae675
- author
- brice · · 2026-02-08 12:31 UTC
- parent
- 37ac30f
- signature
- unsigned
3 files · +96 -3
M docs/config/server.md +18 -0
| @@ -69,6 +69,24 @@ With TLS enabled: | |||
| 69 | 69 | - `port` remains available for plain HTTP unless you restrict it externally | |
| 70 | 70 | - If `tls_cert_file`/`tls_key_file` are empty, Gordon auto-generates a self-signed pair in `{data_dir}/tls/` | |
| 71 | 71 | ||
| 72 | + | For rootless user services, do not bind directly to `443`. Use an unprivileged TLS port (for example `8443`) and forward `443` to it at the firewall or edge proxy. | |
| 73 | + | ||
| 74 | + | ```toml | |
| 75 | + | [server] | |
| 76 | + | tls_enabled = true | |
| 77 | + | tls_port = 8443 | |
| 78 | + | ``` | |
| 79 | + | ||
| 80 | + | With firewalld and Tailscale (`tailscale0` in `trusted` zone): | |
| 81 | + | ||
| 82 | + | ```bash | |
| 83 | + | sudo firewall-cmd --zone=trusted --add-rich-rule='rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443' | |
| 84 | + | sudo firewall-cmd --zone=trusted --add-rich-rule='rule family=ipv6 forward-port port=443 protocol=tcp to-port=8443' | |
| 85 | + | sudo firewall-cmd --permanent --zone=trusted --add-rich-rule='rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443' | |
| 86 | + | sudo firewall-cmd --permanent --zone=trusted --add-rich-rule='rule family=ipv6 forward-port port=443 protocol=tcp to-port=8443' | |
| 87 | + | sudo firewall-cmd --reload | |
| 88 | + | ``` | |
| 89 | + | ||
| 72 | 90 | ### Registry Port | |
| 73 | 91 | ||
| 74 | 92 | The `registry_port` setting controls where Gordon accepts image pushes: | |
| @@ -69,6 +69,24 @@ With TLS enabled: | |||||
| 69 | - `port` remains available for plain HTTP unless you restrict it externally | 69 | - `port` remains available for plain HTTP unless you restrict it externally | ||
| 70 | - If `tls_cert_file`/`tls_key_file` are empty, Gordon auto-generates a self-signed pair in `{data_dir}/tls/` | 70 | - If `tls_cert_file`/`tls_key_file` are empty, Gordon auto-generates a self-signed pair in `{data_dir}/tls/` | ||
| 71 | 71 | ||||
| 72 | + | For rootless user services, do not bind directly to `443`. Use an unprivileged TLS port (for example `8443`) and forward `443` to it at the firewall or edge proxy. | |||
| 73 | + | ||||
| 74 | + | ```toml | |||
| 75 | + | [server] | |||
| 76 | + | tls_enabled = true | |||
| 77 | + | tls_port = 8443 | |||
| 78 | + | ``` | |||
| 79 | + | ||||
| 80 | + | With firewalld and Tailscale (`tailscale0` in `trusted` zone): | |||
| 81 | + | ||||
| 82 | + | ```bash | |||
| 83 | + | sudo firewall-cmd --zone=trusted --add-rich-rule='rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443' | |||
| 84 | + | sudo firewall-cmd --zone=trusted --add-rich-rule='rule family=ipv6 forward-port port=443 protocol=tcp to-port=8443' | |||
| 85 | + | sudo firewall-cmd --permanent --zone=trusted --add-rich-rule='rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443' | |||
| 86 | + | sudo firewall-cmd --permanent --zone=trusted --add-rich-rule='rule family=ipv6 forward-port port=443 protocol=tcp to-port=8443' | |||
| 87 | + | sudo firewall-cmd --reload | |||
| 88 | + | ``` | |||
| 89 | + | ||||
| 72 | ### Registry Port | 90 | ### Registry Port | ||
| 73 | 91 | ||||
| 74 | The `registry_port` setting controls where Gordon accepts image pushes: | 92 | The `registry_port` setting controls where Gordon accepts image pushes: | ||
M wiki/guides/remote-cli.md +29 -3
| @@ -18,15 +18,40 @@ Manage Gordon instances remotely using the CLI with the `--remote` flag or saved | |||
| 18 | 18 | ||
| 19 | 19 | ## Understanding the Remote URL | |
| 20 | 20 | ||
| 21 | - | The `--remote` URL must be the `gordon_domain` configured on the remote Gordon instance. This domain serves both the container registry and the Admin API. | |
| 21 | + | Default: use the Gordon registry domain configured on the remote instance. | |
| 22 | 22 | ||
| 23 | 23 | ```toml | |
| 24 | 24 | # On the remote Gordon server | |
| 25 | 25 | [server] | |
| 26 | - | gordon_domain = "gordon.example.com" # Use this as --remote URL | |
| 26 | + | registry_domain = "reg.example.com" # Use this as --remote URL | |
| 27 | 27 | ``` | |
| 28 | 28 | ||
| 29 | - | The CLI connects to `https://gordon.example.com/admin/*` endpoints. | |
| 29 | + | The CLI connects to `https://reg.example.com/admin/*` endpoints. | |
| 30 | + | ||
| 31 | + | Private tailnet setup (recommended for hardened VPS): keep using the HTTPS domain, point that DNS record to the VPS tailnet IP, and set insecure TLS for self-signed certs. | |
| 32 | + | ||
| 33 | + | ```bash | |
| 34 | + | # Save remote once | |
| 35 | + | gordon remotes add tailnet-reg https://gordon.example.com --token-env GORDON_TOKEN --insecure | |
| 36 | + | gordon remotes use tailnet-reg | |
| 37 | + | ||
| 38 | + | # Use it for auth/admin commands | |
| 39 | + | gordon auth login | |
| 40 | + | gordon routes list | |
| 41 | + | ``` | |
| 42 | + | ||
| 43 | + | Equivalent `remotes.toml` entry: | |
| 44 | + | ||
| 45 | + | ```toml | |
| 46 | + | active = "tailnet-reg" | |
| 47 | + | ||
| 48 | + | [remotes.tailnet-reg] | |
| 49 | + | url = "https://gordon.example.com" | |
| 50 | + | token_env = "GORDON_TOKEN" | |
| 51 | + | insecure_tls = true | |
| 52 | + | ``` | |
| 53 | + | ||
| 54 | + | Use this mode when registry/auth/admin access is intentionally restricted to tailnet CIDRs. | |
| 30 | 55 | ||
| 31 | 56 | ## Quick Start | |
| 32 | 57 | ||
| @@ -65,6 +90,7 @@ These flags are available on all commands: | |||
| 65 | 90 | |------|-------------| | |
| 66 | 91 | | `--remote <URL>` | Remote Gordon URL | | |
| 67 | 92 | | `--token <TOKEN>` | Authentication token | | |
| 93 | + | | `--insecure` | Skip TLS verification (self-signed/private certs) | | |
| 68 | 94 | ||
| 69 | 95 | ```bash | |
| 70 | 96 | # List routes on remote | |
| @@ -18,15 +18,40 @@ Manage Gordon instances remotely using the CLI with the `--remote` flag or saved | |||||
| 18 | 18 | ||||
| 19 | ## Understanding the Remote URL | 19 | ## Understanding the Remote URL | ||
| 20 | 20 | ||||
| 21 | - | The `--remote` URL must be the `gordon_domain` configured on the remote Gordon instance. This domain serves both the container registry and the Admin API. | 21 | + | Default: use the Gordon registry domain configured on the remote instance. |
| 22 | 22 | ||||
| 23 | ```toml | 23 | ```toml | ||
| 24 | # On the remote Gordon server | 24 | # On the remote Gordon server | ||
| 25 | [server] | 25 | [server] | ||
| 26 | - | gordon_domain = "gordon.example.com" # Use this as --remote URL | 26 | + | registry_domain = "reg.example.com" # Use this as --remote URL |
| 27 | ``` | 27 | ``` | ||
| 28 | 28 | ||||
| 29 | - | The CLI connects to `https://gordon.example.com/admin/*` endpoints. | 29 | + | The CLI connects to `https://reg.example.com/admin/*` endpoints. |
| 30 | + | ||||
| 31 | + | Private tailnet setup (recommended for hardened VPS): keep using the HTTPS domain, point that DNS record to the VPS tailnet IP, and set insecure TLS for self-signed certs. | |||
| 32 | + | ||||
| 33 | + | ```bash | |||
| 34 | + | # Save remote once | |||
| 35 | + | gordon remotes add tailnet-reg https://gordon.example.com --token-env GORDON_TOKEN --insecure | |||
| 36 | + | gordon remotes use tailnet-reg | |||
| 37 | + | ||||
| 38 | + | # Use it for auth/admin commands | |||
| 39 | + | gordon auth login | |||
| 40 | + | gordon routes list | |||
| 41 | + | ``` | |||
| 42 | + | ||||
| 43 | + | Equivalent `remotes.toml` entry: | |||
| 44 | + | ||||
| 45 | + | ```toml | |||
| 46 | + | active = "tailnet-reg" | |||
| 47 | + | ||||
| 48 | + | [remotes.tailnet-reg] | |||
| 49 | + | url = "https://gordon.example.com" | |||
| 50 | + | token_env = "GORDON_TOKEN" | |||
| 51 | + | insecure_tls = true | |||
| 52 | + | ``` | |||
| 53 | + | ||||
| 54 | + | Use this mode when registry/auth/admin access is intentionally restricted to tailnet CIDRs. | |||
| 30 | 55 | ||||
| 31 | ## Quick Start | 56 | ## Quick Start | ||
| 32 | 57 | ||||
| @@ -65,6 +90,7 @@ These flags are available on all commands: | |||||
| 65 | |------|-------------| | 90 | |------|-------------| | ||
| 66 | | `--remote <URL>` | Remote Gordon URL | | 91 | | `--remote <URL>` | Remote Gordon URL | | ||
| 67 | | `--token <TOKEN>` | Authentication token | | 92 | | `--token <TOKEN>` | Authentication token | | ||
| 93 | + | | `--insecure` | Skip TLS verification (self-signed/private certs) | | |||
| 68 | 94 | ||||
| 69 | ```bash | 95 | ```bash | ||
| 70 | # List routes on remote | 96 | # List routes on remote | ||
M wiki/guides/secure-vps-setup.md +49 -0
| @@ -142,6 +142,55 @@ Verify public SSH is blocked: | |||
| 142 | 142 | ssh -o ConnectTimeout=5 root@<public-ip> # Should timeout | |
| 143 | 143 | ``` | |
| 144 | 144 | ||
| 145 | + | ## Step 6.5: Restrict Registry and Auth to Tailnet CIDR | |
| 146 | + | ||
| 147 | + | If you want `/auth/*` and registry (`/v2/*`) reachable only from your tailnet, set Gordon's registry allowlist to the Tailscale CGNAT range. | |
| 148 | + | ||
| 149 | + | Edit `~/.config/gordon/gordon.toml`: | |
| 150 | + | ||
| 151 | + | ```toml | |
| 152 | + | [server] | |
| 153 | + | registry_allowed_ips = ["100.64.0.0/10"] | |
| 154 | + | ``` | |
| 155 | + | ||
| 156 | + | Apply the change: | |
| 157 | + | ||
| 158 | + | ```bash | |
| 159 | + | systemctl --user restart gordon | |
| 160 | + | ``` | |
| 161 | + | ||
| 162 | + | Behavior: | |
| 163 | + | ||
| 164 | + | - Requests from tailnet IPs (`100.64.0.0/10`) are allowed. | |
| 165 | + | - Requests outside that CIDR get `403 Forbidden` on registry/auth endpoints. | |
| 166 | + | - App routes still use normal host-based routing through your proxy ports. | |
| 167 | + | ||
| 168 | + | For private operations (auth, push/pull, admin API), keep using the HTTPS registry domain, but resolve that domain to the VPS tailnet IP (for example, via Cloudflare DNS to the tailnet address). With self-signed certs, configure the CLI remote with insecure TLS enabled. | |
| 169 | + | ||
| 170 | + | ```bash | |
| 171 | + | # Example: save remote once | |
| 172 | + | gordon remotes add tailnet-reg https://gordon.example.com --token-env GORDON_TOKEN --insecure | |
| 173 | + | gordon remotes use tailnet-reg | |
| 174 | + | ||
| 175 | + | # Then use commands normally (auth + admin API) | |
| 176 | + | gordon auth login | |
| 177 | + | gordon routes list | |
| 178 | + | gordon backup status | |
| 179 | + | ``` | |
| 180 | + | ||
| 181 | + | `~/.config/gordon/remotes.toml` should contain an entry like: | |
| 182 | + | ||
| 183 | + | ```toml | |
| 184 | + | active = "tailnet-reg" | |
| 185 | + | ||
| 186 | + | [remotes.tailnet-reg] | |
| 187 | + | url = "https://gordon.example.com" | |
| 188 | + | token_env = "GORDON_TOKEN" | |
| 189 | + | insecure_tls = true | |
| 190 | + | ``` | |
| 191 | + | ||
| 192 | + | This keeps transport on HTTPS while allowing self-signed certificates in tailnet-only deployments. | |
| 193 | + | ||
| 145 | 194 | --- | |
| 146 | 195 | ||
| 147 | 196 | ## Step 7: Install CrowdSec | |
| @@ -142,6 +142,55 @@ Verify public SSH is blocked: | |||||
| 142 | ssh -o ConnectTimeout=5 root@<public-ip> # Should timeout | 142 | ssh -o ConnectTimeout=5 root@<public-ip> # Should timeout | ||
| 143 | ``` | 143 | ``` | ||
| 144 | 144 | ||||
| 145 | + | ## Step 6.5: Restrict Registry and Auth to Tailnet CIDR | |||
| 146 | + | ||||
| 147 | + | If you want `/auth/*` and registry (`/v2/*`) reachable only from your tailnet, set Gordon's registry allowlist to the Tailscale CGNAT range. | |||
| 148 | + | ||||
| 149 | + | Edit `~/.config/gordon/gordon.toml`: | |||
| 150 | + | ||||
| 151 | + | ```toml | |||
| 152 | + | [server] | |||
| 153 | + | registry_allowed_ips = ["100.64.0.0/10"] | |||
| 154 | + | ``` | |||
| 155 | + | ||||
| 156 | + | Apply the change: | |||
| 157 | + | ||||
| 158 | + | ```bash | |||
| 159 | + | systemctl --user restart gordon | |||
| 160 | + | ``` | |||
| 161 | + | ||||
| 162 | + | Behavior: | |||
| 163 | + | ||||
| 164 | + | - Requests from tailnet IPs (`100.64.0.0/10`) are allowed. | |||
| 165 | + | - Requests outside that CIDR get `403 Forbidden` on registry/auth endpoints. | |||
| 166 | + | - App routes still use normal host-based routing through your proxy ports. | |||
| 167 | + | ||||
| 168 | + | For private operations (auth, push/pull, admin API), keep using the HTTPS registry domain, but resolve that domain to the VPS tailnet IP (for example, via Cloudflare DNS to the tailnet address). With self-signed certs, configure the CLI remote with insecure TLS enabled. | |||
| 169 | + | ||||
| 170 | + | ```bash | |||
| 171 | + | # Example: save remote once | |||
| 172 | + | gordon remotes add tailnet-reg https://gordon.example.com --token-env GORDON_TOKEN --insecure | |||
| 173 | + | gordon remotes use tailnet-reg | |||
| 174 | + | ||||
| 175 | + | # Then use commands normally (auth + admin API) | |||
| 176 | + | gordon auth login | |||
| 177 | + | gordon routes list | |||
| 178 | + | gordon backup status | |||
| 179 | + | ``` | |||
| 180 | + | ||||
| 181 | + | `~/.config/gordon/remotes.toml` should contain an entry like: | |||
| 182 | + | ||||
| 183 | + | ```toml | |||
| 184 | + | active = "tailnet-reg" | |||
| 185 | + | ||||
| 186 | + | [remotes.tailnet-reg] | |||
| 187 | + | url = "https://gordon.example.com" | |||
| 188 | + | token_env = "GORDON_TOKEN" | |||
| 189 | + | insecure_tls = true | |||
| 190 | + | ``` | |||
| 191 | + | ||||
| 192 | + | This keeps transport on HTTPS while allowing self-signed certificates in tailnet-only deployments. | |||
| 193 | + | ||||
| 145 | --- | 194 | --- | ||
| 146 | 195 | ||||
| 147 | ## Step 7: Install CrowdSec | 196 | ## Step 7: Install CrowdSec | ||