VPN tab: prioritize OPNsense WireGuard, contextual descriptions
When OPNsense WG plugin is detected: - Show recommendation banner at top explaining why router-level VPN is better than running it on the management PC - OPNsense WG section appears first (recommended path) - Local WG panels relabeled as "backup / this machine only" - Local WG description changes to explain the limitation (VLAN 99 only) When OPNsense is not connected: - Local WG shown normally as the primary option - Tip nudge added pointing to DHCP tab to unlock router-level VPN - OPNsense WG section shown below as a setup prompt In both cases: - SSH Tunnel renamed to "Emergency Fallback" with clearer description - Pre-select servers VLAN when OPNsense WG server becomes available (most users want remote access to services, not IoT/cameras) - Connected Peers / Clients panels prefixed "Local WG —" for clarity https://claude.ai/code/session_01JR2EMK7rwrZJowpstcaxQ6
This commit is contained in:
+1
-1
File diff suppressed because one or more lines are too long
+80
-13
@@ -1874,21 +1874,86 @@ function WireGuardTab({ session, onNeedAuth, backendOk, vlans = [] }) {
|
|||||||
} catch(e) { setOpnError(e.message); }
|
} catch(e) { setOpnError(e.message); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Pre-select servers VLAN when OPNsense WG server becomes available
|
||||||
|
useEffect(() => {
|
||||||
|
if (opnWg?.server && opnVlans.length === 0) {
|
||||||
|
const serversVlan = vlans.find(v =>
|
||||||
|
v.name?.toLowerCase().includes("server") && v.id !== 99
|
||||||
|
);
|
||||||
|
if (serversVlan) setOpnVlans([serversVlan.id]);
|
||||||
|
}
|
||||||
|
}, [opnWg?.server]);
|
||||||
|
|
||||||
|
const opnAvailable = opnWg?.opnsense_configured && opnWg?.plugin_installed;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="main" style={{flexDirection:"column",gap:12}}>
|
<div className="main" style={{flexDirection:"column",gap:12}}>
|
||||||
|
|
||||||
|
{/* ── Recommendation banner when OPNsense WG is available ──── */}
|
||||||
|
{opnAvailable && (
|
||||||
|
<div style={{
|
||||||
|
background:"rgba(0,229,255,.06)",border:"1px solid rgba(0,229,255,.25)",
|
||||||
|
borderRadius:6,padding:"12px 16px",display:"flex",gap:12,alignItems:"flex-start",
|
||||||
|
}}>
|
||||||
|
<div style={{fontSize:18,lineHeight:1,color:"var(--ac)"}}>◈</div>
|
||||||
|
<div style={{flex:1}}>
|
||||||
|
<div style={{fontWeight:700,color:"var(--ac)",marginBottom:4}}>
|
||||||
|
OPNsense WireGuard available — recommended
|
||||||
|
</div>
|
||||||
|
<div style={{fontSize:12,color:"var(--dm)",lineHeight:1.7}}>
|
||||||
|
Your OPNsense has the WireGuard plugin. Running VPN on the router is
|
||||||
|
better than here: it stays on when this PC is off, your firewall and VPN
|
||||||
|
live in the same place, and every VLAN can be reached remotely.
|
||||||
|
The local option below still works as a backup.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* ── OPNsense WG first when available ─────────────────────── */}
|
||||||
|
{opnAvailable && (
|
||||||
|
<OPNsenseWGSection
|
||||||
|
opnWg={opnWg} opnLoading={opnLoading} opnError={opnError}
|
||||||
|
opnSetup={opnSetup} setOpnSetup={setOpnSetup}
|
||||||
|
opnPeerName={opnPeerName} setOpnPeerName={setOpnPeerName}
|
||||||
|
opnVlans={opnVlans} opnAdding={opnAdding}
|
||||||
|
session={session} onNeedAuth={onNeedAuth} vlans={vlans}
|
||||||
|
onToggleVlan={opnToggleVlan} onSetupServer={opnSetupServer}
|
||||||
|
onDeleteServer={opnDeleteServer} onAddPeer={opnAddPeer}
|
||||||
|
onRevokePeer={opnRevokePeer} onShowConf={opnShowConf} onRefresh={loadOpnWg}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* ── Local WireGuard ──────────────────────────────────────── */}
|
||||||
<div className="panel">
|
<div className="panel">
|
||||||
<div className="ph">◈ WireGuard VPN
|
<div className="ph">
|
||||||
|
{opnAvailable ? "◈ Local WireGuard — backup / this machine only" : "◈ WireGuard VPN"}
|
||||||
<span style={{marginLeft:"auto",fontFamily:"var(--mono)",fontSize:10,
|
<span style={{marginLeft:"auto",fontFamily:"var(--mono)",fontSize:10,
|
||||||
color:isRunning?"var(--ok)":"var(--err)"}}>
|
color:isRunning?"var(--ok)":"var(--err)"}}>
|
||||||
{isRunning ? "● Running" : "○ Not running"}
|
{isRunning ? "● Running" : "○ Not running"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="pb">
|
<div className="pb">
|
||||||
|
{opnAvailable ? (
|
||||||
<div style={{fontSize:12,color:"var(--dm)",lineHeight:1.7,marginBottom:12}}>
|
<div style={{fontSize:12,color:"var(--dm)",lineHeight:1.7,marginBottom:12}}>
|
||||||
WireGuard lets you connect from anywhere — home WiFi, coffee shop, anywhere —
|
Run WireGuard on this management PC instead of OPNsense.
|
||||||
and reach the switch manager as if you were on the management network.
|
Use this as a backup when OPNsense is being reconfigured, or if you
|
||||||
Each device gets its own key. Revoking a key disconnects that device immediately.
|
prefer not to touch the router. Clients can only reach VLAN 99
|
||||||
|
(management network) from here — they cannot reach other VLANs
|
||||||
|
unless this PC also routes that traffic.
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
<div style={{fontSize:12,color:"var(--dm)",lineHeight:1.7,marginBottom:12}}>
|
||||||
|
WireGuard lets you connect from anywhere — coffee shop, hotel, cellular —
|
||||||
|
and reach this switch manager as if you were on VLAN 99.
|
||||||
|
Each device gets its own key; revoking a key disconnects it immediately.
|
||||||
|
<br/><br/>
|
||||||
|
<span style={{color:"var(--warn)"}}>
|
||||||
|
Tip: Connect OPNsense in the DHCP tab to unlock router-level WireGuard —
|
||||||
|
always on, handles all VLANs, no dependency on this machine.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{!isRunning && (
|
{!isRunning && (
|
||||||
<div style={{background:"rgba(255,23,68,.07)",border:"1px solid rgba(255,23,68,.2)",
|
<div style={{background:"rgba(255,23,68,.07)",border:"1px solid rgba(255,23,68,.2)",
|
||||||
borderRadius:4,padding:"10px 14px",marginBottom:12,fontSize:11,color:"var(--err)"}}>
|
borderRadius:4,padding:"10px 14px",marginBottom:12,fontSize:11,color:"var(--err)"}}>
|
||||||
@@ -1903,7 +1968,7 @@ function WireGuardTab({ session, onNeedAuth, backendOk, vlans = [] }) {
|
|||||||
{/* Connected peers */}
|
{/* Connected peers */}
|
||||||
{isRunning && status?.peers?.length > 0 && (
|
{isRunning && status?.peers?.length > 0 && (
|
||||||
<div className="panel">
|
<div className="panel">
|
||||||
<div className="ph">◈ Connected Peers ({status.peers.length})</div>
|
<div className="ph">◈ Local WG — Connected Peers ({status.peers.length})</div>
|
||||||
<div className="pb">
|
<div className="pb">
|
||||||
{status.peers.map((p,i) => (
|
{status.peers.map((p,i) => (
|
||||||
<div key={i} style={{padding:"8px 0",borderBottom:"1px solid var(--b1)",
|
<div key={i} style={{padding:"8px 0",borderBottom:"1px solid var(--b1)",
|
||||||
@@ -1930,7 +1995,7 @@ function WireGuardTab({ session, onNeedAuth, backendOk, vlans = [] }) {
|
|||||||
|
|
||||||
{/* Client management */}
|
{/* Client management */}
|
||||||
<div className="panel">
|
<div className="panel">
|
||||||
<div className="ph">◈ VPN Clients</div>
|
<div className="ph">◈ Local WG — Clients</div>
|
||||||
<div className="pb">
|
<div className="pb">
|
||||||
{clients.length === 0 && <div className="empty" style={{padding:"16px 0"}}>No clients configured yet.</div>}
|
{clients.length === 0 && <div className="empty" style={{padding:"16px 0"}}>No clients configured yet.</div>}
|
||||||
{clients.map(c => (
|
{clients.map(c => (
|
||||||
@@ -1967,28 +2032,29 @@ function WireGuardTab({ session, onNeedAuth, backendOk, vlans = [] }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* SSH tunnel info */}
|
{/* SSH tunnel fallback */}
|
||||||
<div className="panel">
|
<div className="panel">
|
||||||
<div className="ph">◈ SSH Tunnel — Power User Alternative</div>
|
<div className="ph">◈ SSH Tunnel — Emergency Fallback</div>
|
||||||
<div className="pb">
|
<div className="pb">
|
||||||
<div style={{fontSize:12,color:"var(--dm)",lineHeight:1.7,marginBottom:8}}>
|
<div style={{fontSize:12,color:"var(--dm)",lineHeight:1.7,marginBottom:8}}>
|
||||||
If WireGuard is not available, SSH port forwarding gives secure access
|
If WireGuard is down or misconfigured, SSH port forwarding reaches the
|
||||||
in one command. Run this on your remote machine:
|
switch manager in one command — no daemon, no keys to manage.
|
||||||
</div>
|
</div>
|
||||||
<div style={{background:"#060809",borderRadius:4,padding:"10px 14px",
|
<div style={{background:"#060809",borderRadius:4,padding:"10px 14px",
|
||||||
fontFamily:"var(--mono)",fontSize:12,color:"#a0b0c0",marginBottom:8}}>
|
fontFamily:"var(--mono)",fontSize:12,color:"#a0b0c0",marginBottom:8}}>
|
||||||
ssh -L 8765:localhost:8765 user@your-management-computer-ip
|
ssh -L 8765:localhost:8765 user@your-management-computer-ip
|
||||||
</div>
|
</div>
|
||||||
<div style={{fontSize:11,color:"var(--dm)"}}>
|
<div style={{fontSize:11,color:"var(--dm)"}}>
|
||||||
Then open <span style={{color:"var(--ac)",fontFamily:"var(--mono)"}}>http://localhost:8765</span> in your browser.
|
Then open <span style={{color:"var(--ac)",fontFamily:"var(--mono)"}}>http://localhost:8765</span>.
|
||||||
The management computer needs SSH accessible from outside (key auth only, consider fail2ban).
|
Requires SSH accessible from outside (key auth only — consider fail2ban).
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{qrModal && <QRModal config={qrModal.config} name={qrModal.name} onClose={()=>setQrModal(null)}/>}
|
{qrModal && <QRModal config={qrModal.config} name={qrModal.name} onClose={()=>setQrModal(null)}/>}
|
||||||
|
|
||||||
{/* ── OPNsense WireGuard ─────────────────────────────────────── */}
|
{/* OPNsense WG shown below local when not yet available (nudge to set up) */}
|
||||||
|
{!opnAvailable && (
|
||||||
<OPNsenseWGSection
|
<OPNsenseWGSection
|
||||||
opnWg={opnWg}
|
opnWg={opnWg}
|
||||||
opnLoading={opnLoading}
|
opnLoading={opnLoading}
|
||||||
@@ -2010,6 +2076,7 @@ function WireGuardTab({ session, onNeedAuth, backendOk, vlans = [] }) {
|
|||||||
onShowConf={opnShowConf}
|
onShowConf={opnShowConf}
|
||||||
onRefresh={loadOpnWg}
|
onRefresh={loadOpnWg}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{opnQr && <QRModal config={opnQr.config} name={opnQr.name} onClose={()=>setOpnQr(null)}/>}
|
{opnQr && <QRModal config={opnQr.config} name={opnQr.name} onClose={()=>setOpnQr(null)}/>}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user