* Add per-client firewall filtering Implement server-side firewall rules to restrict client network access, allowing administrators to enforce security policies that cannot be bypassed by clients modifying their local configuration. This feature addresses the limitation where "Allowed IPs" only controls client-side routing but doesn't prevent clients from accessing networks they shouldn't reach. The firewall rules are enforced on the server using iptables/ip6tables and provide true access control. Features: - Opt-in via "Enable Per-Client Firewall" toggle in admin interface - Per-client "Firewall Allowed IPs" field for granular control - Support for IPs, CIDRs, and port-based filtering - Protocol specification: TCP, UDP, or both (default) - IPv4 and IPv6 dual-stack support - Falls back to client's allowedIps when firewallIps is empty - Clean separation of routing (allowedIps) from security (firewallIps) Supported formats: - 10.10.0.3 (single IP) - 10.10.0.0/24 (CIDR range) - 192.168.1.5:443 (IP with port, both TCP+UDP) - 192.168.1.5:443/tcp (IP with specific protocol) - [2001:db8::1]:443 (IPv6 with port) Implementation: - New database columns: firewall_enabled (interfaces), firewall_ips (clients) - Migration 0003_add_firewall_filtering for schema updates - firewall.ts utility for iptables chain management (WG_CLIENTS chain) - Integration into WireGuard.ts for automatic rule application - UI components with conditional rendering based on firewall toggle Technical details: - Uses custom WG_CLIENTS iptables chain for isolation - Rebuild strategy: flush and recreate all rules on config save - Mutex protection via rebuildInProgress/rebuildQueued flags - Graceful cleanup when firewall is disabled - No new dependencies (uses existing is-ip, is-cidr packages) * added Comprehensive documentation in README and docs/ for firewall filtering * validate firewall IPs * check for iptables before enabling the firewall and inform the user if it is missing * updated firewall docs * fix imports * remove extra import * Document all allowed IP/cidr/port/proto combinations that are allowed and check on save * add note on firewall being experimental and how to opt a single client out of the firewall. * cleanup more imports * add tests * Fix firewall IPv6 validation and test expectations Updated validation to correctly handle plain and bracketed IPv6 addresses, and fixed test to expect string from schema instead of object. * added comments to firewall rules and updated tests * fix auto-import * fix typescript errors * recreate sql migrations and rebase * improve tests, typechecking, documentation * fix formatting, fix types * improve type * added note for including host's IP in client firewall * updated language to include cidr and protocol options * another language update * refer to docs for firewall allowed IPs --------- Co-authored-by: Bernd Storath <999999bst@gmail.com>
3.6 KiB
title
| title |
|---|
| Edit Client |
General
- Name: The name of the client.
- Enabled: Whether the client can connect to the VPN.
- Expire Date: The date the client will be disabled.
Address
- IPv4: The IPv4 address of the client.
- IPv6: The IPv6 address of the client.
Allowed IPs
Which IPs will be routed through the VPN.
This will not prevent the user from modifying it locally and accessing IP ranges that they should not be able to access.
Use the Firewall Allowed IPs feature to prevent access to IP ranges that the user should not be able to access.
Firewall Allowed IPs
/// note | Attention
This field only appears when Per-Client Firewall is enabled in the Admin Panel → Interface settings.
///
Server-side firewall rules that restrict which destinations the client can access, regardless of their local configuration.
Unlike "Allowed IPs" which only controls routing on the client side, these rules are enforced by the server using iptables/ip6tables and cannot be bypassed by the client.
Supported Formats:
10.10.0.3,2001:db8::1- Allow access to a single IP address10.10.0.0/24,2001:db8::/32- Allow access to an entire subnet192.168.1.5:443- Allow access to specific port (TCP+UDP)192.168.1.5:443/tcp- Allow access to specific port (TCP only)192.168.1.5:443/udp- Allow access to specific port (UDP only)10.10.0.0/24:443- Allow access to an entire subnet on a specific port (TCP+UDP)10.10.0.0/24:443/tcp- Allow access to an entire subnet on a specific port (TCP only)10.10.0.0/24:443/udp- Allow access to an entire subnet on a specific port (UDP only)[2001:db8::1]:443- IPv6 address with port (brackets required)[2001:db8::/32]:443/tcp- IPv6 CIDR with port and protocol
/// warning | Invalid Formats
Protocol specifiers (/tcp or /udp) require a port number. The following formats are not supported and will result in an error:
10.10.0.3/tcp(use10.10.0.3:443/tcpinstead)10.10.0.0/24/udp(use10.10.0.0/24:53/udpinstead)
///
Behavior:
- Empty: Falls back to the client's "Allowed IPs" setting
- Specified: Only listed destinations are accessible (allow-only, everything else is blocked)
- Disable for specific client: To disable firewall filtering for a single client while keeping it enabled for others, add
0.0.0.0/0, ::/0to allow all traffic
/// note To allow clients to reach the VPN server itself (e.g. for DNS), include the server's VPN address in the firewall allowed IPs. ///
Use Case Examples:
- Allow only specific servers:
10.10.0.5 - Allow only internal network:
10.10.0.0/24, 192.168.1.0/24 - Allow only web browsing:
0.0.0.0/0:80, 0.0.0.0/0:443, [::/0]:80, [::/0]:443 - Block internet, allow LAN: Leave "Allowed IPs" as
0.0.0.0/0, ::/0but set Firewall IPs to10.0.0.0/8, 192.168.0.0/16
Server Allowed IPs
Which IPs will be routed to the client.
DNS
The DNS server that the client will use.
Advanced
- MTU: The maximum transmission unit for the client.
- Persistent Keepalive: The interval for sending keepalive packets to the server.
Hooks
This can only be used for clients that use wg-quick. Setting this will throw a error when importing the config on other clients.
- PreUp: Commands to run before the interface is brought up.
- PostUp: Commands to run after the interface is brought up.
- PreDown: Commands to run before the interface is brought down.
- PostDown: Commands to run after the interface is brought down.
Actions
- Save: Save the changes made in the form.
- Revert: Revert the changes made in the form.
- Delete: Delete the client.