docs(ui): clarify rule source separation on routing tabs

Added info banners on Firewall, Peer Routes, and Live iptables tabs
explaining that stored rules (NAT/Firewall/Peer Routes forms) and live
rules (pic-peer-* from Peers page, PostUp from wg0.conf) are separate
by design — Live iptables shows everything, each form tab shows only
what it manages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-21 01:32:24 -04:00
parent 4bf583c071
commit 1a5da3a207
+18 -9
View File
@@ -1,5 +1,5 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { Plus, Trash2, Wifi, Shield, Activity, Settings, Terminal, ArrowRightLeft, RefreshCw } from 'lucide-react'; import { Plus, Trash2, Wifi, Shield, Activity, Settings, Terminal, ArrowRightLeft, RefreshCw, Info } from 'lucide-react';
import { routingAPI } from '../services/api'; import { routingAPI } from '../services/api';
const EMPTY_NAT = { source_network: '', target_interface: 'eth0', masquerade: true, nat_type: 'MASQUERADE', protocol: 'ALL', external_port: '', internal_ip: '', internal_port: '' }; const EMPTY_NAT = { source_network: '', target_interface: 'eth0', masquerade: true, nat_type: 'MASQUERADE', protocol: 'ALL', external_port: '', internal_ip: '', internal_port: '' };
@@ -337,7 +337,7 @@ function Routing() {
<Plus className="h-4 w-4 mr-1" />{showPfForm ? 'Cancel' : 'Add Rule'} <Plus className="h-4 w-4 mr-1" />{showPfForm ? 'Cancel' : 'Add Rule'}
</button> </button>
} /> } />
<p className="text-sm text-gray-500 mb-4">Forward inbound traffic on a public port to an internal host.</p> <p className="text-sm text-gray-500 mb-4">Forward inbound traffic on a public port to an internal host. Rules here are stored and re-applied on restart.</p>
{showPfForm && ( {showPfForm && (
<form onSubmit={handleAddPf} className="mb-6 p-4 bg-gray-50 rounded-lg space-y-4"> <form onSubmit={handleAddPf} className="mb-6 p-4 bg-gray-50 rounded-lg space-y-4">
@@ -481,9 +481,10 @@ function Routing() {
<Plus className="h-4 w-4 mr-1" />{showPeerForm ? 'Cancel' : 'Add Route'} <Plus className="h-4 w-4 mr-1" />{showPeerForm ? 'Cancel' : 'Add Route'}
</button> </button>
} /> } />
<p className="text-sm text-gray-500 mb-4"> <div className="flex gap-2 p-3 mb-4 bg-blue-50 rounded-lg text-sm text-blue-800">
Add OS-level routes that forward traffic for a network through a specific VPN peer. <Info className="h-4 w-4 mt-0.5 shrink-0" />
</p> <span>OS-level <code className="font-mono">ip route</code> entries stored here. WireGuard per-peer access control (which traffic each peer is allowed) is on the <a href="/peers" className="underline font-medium">Peers page</a>, not here.</span>
</div>
{showPeerForm && ( {showPeerForm && (
<form onSubmit={handleAddPeer} className="mb-6 p-4 bg-gray-50 rounded-lg space-y-4"> <form onSubmit={handleAddPeer} className="mb-6 p-4 bg-gray-50 rounded-lg space-y-4">
@@ -563,9 +564,12 @@ function Routing() {
<Plus className="h-4 w-4 mr-1" />{showFwForm ? 'Cancel' : 'Add Rule'} <Plus className="h-4 w-4 mr-1" />{showFwForm ? 'Cancel' : 'Add Rule'}
</button> </button>
} /> } />
<p className="text-sm text-gray-500 mb-4"> <div className="flex gap-2 p-3 mb-4 bg-blue-50 rounded-lg text-sm text-blue-800">
Custom iptables rules applied on the host. Per-peer VPN access rules are managed on the <a href="/peers" className="text-primary-600 underline">Peers page</a>. <Info className="h-4 w-4 mt-0.5 shrink-0" />
</p> <span>
This tab only shows rules added here. The <strong>Live iptables</strong> tab shows all running rules including per-peer VPN rules (managed on the <a href="/peers" className="underline font-medium">Peers page</a>) and WireGuard PostUp rules. They are intentionally separate.
</span>
</div>
{showFwForm && ( {showFwForm && (
<form onSubmit={handleAddFw} className="mb-6 p-4 bg-gray-50 rounded-lg space-y-4"> <form onSubmit={handleAddFw} className="mb-6 p-4 bg-gray-50 rounded-lg space-y-4">
@@ -668,7 +672,12 @@ function Routing() {
<RefreshCw className={`h-4 w-4 mr-1 ${iptLoading ? 'animate-spin' : ''}`} /> Refresh <RefreshCw className={`h-4 w-4 mr-1 ${iptLoading ? 'animate-spin' : ''}`} /> Refresh
</button> </button>
} /> } />
<p className="text-sm text-gray-500 mb-4">Read-only view of actual iptables rules running inside cell-wireguard.</p> <div className="flex gap-2 p-3 mb-4 bg-blue-50 rounded-lg text-sm text-blue-800">
<Info className="h-4 w-4 mt-0.5 shrink-0" />
<span>
Read-only view of ALL rules running in cell-wireguard. Includes: <strong>pic-peer-*</strong> rules from the Peers page, <strong>MASQUERADE</strong> from wg0.conf PostUp, and any rules added via the forms above. Rules here cannot be edited directly.
</span>
</div>
{iptLoading ? ( {iptLoading ? (
<div className="flex justify-center py-8"><div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary-600" /></div> <div className="flex justify-center py-8"><div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary-600" /></div>