fix: consolidate WireGuard port config and propagate port changes to UI
- docker-compose: fix WireGuard port mapping to ${WG_PORT}:${WG_PORT} so
the daemon ListenPort matches the Docker host-to-container binding
- app.py: sync wireguard.port ↔ identity.wireguard_port in both directions
so changing either keeps them consistent; identity path now also updates
wg0.conf via wireguard_manager.update_config
- Settings.jsx: remove duplicate wireguard_port from Cell Identity section
(port is configurable under WireGuard VPN service config); add
refreshConfig() after saveService so other pages see new values immediately
- WireGuard.jsx: import useConfig() and use service_configs.wireguard.port
as the reactive port source for endpoint display and port-open warnings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+12
-1
@@ -474,6 +474,12 @@ def update_config():
|
|||||||
n = len(peer_registry.list_peers())
|
n = len(peer_registry.list_peers())
|
||||||
if n:
|
if n:
|
||||||
all_warnings.append(f'WireGuard endpoint changed — {n} peer(s) must reinstall VPN config')
|
all_warnings.append(f'WireGuard endpoint changed — {n} peer(s) must reinstall VPN config')
|
||||||
|
# Keep identity.wireguard_port in sync with service config port
|
||||||
|
if 'port' in config:
|
||||||
|
_id = config_manager.configs.get('_identity', {})
|
||||||
|
_id['wireguard_port'] = config['port']
|
||||||
|
config_manager.configs['_identity'] = _id
|
||||||
|
config_manager._save_all_configs()
|
||||||
|
|
||||||
# Apply cell identity domain to network and email services
|
# Apply cell identity domain to network and email services
|
||||||
if identity_updates.get('domain'):
|
if identity_updates.get('domain'):
|
||||||
@@ -542,11 +548,16 @@ def update_config():
|
|||||||
f'{svc_key} {field}: {old_val} → {new_val}'
|
f'{svc_key} {field}: {old_val} → {new_val}'
|
||||||
)
|
)
|
||||||
|
|
||||||
# wireguard_port in identity also drives WG_PORT env var
|
# wireguard_port in identity also drives WG_PORT env var; sync to service config
|
||||||
if 'wireguard_port' in identity_updates:
|
if 'wireguard_port' in identity_updates:
|
||||||
old_wg = old_identity.get('wireguard_port')
|
old_wg = old_identity.get('wireguard_port')
|
||||||
new_wg = identity_updates['wireguard_port']
|
new_wg = identity_updates['wireguard_port']
|
||||||
if old_wg is not None and old_wg != new_wg:
|
if old_wg is not None and old_wg != new_wg:
|
||||||
|
# Sync to wireguard service config and update wg0.conf
|
||||||
|
_wg_svc = config_manager.configs.get('wireguard', {})
|
||||||
|
_wg_svc['port'] = new_wg
|
||||||
|
config_manager.update_service_config('wireguard', _wg_svc)
|
||||||
|
wireguard_manager.update_config({'port': new_wg})
|
||||||
port_changed_containers.add('wireguard')
|
port_changed_containers.add('wireguard')
|
||||||
port_change_messages.append(f'wireguard_port: {old_wg} → {new_wg}')
|
port_change_messages.append(f'wireguard_port: {old_wg} → {new_wg}')
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -167,7 +167,7 @@ services:
|
|||||||
- PUID=${PUID:-1000}
|
- PUID=${PUID:-1000}
|
||||||
- PGID=${PGID:-1000}
|
- PGID=${PGID:-1000}
|
||||||
ports:
|
ports:
|
||||||
- "${WG_PORT:-51820}:51820/udp"
|
- "${WG_PORT:-51820}:${WG_PORT:-51820}/udp"
|
||||||
volumes:
|
volumes:
|
||||||
- ./config/wireguard:/config
|
- ./config/wireguard:/config
|
||||||
- /lib/modules:/lib/modules
|
- /lib/modules:/lib/modules
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ function Settings() {
|
|||||||
const { refresh: refreshConfig } = useConfig();
|
const { refresh: refreshConfig } = useConfig();
|
||||||
|
|
||||||
// identity
|
// identity
|
||||||
const [identity, setIdentity] = useState({ cell_name: '', domain: '', ip_range: '', wireguard_port: 51820 });
|
const [identity, setIdentity] = useState({ cell_name: '', domain: '', ip_range: '' });
|
||||||
const [identityDirty, setIdentityDirty] = useState(false);
|
const [identityDirty, setIdentityDirty] = useState(false);
|
||||||
const [identitySaving, setIdentitySaving] = useState(false);
|
const [identitySaving, setIdentitySaving] = useState(false);
|
||||||
|
|
||||||
@@ -315,7 +315,6 @@ function Settings() {
|
|||||||
cell_name: cfg.cell_name || '',
|
cell_name: cfg.cell_name || '',
|
||||||
domain: cfg.domain || '',
|
domain: cfg.domain || '',
|
||||||
ip_range: cfg.ip_range || '',
|
ip_range: cfg.ip_range || '',
|
||||||
wireguard_port: cfg.wireguard_port || 51820,
|
|
||||||
});
|
});
|
||||||
setServiceConfigs(cfg.service_configs || {});
|
setServiceConfigs(cfg.service_configs || {});
|
||||||
setBackups(bkRes.data || []);
|
setBackups(bkRes.data || []);
|
||||||
@@ -360,6 +359,7 @@ function Settings() {
|
|||||||
const res = await cellAPI.updateConfig({ [key]: serviceConfigs[key] });
|
const res = await cellAPI.updateConfig({ [key]: serviceConfigs[key] });
|
||||||
setServiceDirty((d) => ({ ...d, [key]: false }));
|
setServiceDirty((d) => ({ ...d, [key]: false }));
|
||||||
_applyResult(res, key);
|
_applyResult(res, key);
|
||||||
|
refreshConfig();
|
||||||
} catch {
|
} catch {
|
||||||
toast(`Failed to save ${key} config`, 'error');
|
toast(`Failed to save ${key} config`, 'error');
|
||||||
} finally {
|
} finally {
|
||||||
@@ -482,13 +482,6 @@ function Settings() {
|
|||||||
placeholder="172.20.0.0/16"
|
placeholder="172.20.0.0/16"
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
<Field label="WireGuard Port">
|
|
||||||
<NumberInput
|
|
||||||
value={identity.wireguard_port}
|
|
||||||
onChange={(v) => { setIdentity((i) => ({ ...i, wireguard_port: v })); setIdentityDirty(true); }}
|
|
||||||
min={1} max={65535}
|
|
||||||
/>
|
|
||||||
</Field>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-end mt-4">
|
<div className="flex justify-end mt-4">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { Shield, Key, Users, Activity, Wifi, Download, Copy, RefreshCw, Play, Pause, AlertCircle, Eye, Globe, CheckCircle, XCircle } from 'lucide-react';
|
import { Shield, Key, Users, Activity, Wifi, Download, Copy, RefreshCw, Play, Pause, AlertCircle, Eye, Globe, CheckCircle, XCircle } from 'lucide-react';
|
||||||
import { wireguardAPI, peerAPI } from '../services/api';
|
import { wireguardAPI, peerAPI } from '../services/api';
|
||||||
|
import { useConfig } from '../contexts/ConfigContext';
|
||||||
import QRCode from 'qrcode';
|
import QRCode from 'qrcode';
|
||||||
|
|
||||||
function WireGuard() {
|
function WireGuard() {
|
||||||
|
const { service_configs = {} } = useConfig();
|
||||||
|
const configPort = service_configs?.wireguard?.port ?? null;
|
||||||
const [status, setStatus] = useState(null);
|
const [status, setStatus] = useState(null);
|
||||||
const [serverConfig, setServerConfig] = useState(null);
|
const [serverConfig, setServerConfig] = useState(null);
|
||||||
const [isRefreshingIp, setIsRefreshingIp] = useState(false);
|
const [isRefreshingIp, setIsRefreshingIp] = useState(false);
|
||||||
@@ -381,11 +384,11 @@ PersistentKeepalive = ${peer.persistent_keepalive || 25}`;
|
|||||||
<div>
|
<div>
|
||||||
<p className="text-sm text-gray-500">WireGuard Endpoint</p>
|
<p className="text-sm text-gray-500">WireGuard Endpoint</p>
|
||||||
<p className="font-mono font-semibold text-gray-900">
|
<p className="font-mono font-semibold text-gray-900">
|
||||||
{serverConfig?.endpoint || `<SERVER_IP>:${serverConfig?.port || 51820}`}
|
{serverConfig?.endpoint || `<SERVER_IP>:${configPort ?? serverConfig?.port ?? 51820}`}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm text-gray-500">UDP Port {serverConfig?.port || 51820}</p>
|
<p className="text-sm text-gray-500">UDP Port {configPort ?? serverConfig?.port ?? 51820}</p>
|
||||||
{serverConfig ? (
|
{serverConfig ? (
|
||||||
<span className={`inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${
|
<span className={`inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${
|
||||||
serverConfig.port_open === true ? 'bg-green-100 text-green-800' :
|
serverConfig.port_open === true ? 'bg-green-100 text-green-800' :
|
||||||
@@ -419,7 +422,7 @@ PersistentKeepalive = ${peer.persistent_keepalive || 25}`;
|
|||||||
{serverConfig && serverConfig.port_open === false && (
|
{serverConfig && serverConfig.port_open === false && (
|
||||||
<div className="mt-3 flex items-center text-red-700 bg-red-50 rounded p-2 text-sm">
|
<div className="mt-3 flex items-center text-red-700 bg-red-50 rounded p-2 text-sm">
|
||||||
<AlertCircle className="h-4 w-4 mr-2 flex-shrink-0" />
|
<AlertCircle className="h-4 w-4 mr-2 flex-shrink-0" />
|
||||||
UDP port {serverConfig.port || 51820} appears closed. Check your router/firewall and forward this port to this machine.
|
UDP port {configPort ?? serverConfig.port ?? 51820} appears closed. Check your router/firewall and forward this port to this machine.
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user