doc
This commit is contained in:
+419
-134
@@ -1,18 +1,22 @@
|
|||||||
# WGRplane - WireGuard Remote Plane Control
|
# WGRplane - WireGuard Remote Plane Control
|
||||||
|
|
||||||
**WGRplane** adalah aplikasi kontrol WireGuard Remote Plane yang dibangun dengan fitur lengkap (paritas penuh dengan **WGDashboard**) ditambah integrasi **policy.json API**.
|
**WGRplane** adalah aplikasi WireGuard Control Plane berbasis Go-native dengan frontend Vue 3. Single binary untuk backend, SPA untuk frontend, dilengkapi dynamic policy firewall dan glassmorphism UI.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Fitur Utama
|
## Fitur Utama
|
||||||
|
|
||||||
- **Peer Management**: CRUD peer, generate QR code, export config
|
- **Arsitektur Go-Native**: Single Go binary (`main.go`) menangani semua API, database, webhook, scheduler, dan nftables. Tidak ada Python/Flask.
|
||||||
- **Real-time Monitoring**: Status peer, grafik trafik, riwayat koneksi
|
- **Peer CRUD Lengkap**: Tambah, edit, hapus peer. Generate QR code untuk import ke mobile client. Export file konfigurasi `.conf`.
|
||||||
- **Scheduling & Automation**: Jadwal penghapusan/restriksi peer, reset data usage
|
- **Hybrid Mode**: Mode `forward` (nftables lokal) atau `standalone` (webhook ke server remote).
|
||||||
- **Security**: Autentikasi dashboard (username/password), TOTP (2FA), API key
|
- **2-Column Policy UI**: Kolom "Allow Access" (firewall whitelist CIDR) dan "Allow Internet" (MASQUERADE toggle) per peer.
|
||||||
- **Multi-Server**: Akses multi WGDashboard instance via API keys
|
- **Real-time Monitoring**: WebSocket broadcast statistik peer dan trafik setiap 5 detik.
|
||||||
- **Plugins System**: Ekspansi fitur via plugin (experimental)
|
- **Automated Scheduling**: Cron job harian untuk hapus peer expired, restriksi peer over-limit, dan reset data usage bulanan.
|
||||||
- **i18n & Themes**: Multi-bahasa, dark/light mode
|
- **Security**: Autentikasi API Key (`wg-rplane-datadunia`), JWT Bearer token, dan TOTP (2FA).
|
||||||
|
- **Webhook Engine**: Integrasi dengan server remote (Mikrotik, dll). Retry dengan exponential backoff, custom headers, Go template.
|
||||||
|
- **Plugin System**: Notifikasi Telegram, Slack, dan Traffic Logger.
|
||||||
|
- **i18n & Themes**: Multi-bahasa (English, Indonesian, Chinese). Dark/Light/Auto mode.
|
||||||
|
- **Glassmorphism UI**: Desain futuristik dengan frosted glass cards, buttons, dan inputs.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -21,27 +25,56 @@
|
|||||||
```
|
```
|
||||||
wg0.conf (dengan/tanpa #Access)
|
wg0.conf (dengan/tanpa #Access)
|
||||||
↓
|
↓
|
||||||
wg-engine-api (Go) -- membaca API storage (api-policy.json)
|
┌─────────────────────────────────────────────┐
|
||||||
↓ ↓
|
│ WGRplane (Go Binary :10087) │
|
||||||
+-- GET /api/policy (merged: API + #Access fallback)
|
│ ┌───────────┐ ┌──────────┐ ┌──────────┐ │
|
||||||
+-- POST /api/policy (write ke api-policy.json, trigger sync)
|
│ │ Gorilla │ │ GORM │ │ nftables │ │
|
||||||
↓
|
│ │ Mux Router│ │ SQLite │ │ Engine │ │
|
||||||
policy.json (merged: API overrides #Access)
|
│ └───────────┘ └──────────┘ └──────────┘ │
|
||||||
↓
|
│ ┌───────────┐ ┌──────────┐ ┌──────────┐ │
|
||||||
wg-policy-engine.sh (tidak diubah)
|
│ │ Webhook │ │ Scheduler│ │ WebSocket│ │
|
||||||
↓
|
│ │ Engine │ │ Cron │ │ Hub │ │
|
||||||
iptables / ipset rules
|
│ └───────────┘ └──────────┘ └──────────┘ │
|
||||||
|
│ ┌───────────┐ ┌──────────┐ ┌──────────┐ │
|
||||||
|
│ │ Auth │ │ SMTP │ │ Plugins │ │
|
||||||
|
│ │ JWT/TOTP │ │ Email │ │ TG/Slack │ │
|
||||||
|
│ └───────────┘ └──────────┘ └──────────┘ │
|
||||||
|
└─────────────────────────────────────────────┘
|
||||||
|
↓ HTTP/WebSocket
|
||||||
|
┌─────────────────────────────────────────────┐
|
||||||
|
│ Frontend (Vue 3 + TypeScript + Tailwind) │
|
||||||
|
│ Glassmorphism UI, i18n, Dark/Light mode │
|
||||||
|
└─────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Flow Policy Firewall
|
||||||
|
|
||||||
|
```
|
||||||
|
wg0.conf (#Access comments)
|
||||||
|
↓ inotifywait detects change
|
||||||
|
wg-sync-watch.sh (debounced trigger)
|
||||||
|
↓
|
||||||
|
wg-sync-policy.sh (parses wg0.conf → policy.json, atomic write)
|
||||||
|
↓
|
||||||
|
wg-policy-engine.sh (reads policy.json → iptables/ipset rules)
|
||||||
|
↓
|
||||||
|
Active firewall rules (WG_POLICY chain)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tech Stack
|
### Tech Stack
|
||||||
|
|
||||||
| Komponen | Teknologi |
|
| Komponen | Teknologi |
|
||||||
|-----------|------------|
|
|-----------|------------|
|
||||||
| **WGRplane Backend** | Python + Flask |
|
| **Backend** | Go, Gorilla Mux, GORM (SQLite via glebarez/sqlite) |
|
||||||
| **WGRplane Frontend** | Vue.js 3 |
|
| **Frontend** | Vue 3, TypeScript, Vite, TailwindCSS 4, vue-i18n 9 |
|
||||||
| **wg-engine-api** | Go (Golang) |
|
| **Auth** | JWT (golang-jwt/v5), TOTP (pquerna/otp), API Key |
|
||||||
| **Database** | SQLite (default), PostgreSQL/MySQL via SQLAlchemy |
|
| **WebSockets** | gorilla/websocket |
|
||||||
| **Desktop App** | ElectronJS + Vue.js |
|
| **Webhooks** | Go net/http dengan 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 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -49,162 +82,414 @@ iptables / ipset rules
|
|||||||
|
|
||||||
| Service | Port | Autentikasi |
|
| Service | Port | Autentikasi |
|
||||||
|---------|------|---------------|
|
|---------|------|---------------|
|
||||||
| WGRplane Dashboard | **10086** | Session-based + TOTP |
|
| WGRplane (Go API + Frontend) | **10087** | API Key (`wg-rplane-datadunia`) atau JWT Bearer + TOTP opsional |
|
||||||
| wg-engine-api (Go) | **10087** | Custom header: `wg-rplane-datadunia` |
|
|
||||||
|
### Metode Autentikasi
|
||||||
|
|
||||||
|
| Metode | Header | Catatan |
|
||||||
|
|--------|--------|---------|
|
||||||
|
| API Key | `wg-rplane-datadunia: <KEY>` | Diatur via env var `WG_API_KEY`. Default: `test-api-key`. |
|
||||||
|
| JWT | `Authorization: Bearer <TOKEN>` | Expired 15 menit. Secret via env var `JWT_SECRET`. |
|
||||||
|
| TOTP | `X-TOTP: <CODE>` | Wajib jika user mengaktifkan TOTP. |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## API Endpoints (wg-engine-api)
|
## API Endpoints
|
||||||
|
|
||||||
### Autentikasi
|
Semua endpoint dilayani di port `10087`.
|
||||||
Semua request harus menyertakan header:
|
|
||||||
```
|
|
||||||
wg-rplane-datadunia: <TOKEN>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Endpoints
|
### Servers
|
||||||
|
|
||||||
| Endpoint | Method | Deskripsi |
|
| Endpoint | Method | Deskripsi |
|
||||||
|----------|--------|-------------|
|
|----------|--------|-------------|
|
||||||
| `/api/policy` | GET | Ambil policy.json (merge: API + #Access fallback) |
|
| `/api/servers` | `GET` | Daftar semua server WireGuard. |
|
||||||
| `/api/policy` | POST | Update policy (simpan ke api-policy.json, trigger sync) |
|
| `/api/servers` | `POST` | Buat server baru. Body: `{name, mode, publicKey, endpoint}`. |
|
||||||
| `/api/reload` | POST | Trigger wg-policy-engine.sh untuk apply rules |
|
| `/api/servers/{id}` | `GET` | Ambil satu server berdasarkan ID. |
|
||||||
|
| `/api/servers/{id}` | `PUT` | Update server (name, mode, publicKey, endpoint). |
|
||||||
|
| `/api/servers/{id}` | `DELETE` | Hapus server beserta peer dan webhook-nya. |
|
||||||
|
|
||||||
### Contoh Penggunaan
|
### Peers
|
||||||
|
|
||||||
```bash
|
| Endpoint | Method | Deskripsi |
|
||||||
# Ambil policy
|
|----------|--------|-------------|
|
||||||
curl -H "wg-rplane-datadunia: VALID_TOKEN" http://localhost:10087/api/policy
|
| `/api/servers/{id}/peers` | `GET` | Daftar semua peer untuk satu server. |
|
||||||
|
| `/api/servers/{id}/peers` | `POST` | Buat peer baru. Body: `{publicKey, ip, allowAccess, allowInternet}`. Mode `forward` langsung apply nftables, mode `standalone` trigger webhook. |
|
||||||
|
| `/api/peers/{id}` | `PUT` | Update peer. Hitung diff dan apply perubahan nftables incremental. |
|
||||||
|
| `/api/peers/{id}` | `DELETE` | Hapus peer. Bersihkan rule nftables dan trigger webhook. |
|
||||||
|
| `/api/peers/{id}/config` | `GET` | Download file konfigurasi WireGuard `.conf`. |
|
||||||
|
| `/api/peers/{id}/qrcode` | `GET` | Generate QR code PNG untuk import ke mobile client. |
|
||||||
|
|
||||||
# Update policy untuk client
|
### Webhooks
|
||||||
curl -X POST \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H "wg-rplane-datadunia: VALID_TOKEN" \
|
|
||||||
-d '{"ip": "10.0.0.2", "access": ["1.1.1.1/32"], "internet": true}' \
|
|
||||||
http://localhost:10087/api/policy
|
|
||||||
|
|
||||||
# Trigger reload
|
| Endpoint | Method | Deskripsi |
|
||||||
curl -X POST \
|
|----------|--------|-------------|
|
||||||
-H "wg-rplane-datadunia: VALID_TOKEN" \
|
| `/api/servers/{id}/webhooks` | `GET` | Daftar webhook untuk satu server. |
|
||||||
http://localhost:10087/api/reload
|
| `/api/servers/{id}/webhooks` | `POST` | Buat webhook. Body: `{name, url, template, customBody, customHeaders, subscribedActions, isEnabled, verifySSL}`. |
|
||||||
```
|
| `/api/webhooks/{id}` | `DELETE` | Hapus webhook. |
|
||||||
|
|
||||||
|
### SMTP Settings
|
||||||
|
|
||||||
|
| Endpoint | Method | Deskripsi |
|
||||||
|
|----------|--------|-------------|
|
||||||
|
| `/api/settings/smtp` | `GET` | Ambil konfigurasi SMTP saat ini. |
|
||||||
|
| `/api/settings/smtp` | `POST` | Simpan/update pengaturan SMTP untuk notifikasi email. |
|
||||||
|
|
||||||
|
### Statistics
|
||||||
|
|
||||||
|
| Endpoint | Method | Deskripsi |
|
||||||
|
|----------|--------|-------------|
|
||||||
|
| `/api/stats` | `GET` | Statistik global: total server, peer, webhook. |
|
||||||
|
| `/api/servers/{id}/stats` | `GET` | Statistik per server: jumlah peer, webhook, detail server. |
|
||||||
|
|
||||||
|
### WebSocket
|
||||||
|
|
||||||
|
| Endpoint | Protokol | Deskripsi |
|
||||||
|
|----------|----------|-------------|
|
||||||
|
| `/ws/stats` | WebSocket | Broadcast statistik real-time (interval 5 detik). |
|
||||||
|
|
||||||
|
### TOTP Setup
|
||||||
|
|
||||||
|
| Endpoint | Method | Deskripsi |
|
||||||
|
|----------|--------|-------------|
|
||||||
|
| `/auth/setup-totp?user=<USER>` | `GET` | Generate TOTP secret dan provisioning URI untuk user. |
|
||||||
|
|
||||||
|
### Swagger Documentation
|
||||||
|
|
||||||
|
| Endpoint | Deskripsi |
|
||||||
|
|----------|-----------|
|
||||||
|
| `/swagger/` | Swagger UI untuk dokumentasi API interaktif. |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Migration: #Access ke API
|
## Hybrid Mode
|
||||||
|
|
||||||
| Aspek | Detail |
|
Backend Go mendukung dua mode server:
|
||||||
|
|
||||||
|
- **`forward`** -- Instance WGRplane langsung apply rule nftables di mesin lokal. Policy peer enforced langsung via perintah `nft`.
|
||||||
|
- **`standalone`** -- Instance bertindak sebagai control plane yang trigger webhook ke server WireGuard remote. Policy enforcement terjadi di sisi remote.
|
||||||
|
|
||||||
|
### 2-Column Policy
|
||||||
|
|
||||||
|
Setiap peer memiliki dua kolom policy independen:
|
||||||
|
|
||||||
|
| Kolom | Fungsi |
|
||||||
|-------|--------|
|
|-------|--------|
|
||||||
| **Strategi** | API with #Access fallback (API dicoba pertama, fallback ke #Access) |
|
| **AllowAccess** | Daftar CIDR yang bisa dijangkau peer (target internal). |
|
||||||
| **Precedence** | API policy OVERRIDE #Access untuk IP client yang sama |
|
| **AllowInternet** | Boolean flag. Jika `true`, peer mendapat akses internet tanpa batas (MASQUERADE). |
|
||||||
| **Storage API** | `/etc/wireguard/api-policy.json` (terpisah dari policy.json) |
|
|
||||||
| **Locking** | Menggunakan `/var/lock/wg-policy.lock` (SAMA dengan script shell) |
|
Peer yang tidak punya rule apapun terisolasi dari peer lain dan dari internet secara default.
|
||||||
| **Atomic Write** | Tulis ke tmp file → `mv` (mencegah corrupt saat crash) |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Instalasi
|
## Instalasi
|
||||||
|
|
||||||
|
### Opsi 1: Docker Compose (Direkomendasikan)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone repository
|
||||||
|
git clone https://git.datadunia.com/hainzero/WGRplane.git
|
||||||
|
cd 03.wireguard-policy
|
||||||
|
|
||||||
|
# Start WGRplane dan WireGuard
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# Akses dashboard
|
||||||
|
# http://localhost:10087
|
||||||
|
```
|
||||||
|
|
||||||
|
Stack compose menjalankan:
|
||||||
|
- **WGRplane** di port `10087` (Go API + Vue frontend)
|
||||||
|
- **WireGuard** container dengan host networking untuk akses kernel module
|
||||||
|
|
||||||
|
### Opsi 2: Install Script
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Jalankan installer otomatis (Ubuntu/Debian/CentOS)
|
||||||
|
sudo ./install.sh install
|
||||||
|
|
||||||
|
# Uninstall
|
||||||
|
sudo ./install.sh uninstall
|
||||||
|
```
|
||||||
|
|
||||||
|
Install script menangani instalasi Docker, cloning repository, pembuatan `.env`, dan startup service.
|
||||||
|
|
||||||
|
### Opsi 3: Manual Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build binary Go
|
||||||
|
cd app
|
||||||
|
go build -o ../wgrplane .
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Build frontend
|
||||||
|
cd app/frontend
|
||||||
|
npm install && npm run build
|
||||||
|
cd ../..
|
||||||
|
|
||||||
|
# Jalankan
|
||||||
|
./wgrplane
|
||||||
|
# Server start di :10087
|
||||||
|
```
|
||||||
|
|
||||||
|
### Opsi 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
|
||||||
|
|
||||||
|
# Lihat log
|
||||||
|
journalctl -u wgrplane.service -f
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Konfigurasi
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
| Variable | Default | Deskripsi |
|
||||||
|
|----------|---------|-----------|
|
||||||
|
| `WG_API_KEY` | `test-api-key` | API key untuk autentikasi header-based. |
|
||||||
|
| `JWT_SECRET` | `secret` | Secret untuk signing JWT token. |
|
||||||
|
| `APP_FRONTEND_DIR` | `/var/www/frontend` | Path ke asset frontend yang sudah di-build. |
|
||||||
|
| `WG_RPLANE_MODE` | `forward` | Mode server default (`forward` atau `standalone`). |
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
WGRplane menggunakan SQLite secara default (`wgrplane.db`). Model auto-migrate saat startup:
|
||||||
|
|
||||||
|
- **Server** -- Entry server WireGuard dengan mode dan endpoint.
|
||||||
|
- **Peer** -- Entry peer dengan IP, rule akses, limit data, expiry.
|
||||||
|
- **Webhook** -- Konfigurasi webhook dengan template dan filter aksi.
|
||||||
|
- **SMTPSettings** -- Konfigurasi server SMTP untuk notifikasi email.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Scheduler
|
||||||
|
|
||||||
|
Backend Go menjalankan tiga cron job:
|
||||||
|
|
||||||
|
| Jadwal | Job | Aksi |
|
||||||
|
|--------|-----|------|
|
||||||
|
| Setiap hari 02:00 | `deleteExpiredPeers` | Hapus peer yang sudah melewati `ExpiresAt`. |
|
||||||
|
| Setiap hari 03:00 | `restrictOverLimitPeers` | Disable peer yang melebihi `DataLimitGB`. |
|
||||||
|
| Tanggal 1 setiap bulan | `resetMonthlyUsage` | Reset `CurrentDataUsageBytes` ke nol untuk semua peer. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Webhook Payload
|
||||||
|
|
||||||
|
Webhook trigger pada event lifecycle peer (`peer_created`, `peer_updated`, `peer_deleted`, `policy_changed`). Engine mendukung tiga mode template: `default` (JSON mentah), `mikrotik` (format RouterOS), dan `custom` (Go template).
|
||||||
|
|
||||||
|
### Fitur Webhook
|
||||||
|
|
||||||
|
- **Retry dengan backoff**: Delivery gagal retry hingga 3 kali dengan exponential backoff (2s, 4s, 8s).
|
||||||
|
- **Verifikasi SSL**: Bisa di-toggle per-webhook via `verifySSL`.
|
||||||
|
- **Custom headers**: Inject header per-webhook via `customHeaders` JSON.
|
||||||
|
- **Global webhooks**: Set `isGlobal: true` untuk trigger di semua server.
|
||||||
|
- **Filter aksi**: Subscribe ke event spesifik via array `subscribedActions`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## UI Frontend
|
||||||
|
|
||||||
|
Frontend adalah Vue 3 + TypeScript SPA dengan desain glassmorphism.
|
||||||
|
|
||||||
|
### Design System
|
||||||
|
|
||||||
|
- **Glassmorphism**: Frosted glass cards, buttons, dan inputs dengan efek backdrop blur.
|
||||||
|
- **TailwindCSS 4**: Utility-first styling dengan dukungan dark mode penuh via `dark:` variants.
|
||||||
|
- **Responsive**: Layout mobile-first yang adaptif di semua ukuran layar.
|
||||||
|
|
||||||
|
### Fitur UI
|
||||||
|
|
||||||
|
| Fitur | Deskripsi |
|
||||||
|
|-------|-----------|
|
||||||
|
| **Multi-bahasa (i18n)** | English, Indonesian, dan Chinese via vue-i18n 9. Locale auto-detect dari browser. |
|
||||||
|
| **Theme Switching** | Dark / Light / Auto (ikuti preferensi sistem) via `@vueuse/core`. |
|
||||||
|
| **Real-time Stats** | Koneksi WebSocket broadcast jumlah peer dan data trafik setiap 5 detik. |
|
||||||
|
| **Charts** | Visualisasi trafik via Chart.js + vue-chartjs. |
|
||||||
|
| **Toast Notifications** | Alert non-intrusif via vue-sonner. |
|
||||||
|
| **QR Code Import** | Generate QR code yang bisa di-scan untuk setup mobile WireGuard client. |
|
||||||
|
|
||||||
|
### Struktur Frontend
|
||||||
|
|
||||||
|
```
|
||||||
|
app/frontend/src/
|
||||||
|
├── App.vue # Root component dengan provider theme/i18n
|
||||||
|
├── main.ts # Bootstrap app (Vue, Router, i18n)
|
||||||
|
├── router/ # Definisi Vue Router
|
||||||
|
├── i18n/ # File locale (en.json, id.json, zh.json)
|
||||||
|
├── components/ # Komponen Glass UI (Card, Button, Input, Toggle)
|
||||||
|
├── composables/ # Vue composables (useTheme, useWebSocket)
|
||||||
|
├── views/ # Page components (Dashboard, Servers, Peers, Settings, Webhooks)
|
||||||
|
└── types/ # Definisi tipe TypeScript
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Policy Firewall (`#Access`)
|
||||||
|
|
||||||
|
Engine policy berbasis shell enforcing rule firewall per-peer langsung dari `wg0.conf`.
|
||||||
|
|
||||||
|
### Cara Kerja
|
||||||
|
|
||||||
|
1. Tambahkan komentar `#Access` di bawah setiap blok `[Peer]` di `wg0.conf`.
|
||||||
|
2. Watcher daemon (`wg-sync-watch.sh`) mendeteksi perubahan file via `inotifywait`.
|
||||||
|
3. `wg-sync-policy.sh` parse config dan tulis `policy.json` secara atomik.
|
||||||
|
4. `wg-policy-engine.sh` baca JSON dan apply rule iptables/ipset.
|
||||||
|
|
||||||
|
### Contoh `wg0.conf`
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Interface]
|
||||||
|
Address = 10.0.0.1/24
|
||||||
|
ListenPort = 51820
|
||||||
|
PrivateKey = <SERVER_PRIVATE_KEY>
|
||||||
|
|
||||||
|
PostUp = /usr/local/bin/wg-sync-policy.sh; /usr/local/bin/wg-policy-engine.sh
|
||||||
|
PostDown = /usr/local/bin/wg-policy-cleanup.sh
|
||||||
|
|
||||||
|
[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
|
||||||
|
# Access kosong = internet-only, isolasi client berlaku
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mengapa `#Access` Bukan `AllowedIPs`?
|
||||||
|
|
||||||
|
WireGuard menggunakan `AllowedIPs` untuk Cryptokey Routing. Memasukkan IP destinasi di `AllowedIPs` server akan menyebabkan WireGuard meroute traffic untuk IP tersebut ke dalam tunnel client. Komentar `#Access` memisahkan konfigurasi firewall dari routing secara bersih.
|
||||||
|
|
||||||
|
### CLI: `wg-policy-ctl`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wg-policy-ctl status # Health check, status lock, jumlah rule
|
||||||
|
wg-policy-ctl policy # Lihat raw policy.json
|
||||||
|
wg-policy-ctl rules # Inspect rule iptables aktif
|
||||||
|
wg-policy-ctl ipset # Lihat mapping ipset
|
||||||
|
wg-policy-ctl reload # Force re-sync dan re-apply
|
||||||
|
wg-policy-ctl log # Lihat log packet dropped
|
||||||
|
wg-policy-ctl stats # Statistik koneksi
|
||||||
|
wg-policy-ctl validate # Validasi schema policy.json
|
||||||
|
```
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
```bash
|
| Package | Diperlukan | Install |
|
||||||
# Python dependencies (WGRplane)
|
|---------|------------|---------|
|
||||||
pip install -r requirements.txt
|
| `jq` | Ya | `apt install jq` |
|
||||||
|
| `inotify-tools` | Ya (watcher daemon) | `apt install inotify-tools` |
|
||||||
|
| `ipset` | Opsional | `apt install ipset` |
|
||||||
|
|
||||||
|
Tanpa `ipset`, engine fallback ke entry iptables per-rule. Ini bekerja untuk deployment kecil. Untuk jumlah peer besar, `ipset` memberikan performa lookup O(1).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Plugins
|
||||||
|
|
||||||
|
Sistem plugin menyediakan interface notifikasi sederhana. Plugin bawaan:
|
||||||
|
|
||||||
|
- **TelegramNotifier** -- Kirim pesan Telegram saat event.
|
||||||
|
- **SlackNotifier** -- Kirim pesan Slack saat event.
|
||||||
|
- **TrafficLogger** -- Log event traffic untuk debugging.
|
||||||
|
|
||||||
|
Plugin dimuat saat startup via `PluginManager.LoadPlugins()` dan menerima event melalui `Trigger(event, payload)`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Struktur Proyek
|
||||||
|
|
||||||
# Go dependencies (wg-engine-api)
|
|
||||||
cd wg-engine-api
|
|
||||||
go mod download
|
|
||||||
```
|
```
|
||||||
|
03.wireguard-policy/
|
||||||
### Jalankan WGRplane (Python/Flask)
|
├── app/ # Go backend + Vue frontend
|
||||||
|
│ ├── main.go # Bootstrap server, routing, init DB
|
||||||
```bash
|
│ ├── handlers.go # REST API route handlers
|
||||||
python app.py
|
│ ├── models.go # GORM models (Server, Peer, Webhook, SMTP)
|
||||||
# atau dengan Gunicorn
|
│ ├── auth.go # JWT, TOTP, API key auth middleware
|
||||||
gunicorn -w 4 -b 0.0.0.0:10086 app:app
|
│ ├── nftables.go # nftables rule management (mode forward)
|
||||||
```
|
│ ├── webhook.go # Webhook engine dengan retry/backoff
|
||||||
|
│ ├── scheduler.go # Cron jobs (expiry, data limit, reset)
|
||||||
### Jalankan wg-engine-api (Go)
|
│ ├── stats.go # WebSocket Hub untuk real-time stats
|
||||||
|
│ ├── email.go # Notifikasi email SMTP
|
||||||
```bash
|
│ ├── plugins.go # Plugin system (Telegram, Slack, Logger)
|
||||||
cd wg-engine-api
|
│ ├── validation.go # Input validators (IP, CIDR, PublicKey)
|
||||||
go build -o wg-engine-api .
|
│ ├── wg.go # WireGuard key generation, config export
|
||||||
./wg-engine-api &
|
│ ├── i18n.go # Backend i18n (en/id/zh)
|
||||||
# atau install ke /usr/local/bin/
|
│ ├── docs/ # Swagger documentation
|
||||||
cp wg-engine-api /usr/local/bin/
|
│ └── frontend/ # Vue 3 SPA (TypeScript, TailwindCSS)
|
||||||
|
├── 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 untuk manajemen
|
||||||
|
├── wg-policy-cleanup.sh # Cleanup script untuk PostDown
|
||||||
|
├── wg-policy.service # Systemd unit untuk watcher daemon
|
||||||
|
├── wgrplane.service # Systemd unit untuk Go backend
|
||||||
|
├── install.sh # Automated installer (Docker + services)
|
||||||
|
├── Dockerfile # Multi-stage Docker build
|
||||||
|
├── docker-compose.yml # Docker Compose stack
|
||||||
|
├── build.sh / build.bat # Script rebuild installer
|
||||||
|
└── README.md # Dokumentasi ini
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
### Bats (Shell Scripts)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
apt install bats
|
|
||||||
bats /tests/policy.bats
|
|
||||||
```
|
|
||||||
|
|
||||||
### Go Tests (wg-engine-api)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd wg-engine-api
|
|
||||||
go test ./...
|
|
||||||
```
|
|
||||||
|
|
||||||
### Manual QA
|
### Manual QA
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Test auth
|
# Test auth (tanpa header)
|
||||||
curl -H "wg-rplane-datadunia: wrong" http://localhost:10087/api/policy
|
curl http://localhost:10087/api/servers
|
||||||
# Expected: 401 Unauthorized
|
# Expected: 401 Unauthorized
|
||||||
|
|
||||||
# Test policy retrieval
|
# Test auth (header salah)
|
||||||
curl -H "wg-rplane-datadunia: VALID_TOKEN" http://localhost:10087/api/policy
|
curl -H "wg-rplane-datadunia: wrong" http://localhost:10087/api/servers
|
||||||
|
# Expected: 401 Unauthorized
|
||||||
|
|
||||||
# Test policy update
|
# Test auth (header benar)
|
||||||
curl -X POST -H "Content-Type: application/json" \
|
curl -H "wg-rplane-datadunia: test-api-key" http://localhost:10087/api/servers
|
||||||
-H "wg-rplane-datadunia: VALID_TOKEN" \
|
# Expected: 200 OK, daftar server
|
||||||
-d '{"ip": "10.0.0.2", "access": ["1.1.1.1/32"]}' \
|
|
||||||
http://localhost:10087/api/policy
|
|
||||||
|
|
||||||
# Verify iptables rules
|
# Test buat server
|
||||||
|
curl -X POST \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "wg-rplane-datadunia: test-api-key" \
|
||||||
|
-d '{"name":"wg-01","mode":"forward","publicKey":"<PUBKEY>","endpoint":"vpn.example.com:51820"}' \
|
||||||
|
http://localhost:10087/api/servers
|
||||||
|
|
||||||
|
# Test buat peer
|
||||||
|
curl -X POST \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "wg-rplane-datadunia: test-api-key" \
|
||||||
|
-d '{"publicKey":"<PEER_PUBKEY>","ip":"10.0.0.2","allowAccess":["192.168.1.0/24"],"allowInternet":true}' \
|
||||||
|
http://localhost:10087/api/servers/1/peers
|
||||||
|
|
||||||
|
# Test QR code
|
||||||
|
curl -H "wg-rplane-datadunia: test-api-key" http://localhost:10087/api/peers/1/qrcode --output peer-qr.png
|
||||||
|
|
||||||
|
# Verifikasi rule iptables
|
||||||
wg-policy-ctl rules
|
wg-policy-ctl rules
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Deployment
|
|
||||||
|
|
||||||
### Systemd Services
|
|
||||||
|
|
||||||
WGRplane menggunakan systemd untuk manajemen service:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Copy systemd units
|
|
||||||
cp wg-policy.service wg-policy-health.timer wg-policy-health.service /etc/systemd/system/
|
|
||||||
|
|
||||||
# Enable & start
|
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
### Install Script
|
|
||||||
|
|
||||||
Gunakan `install.sh` untuk instalasi otomatis:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo ./install.sh install
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Dokumentasi Tambahan
|
## Dokumentasi Tambahan
|
||||||
|
|
||||||
- **Plan File**: `plan.md` (detail rencana implementasi 20 tasks dalam 7 fase)
|
- **Plan File**: `plan.md` (detail rencana implementasi)
|
||||||
- **AGENTS.md**: Panduan untuk AI agent dalam mengembangkan proyek ini
|
- **AGENTS.md**: Panduan untuk AI agent dalam mengembangkan proyek ini
|
||||||
- **Parent Repo**: `https://git.datadunia.com/hainzero/WGRplane.git` (submodule di `/app`)
|
- **Parent Repo**: `https://git.datadunia.com/hainzero/WGRplane.git` (submodule di `/app`)
|
||||||
|
|
||||||
@@ -212,4 +497,4 @@ sudo ./install.sh install
|
|||||||
|
|
||||||
## Lisensi
|
## Lisensi
|
||||||
|
|
||||||
Proyek ini mengikuti lisensi dari WGDashboard (donaldzou/WGDashboard) dan modifikasi untuk integrasi policy.json API.
|
Proyek ini membangun konsep dari WGDashboard (donaldzou/WGDashboard) dengan modifikasi untuk integrasi policy.json API dan dynamic firewall enforcement.
|
||||||
|
|||||||
Reference in New Issue
Block a user