2026-05-06 17:52:25 +07:00
2026-04-29 07:52:29 +07:00
2026-04-29 07:52:29 +07:00
2026-04-29 07:52:29 +07:00

WireGuard Policy Firewall + WGRplane Control Plane

A complete WireGuard management solution combining two powerful components:

  1. WireGuard Dynamic Policy Firewall - A lightweight, robust iptables/ipset policy engine that restricts and controls WireGuard peer traffic directly from wg0.conf using custom #Access comments.
  2. WGRplane - A Go-native control plane application with Vue 3 frontend, providing a modern web dashboard for WireGuard management with real-time monitoring, peer CRUD, and hybrid firewall enforcement.

📑 Table of Contents

Policy Firewall (Shell Scripts)

WGRplane (Go App)


🎯 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.

📁 Installation

The easiest way to install is using the provided install.sh script, which automatically installs dependencies, copies all scripts to /usr/local/bin/, sets up the systemd daemon, and enables the service.

# Install everything
sudo ./install.sh install

# Uninstall everything
sudo ./install.sh uninstall

Building the Installer (For Developers)

If you modify any of the source .sh or .service files, you must rebuild the install.sh script using the provided builders.

On Linux (Bash):

./build.sh

On Windows (CMD/PowerShell):

build.bat

📦 Prerequisites

Package Required Install
jq Yes apt install jq
inotify-tools Yes (for watcher daemon) apt install inotify-tools
ipset Optional apt install ipset

If ipset is not installed, the engine will automatically fall back to per-rule iptables whitelist entries. This works fine for small deployments. For large numbers of clients/targets, ipset is recommended for O(1) lookup performance.


⚙️ 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.

⚠️ WireGuard does NOT support multiline values. Every command must be on a PostUp = ... or PostDown = ... line. Bare commands without the PostUp = prefix will cause Configuration parsing error.

