diff --git a/README.md b/README.md new file mode 100644 index 0000000..2386803 --- /dev/null +++ b/README.md @@ -0,0 +1,132 @@ +# WireGuard Dynamic Policy Firewall + +A lightweight, robust, and highly dynamic iptables/ipset policy firewall engine designed to restrict and control WireGuard peer traffic (egress traffic mapping) straight from `wg0.conf`. + +Rather than allowing all VPN clients to reach any part of your internal network, this tool isolates clients from each other by default and reads a custom `#Access` comment inside `wg0.conf` to automatically generate strict `iptables` rules and `ipset` whitelists per-client on the fly. + +--- + +## 🎯 Architecture & Data Flow + +1. **`wg0.conf`**: The standard WireGuard configuration. Contains standard `[Peer]` configs alongside a custom `#Access` tag. +2. **`wg-sync-policy.sh`**: Safely parses `wg0.conf` and generates a structured `/etc/wireguard/policy.json` atomically. +3. **`wg-policy-engine.sh`**: Reads `policy.json` to generate robust rules, applying `iptables` and `ipset` directly to the system. +4. **Watcher Daemon**: Monitors `wg0.conf` for changes via `inotifywait` and triggers the pipeline seamlessly when updates are made. + +--- + +## 📁 File Locations & Installation + +All scripts must be placed in `/usr/local/bin/` and made executable. + +| File | Location | Description | +|------|----------|-------------| +| `wg-policy-lib.sh` | `/usr/local/bin/wg-policy-lib.sh` | Shared library and core validation tools. | +| `wg-sync-policy.sh` | `/usr/local/bin/wg-sync-policy.sh` | Extracts config into atomic JSON format. | +| `wg-policy-engine.sh` | `/usr/local/bin/wg-policy-engine.sh` | Translates JSON into iptables & ipset logic. | +| `wg-policy-cleanup.sh` | `/usr/local/bin/wg-policy-cleanup.sh` | Reverts and cleans up all firewall traces safely. | +| `wg-sync-watch.sh` | `/usr/local/bin/wg-sync-watch.sh` | Debounced file watcher (daemon). | +| `wg-policy-ctl` | `/usr/local/bin/wg-policy-ctl` | Handy command-line interface tool. | + +Make sure they are executable: +```bash +chmod +x /usr/local/bin/wg-*.sh /usr/local/bin/wg-policy-ctl +``` + +--- + +## ⚙️ Integrasi ke `wg0.conf` + +To integrate the engine, you need to append hooks into your `wg0.conf` interface block, and declare the `#Access` tags under each peer. + +### 1. Interface Block (Hooks) +Add the `PostUp` and `PostDown` scripts so the engine initializes correctly during VPN startup and removes traces upon shutdown. + +```ini +[Interface] +Address = 10.0.0.1/24 +ListenPort = 51820 +PrivateKey = + +# PostUp: sync policy + apply engine +PostUp = /usr/local/bin/wg-sync-policy.sh && /usr/local/bin/wg-policy-engine.sh + +# PostDown: safe cleanup +PostDown = /usr/local/bin/wg-policy-cleanup.sh +``` + +### 2. Peer Block (`#Access` Tags) +For each client, use the `#Access` comment line. Define the destinations (targets) the peer is allowed to access. You can separate multiple IPs or CIDRs with commas or semicolons. + +```ini +[Peer] +PublicKey = +AllowedIPs = 10.0.0.2/32 +#Access 192.168.1.10/32, 192.168.12.0/24 + +[Peer] +PublicKey = +AllowedIPs = 10.0.0.3/32 +#Access = 10.0.0.1/32 + +[Peer] +PublicKey = +AllowedIPs = 10.0.0.4/32 +#Access +# ^ (Empty Access implies internet-only, client isolation applies) +``` + +**⚠️ Important constraint:** Why `#Access` instead of just using `AllowedIPs` directly? +WireGuard uses `AllowedIPs` for Cryptokey Routing (deciding which tunnel interface to route outbound packets). If you put an internal server IP inside the server's `wg0.conf` AllowedIPs block, WireGuard will aggressively capture and redirect packets bound for that internal server into the VPN client's tunnel. The `#Access` comment separates routing parameters from firewall parameters cleanly. + +--- + +## 🛠 `wg-policy-ctl` CLI Usage + +You don't need to manually interact with `iptables` or `.json` files. Use the `wg-policy-ctl` wrapper. + +```bash +# View the health of the firewall engine and active locks +wg-policy-ctl status + +# View the raw, parsed JSON policy +wg-policy-ctl policy + +# Inspect active iptables rules +wg-policy-ctl rules + +# Check memory sets mapping IP targets (ipset) +wg-policy-ctl ipset + +# Manually re-sync rules immediately +wg-policy-ctl reload + +# Inspect dropped packets (rate-limited log output) +wg-policy-ctl log + +# See connection statistics, how many targets loaded +wg-policy-ctl stats + +# Force validation of the policy schema +wg-policy-ctl validate +``` + +--- + +## 🔧 Systemd Integration (Watcher Daemon) + +If you are using the daemon mode to auto-sync changes instantly upon editing `wg0.conf` (without needing to run `wg-policy-ctl reload` or restarting the interface). + +Enable the systemd services: +```bash +systemctl daemon-reload +systemctl enable wg-policy.service +systemctl enable wg-policy-health.timer +systemctl start wg-policy.service +systemctl start wg-policy-health.timer +``` + +Check the watcher logs: +```bash +journalctl -u wg-policy.service -f +```