From 6ccfb57c80c3a1be0d064e01b4b5b2f4b93897c5 Mon Sep 17 00:00:00 2001 From: kevin Date: Mon, 6 Jul 2026 14:42:58 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=BB=98=E8=AE=A4=E5=AD=90=E7=BD=91?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=20192.168.77.0/24=EF=BC=8C=E5=AE=89=E8=A3=85?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E6=8E=88=E6=9D=83=20CAP=5FNET=5FADMIN=20?= =?UTF-8?q?=E4=B8=8E=20iptables=20=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 默认 VPN 子网由 192.168.3.0/24 改为 192.168.77.0/24(db seed、前端表单默认值与 placeholder 同步) - install_linux.sh 顶部增加 VPN_SUBNET 可配置变量 - systemd unit 增加 AmbientCapabilities/CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW,服务以 lmvpn 用户运行即可创建 TUN,无需 root - 脚本自动开启 net.ipv4.ip_forward 并持久化到 /etc/sysctl.d/99-lmvpn.conf - 脚本自动检测出口网卡,幂等配置 iptables NAT MASQUERADE 与 FORWARD 放行规则 - 优先 netfilter-persistent 持久化,回退 iptables-save 写 /etc/iptables/rules.v4 --- frontend/src/views/VpnView.vue | 6 ++-- install_linux.sh | 52 ++++++++++++++++++++++++++++++++++ internal/db/db.go | 2 +- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/frontend/src/views/VpnView.vue b/frontend/src/views/VpnView.vue index 194d6df..c15ab50 100644 --- a/frontend/src/views/VpnView.vue +++ b/frontend/src/views/VpnView.vue @@ -63,7 +63,7 @@ const saveMsg = ref('') const form = ref({ enabled: false, - subnet: '192.168.3.0/24', + subnet: '192.168.77.0/24', mtu: 1420, interface_name: '', allow_client_to_client: false, @@ -331,7 +331,7 @@ onMounted(() => {
- +
@@ -437,7 +437,7 @@ onMounted(() => {
- +

{{ resvError }}

diff --git a/install_linux.sh b/install_linux.sh index 6d76121..d46d607 100755 --- a/install_linux.sh +++ b/install_linux.sh @@ -1,6 +1,12 @@ #!/usr/bin/env bash set -e +# ───────────────────────────────────────────────────────────── +# VPN 子网(与后台 VPN 设置中的子网保持一致) +# 若后台修改了子网,需同步修改此处并重新执行脚本,或手动更新 iptables 规则 +# ───────────────────────────────────────────────────────────── +VPN_SUBNET="192.168.77.0/24" + if [ "$(id -u)" -ne 0 ]; then echo "请使用 root 用户执行此脚本: sudo bash install_linux.sh" exit 1 @@ -33,6 +39,48 @@ cp lmvpn /opt/lmvpn/ cp -r dist /opt/lmvpn/ chown -R lmvpn:lmvpn /opt/lmvpn +echo ">>> 配置内核 IP 转发..." +# 临时生效 +sysctl -w net.ipv4.ip_forward=1 >/dev/null +# 持久化 +cat > /etc/sysctl.d/99-lmvpn.conf << EOF +net.ipv4.ip_forward = 1 +EOF +sysctl -p /etc/sysctl.d/99-lmvpn.conf >/dev/null + +echo ">>> 配置 iptables NAT 与转发规则..." +# 自动检测默认路由出口网卡 +WAN_IFACE=$(ip route show default 2>/dev/null | awk '{print $5; exit}') +if [ -z "$WAN_IFACE" ]; then + echo "警告: 未能自动检测出口网卡,跳过 iptables 配置,请手动设置" +else + echo "出口网卡: $WAN_IFACE" + + # 幂等:先删除旧规则(忽略错误),再添加 + # NAT: VPN 子网经出口网卡做源地址转换 + iptables -t nat -D POSTROUTING -s "$VPN_SUBNET" -o "$WAN_IFACE" -j MASQUERADE 2>/dev/null || true + iptables -t nat -A POSTROUTING -s "$VPN_SUBNET" -o "$WAN_IFACE" -j MASQUERADE + + # FORWARD: 放行 VPN 子网进出 + iptables -D FORWARD -s "$VPN_SUBNET" -j ACCEPT 2>/dev/null || true + iptables -D FORWARD -d "$VPN_SUBNET" -j ACCEPT 2>/dev/null || true + iptables -A FORWARD -s "$VPN_SUBNET" -j ACCEPT + iptables -A FORWARD -d "$VPN_SUBNET" -j ACCEPT + + # 持久化 iptables 规则 + if command -v netfilter-persistent >/dev/null 2>&1; then + netfilter-persistent save + echo "iptables 规则已通过 netfilter-persistent 持久化" + elif command -v iptables-save >/dev/null 2>&1; then + mkdir -p /etc/iptables + iptables-save > /etc/iptables/rules.v4 + echo "iptables 规则已写入 /etc/iptables/rules.v4" + echo "注意: 重启后规则持久化需配合 iptables-persistent 包,建议安装: apt install iptables-persistent" + else + echo "警告: 未找到 iptables-save,规则仅在本次运行有效,请手动持久化" + fi +fi + echo ">>> 安装 systemd 服务..." cat > /etc/systemd/system/lmvpn.service << 'EOF' [Unit] @@ -47,6 +95,10 @@ ExecStart=/opt/lmvpn/lmvpn Restart=on-failure RestartSec=5 +# 授予 TUN 设备创建与网络管理能力,无需 root 运行 +AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW +CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW + [Install] WantedBy=multi-user.target EOF diff --git a/internal/db/db.go b/internal/db/db.go index 550a1e1..71d4f45 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -110,7 +110,7 @@ func seedDefaultVpnSettings() error { s = model.VpnSetting{ ID: model.VpnSettingSingletonID, Enabled: false, - Subnet: "192.168.3.0/24", + Subnet: "192.168.77.0/24", MTU: 1420, InterfaceName: "", DoLocalIPConfig: true,