Docs: add IP forwarding/NAT section for client-to-LAN access
The most common OpenVPN deployment scenario is letting remote users
access the server's LAN (office/home network). This requires:
1. net.ipv4.ip_forward=1
2. iptables MASQUERADE on the LAN-facing interface
3. push 'route <LAN-net>' so clients know to send LAN traffic through VPN
Previously this was only mentioned in the FAQ row 'ping不通服务端',
with no actionable instructions. Users (including the project's own
first deployment) hit this exact issue and had to figure it out from
forum posts.
Changes:
README.md:
- New section 'IP 转发与内网访问' before 防火墙与公网暴露
- Covers: enabling ip_forward (immediate + persistent via sysctl.d),
MASQUERADE rules for one/multiple LAN interfaces, push routes,
verification commands, troubleshooting table, full checklist
- FAQ table: add explicit row for 'gateway reachable, LAN not'
- Features table: add '内网转发' row
- TOC: link new section
scripts/install.sh:
- Auto-enable ip_forward on install (idempotent, persistent via
/etc/sysctl.d/99-openvpn-manager.conf)
- Skip silently in containerized environments (no /proc/sys write)
- Print reminder about manual MASQUERADE rule with link to docs
This commit is contained in:
@@ -23,8 +23,9 @@
|
|||||||
- [二、首次配置](#二首次配置)
|
- [二、首次配置](#二首次配置)
|
||||||
- [登录 Web 控制台](#登录-web-控制台)
|
- [登录 Web 控制台](#登录-web-控制台)
|
||||||
- [修改默认密码](#修改默认密码)
|
- [修改默认密码](#修改默认密码)
|
||||||
- [创建第一个实例](#创建第一个实例)
|
| - [创建第一个实例](#创建第一个实例)
|
||||||
- [创建客户端用户并下载配置](#创建客户端用户并下载配置)
|
- [创建客户端用户并下载配置](#创建客户端用户并下载配置)
|
||||||
|
- [IP 转发与内网访问](#ip-转发与内网访问客户端访问服务端-lan)
|
||||||
- [防火墙与公网暴露](#防火墙与公网暴露)
|
- [防火墙与公网暴露](#防火墙与公网暴露)
|
||||||
- [三、访问控制(白名单模式)](#三访问控制白名单模式)
|
- [三、访问控制(白名单模式)](#三访问控制白名单模式)
|
||||||
- [四、客户端使用](#四客户端使用)
|
- [四、客户端使用](#四客户端使用)
|
||||||
@@ -58,6 +59,7 @@
|
|||||||
| 一键恢复 | 上传/选择已有备份,直接覆盖还原 |
|
| 一键恢复 | 上传/选择已有备份,直接覆盖还原 |
|
||||||
| 操作审计 | 所有写操作(创建/修改/删除/吊销/备份)持久化,记录操作者/IP/结果 |
|
| 操作审计 | 所有写操作(创建/修改/删除/吊销/备份)持久化,记录操作者/IP/结果 |
|
||||||
| JWT 鉴权 | 登录后 12 小时有效 token,无状态可水平扩展 |
|
| JWT 鉴权 | 登录后 12 小时有效 token,无状态可水平扩展 |
|
||||||
|
| **内网转发** | 文档化 IP 转发 + NAT 一键配置,客户端可访问服务端 LAN |
|
||||||
|
|
||||||
## 架构概览
|
## 架构概览
|
||||||
|
|
||||||
@@ -369,6 +371,127 @@ Web → "用户管理":
|
|||||||
|
|
||||||
直接发给用户即可,无需额外的 `ca.crt` 等文件。
|
直接发给用户即可,无需额外的 `ca.crt` 等文件。
|
||||||
|
|
||||||
|
## IP 转发与内网访问(客户端访问服务端 LAN)
|
||||||
|
|
||||||
|
**场景**: 客户端连上 VPN 后,想访问服务端所在的局域网设备(如 `172.16.2.0/24` 网段的服务器、打印机、NAS 等)。
|
||||||
|
|
||||||
|
**前提**: 客户端能 ping 通 VPN 网关(`10.8.0.1`),但访问不了 LAN(如 `ping 172.16.2.30` 失败)。
|
||||||
|
|
||||||
|
OpenVPN 默认**只让客户端访问 VPN 子网本身**,不能直接访问服务端 LAN。要打通,服务端需要做两件事:
|
||||||
|
|
||||||
|
1. **开启 IP 转发**(`net.ipv4.ip_forward=1`),让内核把 VPN 客户端的包从 tun 设备转到 LAN 网卡。
|
||||||
|
2. **配置 NAT(MASQUERADE)**,让 VPN 客户端的源 IP 在离开服务端时被替换成 LAN 网卡 IP,这样 LAN 设备知道怎么回包。
|
||||||
|
|
||||||
|
### 一键启用(推荐)
|
||||||
|
|
||||||
|
如果服务端只有一个网卡接 LAN(典型场景),执行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 立即启用 IP 转发
|
||||||
|
sudo sysctl -w net.ipv4.ip_forward=1
|
||||||
|
|
||||||
|
# 2. 持久化(重启不丢)
|
||||||
|
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-openvpn-manager.conf
|
||||||
|
|
||||||
|
# 3. 添加 NAT 规则
|
||||||
|
# eth0 是服务端接 LAN 的网卡名(可能是 ens192/eno1/enp0s3 等,用 ip a 查看)
|
||||||
|
LAN_IF="eth0" # ← 改成实际网卡名
|
||||||
|
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o "$LAN_IF" -j MASQUERADE
|
||||||
|
sudo iptables -A FORWARD -i "$LAN_IF" -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||||
|
sudo iptables -A FORWARD -i tun+ -o "$LAN_IF" -j ACCEPT
|
||||||
|
|
||||||
|
# 4. 持久化 iptables(重启不丢)
|
||||||
|
sudo apt-get install -y iptables-persistent # Debian/Ubuntu
|
||||||
|
sudo netfilter-persistent save # 保存当前规则
|
||||||
|
# 或: sudo service iptables save # CentOS/RHEL
|
||||||
|
```
|
||||||
|
|
||||||
|
> **为什么是 `tun+`?**: OpenVPN 用 `tun0/tun1...` 设备,`+` 通配匹配所有 tun 设备。多个实例并存也能用。
|
||||||
|
|
||||||
|
### 验证
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 服务端视角: 应该看到一条 MASQUERADE 规则
|
||||||
|
sudo iptables -t nat -L POSTROUTING -n -v | grep MASQUERADE
|
||||||
|
|
||||||
|
# 客户端视角: VPN 连接后
|
||||||
|
ping 10.8.0.1 # 必通(网关)
|
||||||
|
ping <服务端 LAN 上的某个 IP> # 通了说明成功
|
||||||
|
curl ifconfig.me # 显示服务端公网 IP,说明 NAT 生效
|
||||||
|
```
|
||||||
|
|
||||||
|
### 找对 LAN 网卡
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ip -br a # 简略列出所有网卡和 IP
|
||||||
|
ip route | grep default # 看默认路由走哪块网卡 — 通常就是 LAN 网卡
|
||||||
|
```
|
||||||
|
|
||||||
|
例:
|
||||||
|
```
|
||||||
|
default via 172.16.2.254 dev ens192 → LAN 网卡是 ens192
|
||||||
|
```
|
||||||
|
|
||||||
|
### push 路由(让客户端知道去 LAN 怎么走)
|
||||||
|
|
||||||
|
光在服务端做 NAT 不够,还得让**客户端知道** "要去 `172.16.2.0/24` 就走 VPN"。两种做法:
|
||||||
|
|
||||||
|
**方法 A:在实例里 push 路由(推荐)**
|
||||||
|
|
||||||
|
编辑实例的 `server.conf`,添加:
|
||||||
|
```
|
||||||
|
push "route 172.16.2.0 255.255.255.0"
|
||||||
|
```
|
||||||
|
然后在 Web 面板重启实例。
|
||||||
|
|
||||||
|
**方法 B:在 Web 面板"实例管理"里配置**
|
||||||
|
|
||||||
|
把 LAN 网段加到实例的 **AccessMode** 白名单或 **push 路由列表**。白名单模式下 `allow_networks` 会自动生成对应的 push 路由。
|
||||||
|
|
||||||
|
### 多网卡/复杂路由场景
|
||||||
|
|
||||||
|
如果服务端有**多块 LAN 网卡**(如同时接公司网和家庭网),MASQUERADE 规则要分别添加:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
for IF in ens192 ens224; do
|
||||||
|
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o "$IF" -j MASQUERADE
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
或者直接用 `-o eth+` 一次性匹配所有以太网卡(不太安全,慎用):
|
||||||
|
```bash
|
||||||
|
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE
|
||||||
|
```
|
||||||
|
|
||||||
|
### 排障
|
||||||
|
|
||||||
|
| 症状 | 排查 |
|
||||||
|
| ---- | ---- |
|
||||||
|
| 客户端能 ping 通 10.8.0.1,ping 不通 LAN | 没开 IP 转发,或没加 MASQUERADE 规则 |
|
||||||
|
| 能 ping 通 LAN IP,但 SSH/服务不通 | LAN 设备防火墙拒绝 VPN 子网;在 LAN 设备上 `iptables -I INPUT -s 10.8.0.0/24 -j ACCEPT` |
|
||||||
|
| 重启后规则丢失 | 没装 iptables-persistent 或没保存;参考上文持久化步骤 |
|
||||||
|
| ping 得通但访问慢/丢包 | MTU 问题;在 server.conf 加 `tun-mtu 1400 mssfix 1360` |
|
||||||
|
| ip_forward 已开但客户端仍上不了网 | push 路由缺失;客户端路由表里没有目标 LAN 网段 |
|
||||||
|
|
||||||
|
### 检查清单
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 转发开关
|
||||||
|
cat /proc/sys/net/ipv4/ip_forward # 必须输出 1
|
||||||
|
|
||||||
|
# 2. NAT 规则
|
||||||
|
sudo iptables -t nat -L POSTROUTING -n # 应该有 10.8.0.0/24 的 MASQUERADE
|
||||||
|
|
||||||
|
# 3. FORWARD 策略(默认 ACCEPT 还是 DROP?)
|
||||||
|
sudo iptables -L FORWARD # 看到 policy DROP 就需要显式 ACCEPT tun+ ↔ LAN 的包
|
||||||
|
|
||||||
|
# 4. 客户端路由
|
||||||
|
# VPN 连接后,在客户端执行:
|
||||||
|
ip route # 应该看到 "10.8.0.0/24 dev tun0" 和 "172.16.2.0/24 via 10.8.0.1 dev tun0"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 防火墙与公网暴露
|
## 防火墙与公网暴露
|
||||||
|
|
||||||
1. Web 管理端口(默认 8089)**不建议直接暴露公网**,建议:
|
1. Web 管理端口(默认 8089)**不建议直接暴露公网**,建议:
|
||||||
@@ -647,8 +770,9 @@ sudo dnf install -y NetworkManager-openvpn NetworkManager-openvpn-gnome # F
|
|||||||
| 症状 | 可能原因 |
|
| 症状 | 可能原因 |
|
||||||
| ---- | -------- |
|
| ---- | -------- |
|
||||||
| 连接后立刻断开 | 客户端证书与 CA 不匹配;服务端证书过期 |
|
| 连接后立刻断开 | 客户端证书与 CA 不匹配;服务端证书过期 |
|
||||||
| 拿到 IP 但 ping 不通服务端 | 防火墙没允许 UDP 1194;服务端没启用 IP 转发 |
|
| 拿到 IP 但 ping 不通服务端 | 防火墙没允许 UDP 1194;服务端没启用 IP 转发(见 [IP 转发与内网访问](#ip-转发与内网访问客户端访问服务端-lan)) |
|
||||||
| 拿到 IP 但访问不了互联网 | 没推送 DNS,或客户端没把 VPN 设为默认网关 |
|
| 拿到 IP 但访问不了互联网 | 没推送 DNS,或客户端没把 VPN 设为默认网关 |
|
||||||
|
| 拿到 IP 能 ping 通网关,访问不了 LAN | **没做服务端 NAT** — 见 [IP 转发与内网访问](#ip-转发与内网访问客户端访问服务端-lan) |
|
||||||
| Android 连不上 | 服务器在 NAT 后,检查运营商是否屏蔽 UDP |
|
| Android 连不上 | 服务器在 NAT 后,检查运营商是否屏蔽 UDP |
|
||||||
| iOS 连不上 | 看 OpenVPN 日志(应用内 OpenVPN → Settings → Log) |
|
| iOS 连不上 | 看 OpenVPN 日志(应用内 OpenVPN → Settings → Log) |
|
||||||
|
|
||||||
|
|||||||
@@ -172,6 +172,25 @@ for i in 1 2 3 4 5; do
|
|||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# ---------- 启用 IP 转发 (客户端访问服务端 LAN 的前提) ----------
|
||||||
|
echo "==> 启用 IPv4 转发 (客户端访问服务端 LAN 需要)"
|
||||||
|
if [[ -w /proc/sys/net/ipv4/ip_forward ]]; then
|
||||||
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||||
|
# 持久化(下次重启不丢)
|
||||||
|
CONF_FILE="/etc/sysctl.d/99-openvpn-manager.conf"
|
||||||
|
if [[ ! -f "$CONF_FILE" ]] || ! grep -q "^net.ipv4.ip_forward=1" "$CONF_FILE" 2>/dev/null; then
|
||||||
|
echo "net.ipv4.ip_forward=1" > "$CONF_FILE"
|
||||||
|
sysctl -p "$CONF_FILE" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
echo " ✓ IP 转发已启用 (持久化到 $CONF_FILE)"
|
||||||
|
echo " 提示: 如需让客户端访问服务端 LAN 网段, 还需手动添加 iptables NAT 规则:"
|
||||||
|
echo " sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o <LAN网卡> -j MASQUERADE"
|
||||||
|
echo " 详见 README \"IP 转发与内网访问\" 章节"
|
||||||
|
else
|
||||||
|
echo " ! 无法写入 /proc/sys/net/ipv4/ip_forward (容器环境?) — 跳过"
|
||||||
|
echo " 如需客户端访问服务端 LAN, 请在宿主机启用: sysctl -w net.ipv4.ip_forward=1"
|
||||||
|
fi
|
||||||
|
|
||||||
# ---------- 完成提示 ----------
|
# ---------- 完成提示 ----------
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user