[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <SERVER_PRIVATE_KEY>

# Policy engine: auto-handles NAT, IP forwarding, and dynamic firewall rules
PostUp = /usr/local/bin/wg-sync-policy.sh; /usr/local/bin/wg-policy-engine.sh

# Policy engine: cleanup all firewall and routing traces
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.

⚠️ WARNING: Do NOT use SaveConfig = true! WireGuard's SaveConfig feature overwrites wg0.conf directly and strips all comments, which will permanently delete all #Access tags. If you are using a Web UI/Dashboard, make sure it does not strip unknown comments when saving.

[Peer]
PublicKey = <CLIENT_1_PUBKEY>
AllowedIPs = 10.0.0.2/32
#Access 192.168.1.10/32, 192.168.12.0/24

[Peer]
PublicKey = <CLIENT_2_PUBKEY>
AllowedIPs = 10.0.0.3/32
#Access = 10.0.0.1/32

[Peer]
PublicKey = <CLIENT_3_PUBKEY>
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.

# 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 use the install.sh script, the daemon is automatically installed, enabled, and started for you. It monitors wg0.conf for changes and triggers the pipeline seamlessly.

Manual File Installation (If not using install.sh)

Place the three provided systemd unit files into /etc/systemd/system/.

Systemd File Location Description
wg-policy.service /etc/systemd/system/wg-policy.service The main daemon that runs wg-sync-watch.sh
wg-policy-health.timer /etc/systemd/system/wg-policy-health.timer Triggers the health check every 5 minutes
wg-policy-health.service /etc/systemd/system/wg-policy-health.service Executes the actual health check logic
# Example copy command
cp wg-policy.service wg-policy-health.timer wg-policy-health.service /etc/systemd/system/

2. Enable & Start Services

After copying the files, reload systemd to recognize them, then enable and start the services.

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:

journalctl -u wg-policy.service -f

🚀 WGRplane Overview

WGRplane is a Go-native WireGuard control plane application with a Vue 3 frontend, providing a modern web dashboard for WireGuard management. It features a single Go binary backend, SPA frontend, dynamic policy firewall integration, and glassmorphism UI design.

The application lives in the /app directory. For full documentation, see app/README.md.


🏗 WGRplane Architecture

wg0.conf (with/without #Access)
        ↓
┌─────────────────────────────────────────────┐
│  WGRplane (Go Binary :10087)                │
│  ┌───────────┐  ┌──────────┐  ┌──────────┐  │
│  │ Gorilla   │  │ GORM     │  │ nftables │  │
│  │ Mux Router│  │ SQLite   │  │ Engine   │  │
│  └───────────┘  └──────────┘  └──────────┘  │
│  ┌───────────┐  ┌──────────┐  ┌──────────┐  │
│  │ Webhook   │  │ Scheduler│  │ WebSocket│  │
│  │ Engine    │  │ Cron     │  │ Hub      │  │
│  └───────────┘  └──────────┘  └──────────┘  │
│  ┌───────────┐  ┌──────────┐  ┌──────────┐  │
│  │ Auth      │  │ SMTP     │  │ Plugins  │  │
│  │ JWT/TOTP  │  │ Email    │  │ TG/Slack │  │
│  └───────────┘  └──────────┘  └──────────┘  │
└─────────────────────────────────────────────┘
        ↓ HTTP/WebSocket
┌─────────────────────────────────────────────┐
│  Frontend (Vue 3 + TypeScript + Tailwind)   │
│  Glassmorphism UI, i18n, Dark/Light mode    │
└─────────────────────────────────────────────┘

Hybrid Mode

WGRplane supports two server modes:

  • forward - Directly applies nftables rules on the local machine. Peer policies are enforced via nft commands.
  • standalone - Acts as a control plane that triggers webhooks to remote WireGuard servers. Policy enforcement happens on the remote side.

2-Column Policy

Each peer has two independent policy columns:

Column Function
AllowAccess List of CIDRs the peer can access (internal targets)
AllowInternet Boolean flag. If true, peer gets unlimited internet access (MASQUERADE)

Peers without any rules are isolated from other peers and the internet by default.


WGRplane Features

  • Go-Native Architecture: Single Go binary handles all API, database, webhooks, scheduler, and nftables. No Python/Flask needed.
  • Complete Peer CRUD: Add, edit, delete peers. Generate QR codes for mobile client import. Export .conf configuration files.
  • Hybrid Mode: forward mode (local nftables) or standalone mode (webhook to remote servers).
  • 2-Column Policy UI: "Allow Access" column (firewall whitelist CIDR) and "Allow Internet" toggle per peer.
  • Real-time Monitoring: WebSocket broadcasts peer statistics and traffic every 5 seconds.
  • Automated Scheduling: Daily cron jobs to delete expired peers, restrict over-limit peers, and reset monthly data usage.
  • Security: API Key authentication (wg-rplane-datadunia), JWT Bearer tokens, and TOTP (2FA).
  • Webhook Engine: Integration with remote servers (Mikrotik, etc.). Retry with exponential backoff, custom headers, Go templates.
  • Plugin System: Telegram, Slack, and Traffic Logger notifications.
  • i18n & Themes: Multi-language (English, Indonesian, Chinese). Dark/Light/Auto mode.
  • Glassmorphism UI: Futuristic design with frosted glass cards, buttons, and inputs.

🛠 WGRplane Tech Stack

Component Technology
Backend Go, Gorilla Mux, GORM (SQLite via glebarez/sqlite)
Frontend Vue 3, TypeScript, Vite, TailwindCSS 4, vue-i18n 9
Auth JWT (golang-jwt/v5), TOTP (pquerna/otp), API Key
WebSockets gorilla/websocket
Webhooks Go net/http with retry + exponential backoff
Scheduling robfig/cron v3
QR Code skip2/go-qrcode
Email jordan-wright/email (SMTP)
Firewall Bash, iptables, ipset, nftables, inotify-tools, jq
Container Docker (multi-stage build), docker-compose

🌐 WGRplane API Endpoints Summary

All endpoints are served on port 10087. For complete API documentation with request/response details, see app/README.md or visit /swagger/ on your running instance.

Authentication

Method Header Notes
API Key wg-rplane-datadunia: <KEY> Set via env var WG_API_KEY. Default: test-api-key
JWT Authorization: Bearer <TOKEN> Expires in 15 minutes. Secret via env var JWT_SECRET
TOTP X-TOTP: <CODE> Required if user enables TOTP

Main Endpoints

Endpoint Method Description
/api/servers GET/POST List all servers / Create new server
/api/servers/{id} GET/PUT/DELETE Get/Update/Delete server
/api/servers/{id}/peers GET/POST List peers / Create new peer
/api/peers/{id} PUT/DELETE Update/Delete peer
/api/peers/{id}/config GET Download WireGuard .conf file
/api/peers/{id}/qrcode GET Generate QR code PNG for mobile import
/api/servers/{id}/webhooks GET/POST List/Create webhooks
/api/stats GET Global statistics
/ws/stats WebSocket Real-time stats broadcast (5s interval)
/swagger/ - Interactive Swagger UI documentation

📦 WGRplane Installation

# Clone repository
git clone https://git.datadunia.com/hainzero/WGRplane.git
cd 03.wireguard-policy

# Start WGRplane and WireGuard
docker compose up -d

# Access dashboard at http://localhost:10087

Option 2: Install Script

# Run automated installer (Ubuntu/Debian/CentOS)
sudo ./install.sh install

# Uninstall
sudo ./install.sh uninstall

Option 3: Manual Build

# Build Go binary
cd app
go build -o ../wgrplane .
cd ..

# Build frontend
cd app/frontend
npm install && npm run build
cd ../..

# Run
./wgrplane
# Server starts on :10087

Option 4: Systemd Service

# Install service file
sudo cp wgrplane.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable wgrplane.service
sudo systemctl start wgrplane.service

# View logs
journalctl -u wgrplane.service -f

📁 Project Structure

03.wireguard-policy/
├── app/                          # Go backend + Vue frontend
│   ├── main.go                   # Bootstrap server, routing, init DB
│   ├── handlers.go               # REST API route handlers
│   ├── models.go                 # GORM models (Server, Peer, Webhook, SMTP)
│   ├── auth.go                   # JWT, TOTP, API key auth middleware
│   ├── nftables.go               # nftables rule management (mode forward)
│   ├── webhook.go                # Webhook engine with retry/backoff
│   ├── scheduler.go              # Cron jobs (expiry, data limit, reset)
│   ├── stats.go                  # WebSocket Hub for real-time stats
│   ├── frontend/                 # Vue 3 SPA (TypeScript, TailwindCSS)
│   └── docs/                     # Swagger documentation
├── wg-sync-policy.sh             # Parse wg0.conf → policy.json
├── wg-policy-engine.sh           # Apply policy.json → iptables/ipset
├── wg-sync-watch.sh              # inotifywait watcher daemon
├── wg-policy-ctl                 # CLI wrapper for policy management
├── wg-policy-cleanup.sh          # Cleanup script for PostDown
├── wg-policy.service             # Systemd unit for watcher daemon
├── wgrplane.service              # Systemd unit for Go backend
├── install.sh                    # Automated installer (Docker + services)
├── Dockerfile                    # Multi-stage Docker build
├── docker-compose.yml            # Docker Compose stack
└── README.md                     # This file

For detailed WGRplane documentation including webhooks, plugins, scheduler, and frontend details, refer to app/README.md.

S
Description
No description provided
Readme 1.9 MiB
v1.0.0 Latest
2026-05-08 05:51:48 +07:00
Languages
Shell 87.9%
Batchfile 12.1%