Add per-instance/user access whitelist

Features:
- New Instance.AccessMode: "open" (default) or "whitelist"
- New Instance.AllowNetworks + VPNUser.AllowNetworks: list of CIDRs
- Effective whitelist = instance allow_networks ∪ user allow_networks (dedup)
- Auto-generates client-connect.sh / client-disconnect.sh for OpenVPN:
    * Reads ccd/<cn> to extract CIDRs
    * Pushes "route <ip> <mask>" to client (client side)
    * Inserts iptables ACCEPT rules in FORWARD chain (server side, defense in depth)
    * Cleans up rules on disconnect
- server.conf auto-includes client-connect / client-disconnect directives
  and push "redirect-gateway def1 bypass-dhcp" in whitelist mode
- ccd/<cn> file format: first line ifconfig-push (static IP), then one CIDR per line
- Editing instance allow_networks refreshes all users' ccd automatically
- New PUT /api/instances/:id/users/:uid endpoint
- CIDR format validation; reject malformed inputs with friendly errors
- Dashboard shows whitelist_instances count and per-instance allow_networks table

Docs:
- README: new section "三、访问控制(白名单模式)" with usage, validation, pitfalls
- docs/API.md: updated Instance / VPNUser model + create/update payloads
- Renumbered client usage section as 四
This commit is contained in:
cnbugs
2026-08-09 20:47:21 +08:00
parent 77f8b59290
commit 4c8b7b5188
11 changed files with 697 additions and 64 deletions
+25 -2
View File
@@ -109,11 +109,18 @@ POST /api/instances
"auth_digest": "SHA256", // 可选
"push_dns": "dhcp-option DNS 8.8.8.8\ndhcp-option DNS 1.1.1.1",
"push_routes": "192.168.1.0 255.255.255.0",
"extra": ""
"extra": "",
"access_mode": "whitelist", // open(默认) | whitelist
"allow_networks": ["192.168.1.0/24", "10.0.0.0/8"] // CIDR 列表
}
→ 200 Instance
```
> `access_mode=whitelist` 时,服务端会生成 `client-connect.sh` / `client-disconnect.sh`,
> 通过 OpenVPN `--learn-address` 钩子在每次客户端连接/断开时修改 iptables FORWARD 链,
> 仅放行到 allow_networks 中网段的流量,其他内网访问被 REJECT。
> allow_networks 为空表示完全隔离(最严格)。
### 更新
```
PUT /api/instances/:id
@@ -121,6 +128,8 @@ PUT /api/instances/:id
→ 200 Instance
```
> 修改实例级 `allow_networks` 后,所有用户的 ccd 文件会被自动重写。
### 删除(级联删除该实例下所有用户/证书)
```
DELETE /api/instances/:id
@@ -171,11 +180,22 @@ POST /api/instances/:id/users
"username": "alice",
"real_name": "Alice",
"email": "alice@example.com",
"static_ip": "10.8.0.10" // 可选
"static_ip": "10.8.0.10", // 可选
"allow_networks": ["172.16.0.0/16"] // 可选,用户级白名单(在实例基础上叠加)
}
→ 200 VPNUser
```
### 修改(改 allow_networks / static_ip 等)
```
PUT /api/instances/:id/users/:uid
{...同上}
→ 200 VPNUser
```
> 修改用户的 `allow_networks` 后,会重新生成 ccd 文件,
> 用户重新连接即可拿到新的 push route。
### 吊销
```
POST /api/instances/:id/users/:uid/revoke
@@ -311,6 +331,8 @@ GET /api/audits
"push_dns": "...",
"push_routes": "...",
"extra": "",
"access_mode": "open | whitelist",
"allow_networks": ["192.168.1.0/24", "10.0.0.0/8"],
"status": "running | stopped | error",
"pid": 12345,
"created_at": "...",
@@ -328,6 +350,7 @@ GET /api/audits
"email": "alice@example.com",
"enabled": true,
"static_ip": "10.8.0.10",
"allow_networks": ["172.16.0.0/16"],
"created_at": "...",
"revoked_at": null
}