fix: advertise WireGuard endpoint by domain, and reach linked cells over HTTPS
Unit Tests / test (push) Successful in 9m50s

Three related cell-link/peer-config fixes (the peer and cell endpoints were
showing the raw external IP, which confused public-vs-internal addressing):

1. Peer WireGuard configs now embed the cell's effective domain (DDNS/ACME
   modes) instead of the detected external IP, via the new
   WireGuardManager.get_advertised_endpoint(). A name that resolves to the
   public IP survives IP changes and lets the datacenter forward each cell's
   WG port to the right host. LAN mode still falls back to the IP; an admin
   wireguard_endpoint override still wins.

2. Cell invites advertise <effective-domain>:<this cell's WG port> (was the
   external IP + a default/possibly-wrong port), so a remote cell pairs to the
   right host and port over the public path.

3. Cross-cell peer-sync no longer targets http://<ip>:3000 (the API binds
   127.0.0.1 and is unreachable across cells). It targets the remote's Caddy on
   HTTPS/443 — which the WireGuard server already DNATs over the tunnel — and the
   initial pre-tunnel invite push goes to https://<endpoint-host>/... ; legacy
   http://<ip>:3000 link URLs migrate to https on load.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-16 04:21:16 -04:00
parent fa746a3b30
commit 1bb8a5eb59
6 changed files with 181 additions and 37 deletions
+4 -8
View File
@@ -8,15 +8,11 @@ bp = Blueprint('wireguard', __name__)
def _effective_endpoint(wireguard_manager, config_manager) -> str:
"""Return the WireGuard endpoint to embed in peer configs.
Uses wireguard_endpoint from identity config when set (admin override),
falling back to get_external_ip() detection.
Prefers the cell's public domain (DDNS/ACME modes) or an admin override over
the raw external IP, so a peer config points at a name that resolves to the
cell rather than a bare IP. See WireGuardManager.get_advertised_endpoint.
"""
srv = wireguard_manager.get_server_config()
override = (config_manager.get_identity().get('wireguard_endpoint') or '').strip()
if override:
port = srv.get('port', 51820)
return override if ':' in override else f'{override}:{port}'
return srv.get('endpoint') or '<SERVER_IP>'
return wireguard_manager.get_advertised_endpoint(config_manager) or '<SERVER_IP>'
@bp.route('/api/wireguard/keys', methods=['GET'])
def get_wireguard_keys():