fix: /https/settings shows the https section and switches https.acme_staging, for the Router Manager.
Release / release (push) Successful in 56s
Release / release (push) Successful in 56s
This commit is contained in:
1 parent
f36e2a3b04
commit
c2c33cfca0
5 files changed
+68
-3
No files matched your search
@@ -537,7 +537,9 @@ unchanged. Both services always listen on `127.0.0.1` as well as on the interfac
|
|||||||
never takes from the client. Let's Encrypt issues at most 5 certificates a week for the same
|
never takes from the client. Let's Encrypt issues at most 5 certificates a week for the same
|
||||||
names, which routers rebuilt for tests reach; `https.acme_staging` sets Caddy's global `acme_ca`
|
names, which routers rebuilt for tests reach; `https.acme_staging` sets Caddy's global `acme_ca`
|
||||||
to Let's Encrypt's staging directory, which replaces Caddy's default CAs for every site, so no
|
to Let's Encrypt's staging directory, which replaces Caddy's default CAs for every site, so no
|
||||||
test certificate comes from a production CA.
|
test certificate comes from a production CA. `PUT /https/settings` changes `acme_staging` alone:
|
||||||
|
the other settings of the section switch HTTPS off or move its ports, which would end the
|
||||||
|
connection the Router Manager makes the change on.
|
||||||
|
|
||||||
Consequences: HTTPS needs `wan.local_fqdn` in public DNS pointing at the router and port 80
|
Consequences: HTTPS needs `wan.local_fqdn` in public DNS pointing at the router and port 80
|
||||||
reachable from the internet; until then Caddy retries and the HTTPS ports do not answer. The
|
reachable from the internet; until then Caddy retries and the HTTPS ports do not answer. The
|
||||||
|
|||||||
@@ -1018,7 +1018,7 @@ curl http://10.0.0.4:7081/status
|
|||||||
|
|
||||||
### Tokens and signing in
|
### Tokens and signing in
|
||||||
|
|
||||||
`/config`, `/metrics/history`, `/metrics/settings`, `/users`, `/service-accounts`, `/groups`, `/site-to-site`, `/backup`, `/remote-access`, `/ca`, `/logs`, `/sites`, `/dns`, `/shell` and `/account` need a JWT in an `Authorization: Bearer` header, signed with
|
`/config`, `/metrics/history`, `/metrics/settings`, `/https/settings`, `/users`, `/service-accounts`, `/groups`, `/site-to-site`, `/backup`, `/remote-access`, `/ca`, `/logs`, `/sites`, `/dns`, `/shell` and `/account` need a JWT in an `Authorization: Bearer` header, signed with
|
||||||
HS256 by the key the web service makes on its first run, `/etc/vpn-router/web.key` (root only).
|
HS256 by the key the web service makes on its first run, `/etc/vpn-router/web.key` (root only).
|
||||||
The key never leaves the router; while it does not exist these paths and `/auth` are not served
|
The key never leaves the router; while it does not exist these paths and `/auth` are not served
|
||||||
(404). A missing, expired or wrongly signed token, or one of another algorithm, gets 401 with
|
(404). A missing, expired or wrongly signed token, or one of another algorithm, gets 401 with
|
||||||
@@ -1405,6 +1405,18 @@ A change is made, checked and applied as for `/site-to-site`.
|
|||||||
|
|
||||||
A change is made, checked and applied as for `/site-to-site`.
|
A change is made, checked and applied as for `/site-to-site`.
|
||||||
|
|
||||||
|
### The /https/settings API
|
||||||
|
|
||||||
|
`/https/settings` shows the settings of HTTPS and changes the CA of Caddy's certificates, with the
|
||||||
|
same token as `/users`.
|
||||||
|
|
||||||
|
| Request | Body | Answer |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `GET /https/settings` | | `{"settings"}`: the `https` section |
|
||||||
|
| `PUT /https/settings` | `{"acme_staging"}`; any other setting of the `https` section is 400, as it is changed on the router with `vpn-config-edit` | `{"settings"}` |
|
||||||
|
|
||||||
|
A change is made, checked and applied as for `/site-to-site`.
|
||||||
|
|
||||||
### The /remote-access API
|
### The /remote-access API
|
||||||
|
|
||||||
`/remote-access` shows and changes the remote access systems, IKEv2 (`p2s`),
|
`/remote-access` shows and changes the remote access systems, IKEv2 (`p2s`),
|
||||||
@@ -1484,6 +1496,9 @@ obtains from an ACME CA, those of the web sites with `tls` `acme` included.
|
|||||||
vpn-config-edit set --restart https.acme_staging true
|
vpn-config-edit set --restart https.acme_staging true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The Router Manager switches it on the Overview, and `PUT /https/settings` changes it (see The
|
||||||
|
/https/settings API).
|
||||||
|
|
||||||
`vpn-router-setup` writes Caddy's configuration to `/etc/caddy/vpn-router.Caddyfile` (root, group
|
`vpn-router-setup` writes Caddy's configuration to `/etc/caddy/vpn-router.Caddyfile` (root, group
|
||||||
`caddy`, the group Caddy runs as, mode 0640), which the
|
`caddy`, the group Caddy runs as, mode 0640), which the
|
||||||
package's drop-in `/usr/lib/systemd/system/caddy.service.d/vpn-router.conf` makes `caddy.service`
|
package's drop-in `/usr/lib/systemd/system/caddy.service.d/vpn-router.conf` makes `caddy.service`
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
vpn-router (0.38.1-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
fix: /https/settings shows the https section and switches https.acme_staging, for the Router Manager.
|
||||||
|
|
||||||
|
* GET /https/settings shows the https section, and PUT /https/settings
|
||||||
|
changes acme_staging; the other settings of the section stay with
|
||||||
|
vpn-config-edit.
|
||||||
|
|
||||||
|
-- Slawomir Koszewski <slawek@koszewscy.waw.pl> Fri, 30 Oct 2026 02:43:22 +0100
|
||||||
|
|
||||||
vpn-router (0.38.0-1) unstable; urgency=medium
|
vpn-router (0.38.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
feature: https.acme_staging takes Caddy's certificates from Let's Encrypt's staging environment.
|
feature: https.acme_staging takes Caddy's certificates from Let's Encrypt's staging environment.
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ from .connectivity import remote_access, site_to_site
|
|||||||
from .dns import dns
|
from .dns import dns
|
||||||
from .identities import account, groups, service_accounts, users
|
from .identities import account, groups, service_accounts, users
|
||||||
from .logs import logs
|
from .logs import logs
|
||||||
|
from .https import https_settings
|
||||||
from .metrics import metrics_history, metrics_settings
|
from .metrics import metrics_history, metrics_settings
|
||||||
from .pki import PUBLISHED, ca
|
from .pki import PUBLISHED, ca
|
||||||
from .shell import EDITOR_BODY_LIMIT, shell, shell_editor, shell_passkey, shell_ticket
|
from .shell import EDITOR_BODY_LIMIT, shell, shell_editor, shell_passkey, shell_ticket
|
||||||
@@ -66,7 +67,8 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
directory = next((name for name in ('users', 'service-accounts', 'groups', 'account', 'site-to-site', 'backup',
|
directory = next((name for name in ('users', 'service-accounts', 'groups', 'account', 'site-to-site', 'backup',
|
||||||
'ca', 'shell', 'remote-access', 'logs', 'sites', 'dns')
|
'ca', 'shell', 'remote-access', 'logs', 'sites', 'dns')
|
||||||
if path == f'/{name}' or path.startswith(f'/{name}/')), None)
|
if path == f'/{name}' or path.startswith(f'/{name}/')), None)
|
||||||
protected = path in ('/status/full', '/config', '/metrics/history', '/metrics/settings', '/postgresql') or \
|
protected = path in ('/status/full', '/config', '/metrics/history', '/metrics/settings', '/https/settings',
|
||||||
|
'/postgresql') or \
|
||||||
directory is not None
|
directory is not None
|
||||||
signing = path in ('/auth', '/auth/passkey', '/auth/passkey/complete', '/auth/refresh', '/auth/logout')
|
signing = path in ('/auth', '/auth/passkey', '/auth/passkey/complete', '/auth/refresh', '/auth/logout')
|
||||||
oidc = (path == '/.well-known/openid-configuration' or path.startswith('/oidc/')) and \
|
oidc = (path == '/.well-known/openid-configuration' or path.startswith('/oidc/')) and \
|
||||||
@@ -113,6 +115,9 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
elif path == '/metrics/settings':
|
elif path == '/metrics/settings':
|
||||||
code, document = metrics_settings(self.command, payload)
|
code, document = metrics_settings(self.command, payload)
|
||||||
body, kind = json.dumps(document, indent=2).encode() + b'\n', 'application/json'
|
body, kind = json.dumps(document, indent=2).encode() + b'\n', 'application/json'
|
||||||
|
elif path == '/https/settings':
|
||||||
|
code, document = https_settings(self.command, payload)
|
||||||
|
body, kind = json.dumps(document, indent=2).encode() + b'\n', 'application/json'
|
||||||
elif directory == 'shell' and (path, self.command) == ('/shell', 'GET'):
|
elif directory == 'shell' and (path, self.command) == ('/shell', 'GET'):
|
||||||
return shell(self, claims.get('sub'))
|
return shell(self, claims.get('sub'))
|
||||||
elif directory == 'shell' and path.startswith('/shell/editor/'):
|
elif directory == 'shell' and path.startswith('/shell/editor/'):
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
"""/https/settings: the settings of HTTPS, of which the API changes the CA of Caddy's certificates."""
|
||||||
|
|
||||||
|
import vpnrouter
|
||||||
|
|
||||||
|
from .common import section_change
|
||||||
|
|
||||||
|
#: The settings of the https section PUT /https/settings changes.
|
||||||
|
CHANGEABLE = ('acme_staging',)
|
||||||
|
|
||||||
|
|
||||||
|
def https_settings(method, body):
|
||||||
|
"""Answer a /https/settings request: the HTTP status and the JSON document.
|
||||||
|
|
||||||
|
GET /https/settings {"settings"}: the https section
|
||||||
|
PUT /https/settings change acme_staging; the other settings of the section are changed on the router with
|
||||||
|
vpn-config-edit, and a body naming one is 400
|
||||||
|
|
||||||
|
A change is applied by restarting vpn-router-setup without waiting for it.
|
||||||
|
"""
|
||||||
|
if body == 'invalid' or (body is not None and not isinstance(body, dict)):
|
||||||
|
return 400, {'error': 'the body must be a JSON object'}
|
||||||
|
if method in ('GET', 'HEAD'):
|
||||||
|
try:
|
||||||
|
return 200, {'settings': vpnrouter.load_config()['https']}
|
||||||
|
except SystemExit as exc:
|
||||||
|
return 500, {'error': str(exc.code)}
|
||||||
|
if method != 'PUT':
|
||||||
|
return 404, {'error': f'no route {method} /https/settings'}
|
||||||
|
others = sorted(set(body or {}) - set(CHANGEABLE))
|
||||||
|
if others:
|
||||||
|
return 400, {'error': f'https.{", https.".join(others)}: changed on the router with vpn-config-edit only'}
|
||||||
|
changed = section_change('https', body or {})
|
||||||
|
return changed if isinstance(changed, tuple) else (200, {'settings': changed})
|
||||||
Reference in new issue
Block a user