52e629ac02
- Add WGRplane component documentation to AGENTS.md - Update README.md with combined WireGuard Policy + WGRplane docs - Fix .gitignore (remove .gitea/ from ignore)
402 lines
16 KiB
Markdown
402 lines
16 KiB
Markdown
# 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)
|
|
- [Architecture & Data Flow](#-architecture--data-flow)
|
|
- [Installation](#-installation)
|
|
- [Prerequisites](#-prerequisites)
|
|
- [wg0.conf Integration](#-integrasi-ke-wg0conf)
|
|
- [CLI Usage](#-wg-policy-ctl-cli-usage)
|
|
- [Systemd Integration](#-systemd-integration-watcher-daemon)
|
|
|
|
### WGRplane (Go App)
|
|
- [WGRplane Overview](#-wgrplane-overview)
|
|
- [WGRplane Architecture](#-wgrplane-architecture)
|
|
- [WGRplane Features](#-wgrplane-features)
|
|
- [WGRplane Tech Stack](#-wgrplane-tech-stack)
|
|
- [WGRplane API Endpoints](#-wgrplane-api-endpoints)
|
|
- [WGRplane Installation](#-wgrplane-installation)
|
|
|
|
---
|
|
|
|
## 🎯 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.
|
|
|
|
```bash
|
|
# 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):**
|
|
```bash
|
|
./build.sh
|
|
```
|
|
|
|
**On Windows (CMD/PowerShell):**
|
|
```cmd
|
|
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`.
|
|
|
|
```ini
|
|
[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.
|
|
|
|
```ini
|
|
[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.
|
|
|
|
```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 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 |
|
|
|
|
```bash
|
|
# 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.
|
|
|
|
```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
|
|
```
|
|
|
|
---
|
|
|
|
## 🚀 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`](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`](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
|
|
|
|
### Option 1: Docker Compose (Recommended)
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# Run automated installer (Ubuntu/Debian/CentOS)
|
|
sudo ./install.sh install
|
|
|
|
# Uninstall
|
|
sudo ./install.sh uninstall
|
|
```
|
|
|
|
### Option 3: Manual Build
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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`](app/README.md).
|