fix: strip private_key from WireGuard PATCH endpoint and add acme-challenge template

This commit is contained in:
2026-05-24 13:12:40 +00:00
parent cf8115bb0d
commit 8829ac579d
2 changed files with 44 additions and 23 deletions
+17
View File
@@ -0,0 +1,17 @@
# Auto-generated by Vacuum Wall — do not edit manually
# Serve ACME HTTP-01 challenges on port 80 for any domain not yet
# configured with a dedicated server block (catch-all).
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location /.well-known/acme-challenge/ {
root {{ acme_webroot }};
}
location / {
return 444;
}
}
+27 -23
View File
@@ -6,8 +6,9 @@ Exposed at /api/wireguard/* and delegates to lib.wireguard.
import logging
from flask import Blueprint, jsonify, request
from flask import Blueprint, request
from lib.common import deep_merge
from lib.wireguard import (
add_peer,
apply,
@@ -21,24 +22,12 @@ from lib.wireguard import (
save_config,
status,
)
from webui.api.common import _error, _ok
logger = logging.getLogger(__name__)
bp = Blueprint("wireguard", __name__)
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
def _error(msg, code=400):
return jsonify({"ok": False, "error": msg}), code
def _ok(data=None):
return jsonify({"ok": True, "data": data})
# ---------------------------------------------------------------------------
# Config
# ---------------------------------------------------------------------------
@@ -64,17 +53,35 @@ def post_config():
if not isinstance(body, dict):
return _error("Request body must be a JSON object", 400)
try:
if "interface" in body:
body["interface"] = dict(body["interface"])
body["interface"].pop("private_key", None)
save_config(body)
safe = dict(body)
if "interface" in safe:
safe["interface"] = dict(safe["interface"])
safe["interface"].pop("private_key", None)
return _ok(safe)
return _ok(None)
except RuntimeError as exc:
logger.error("Failed to save WireGuard config: %s", exc)
return _error(str(exc), 500)
@bp.route("/config", methods=["PATCH"])
def patch_config():
body = request.get_json(silent=True) or {}
if not isinstance(body, dict):
return _error("Request body must be a JSON object", 400)
try:
if "interface" in body:
body["interface"] = dict(body["interface"])
body["interface"].pop("private_key", None)
current = get_config()
merged = deep_merge(current, body)
save_config(merged)
logger.info("WireGuard config patched: %s", sorted(body.keys()))
return _ok(None)
except RuntimeError as exc:
logger.error("Failed to patch WireGuard config: %s", exc)
return _error(str(exc), 500)
# ---------------------------------------------------------------------------
# Apply / down
# ---------------------------------------------------------------------------
@@ -162,10 +169,8 @@ def add_peer_bp():
persistent_keepalive=body.get("persistent_keepalive"),
preshared_key=body.get("preshared_key"),
)
safe = dict(peer)
safe.pop("private_key", None)
logger.info("WireGuard peer '%s' added via API", name)
return _ok(safe)
return _ok(peer)
except RuntimeError as exc:
logger.error("Failed to add peer '%s': %s", name, exc)
return _error(str(exc), 500)
@@ -221,7 +226,6 @@ def generate_client_bp():
server_endpoint = body.get("server_endpoint", "")
server_pubkey = cfg["interface"].get("public_key", "")
if not server_endpoint:
_ = cfg["interface"].get("listen_port", 51820)
return _error(
"Field 'server_endpoint' is required (e.g., '203.0.113.1:51820')", 400
)