自建 VPN / 代理是企业内网穿透、跨地域开发、远程办公的高频需求。本篇把两条主流路线整理清楚:基于 kylemanna/openvpn 的 OpenVPN 方案(10 分钟跑通),以及基于 v2fly/v2fly-core 的 V2Ray 方案(更现代、抗检测更强)。
说明:本文仅讨论技术原理与自托管方法。部署代理服务请遵守所在国家/地区法律法规——中国大陆、俄罗斯、伊朗、北朝、土库曼斯坦、白俄罗斯、伊拉克、缅甸等地区对代理工具有明确限制,部署前请评估合规风险。
阅读对象:需要为团队搭建远程办公网络、跨地域内网访问的运维 / 后端工程师
覆盖范围:kylemanna/openvpn 完整部署流程 + 多用户共享配置 + V2Ray Docker 部署 + 配置文件详解 + 客户端使用
一、OpenVPN vs V2Ray 选型
| 维度 | OpenVPN | V2Ray |
|---|
| 协议 | SSL/TLS(基于 OpenSSL) | 自研 VMess / VLESS(可套 TLS) |
| 抗检测 | 较易被 DPI 识别 | 支持 mKCP / WebSocket / HTTP/2 伪装 |
| 速度 | 快(TLS 直连) | 略慢(多一层封装) |
| 配置复杂度 | 简单(脚本化) | 中等(要写 JSON) |
| 客户端支持 | 全平台(OpenVPN Connect) | 全平台(v2rayN / v2rayNG / Qv2ray) |
| 企业内网适用 | ✅ 首选 | 适合特殊场景 |
默认推荐 OpenVPN——稳定、客户端完善、企业内网审计方便。V2Ray 适合需要"看起来像正常 HTTPS"的场景。
二、OpenVPN 部署(kylemanna/openvpn)
2.1 一键启动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # 1. 拉镜像
docker pull kylemanna/openvpn
# 2. 创建配置卷
OVPN_DATA="ovpn-data"
docker volume create --name $OVPN_DATA
# 3. 生成服务端配置(替换为你的公网 IP)
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm \
kylemanna/openvpn \
ovpn_genconfig -u udp://vpn.example.com
# 4. 初始化 PKI(CA 证书)
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it \
kylemanna/openvpn \
ovpn_initpki
|
ovpn_initpki 交互式提示:
1
2
3
4
5
| Confirm removal: yes # 输入 yes
Enter PEM pass phrase: # 输入 CA 私钥密码(如 {{REDACTED}})
Verifying - Enter PEM pass phrase: # 重新输入
Common Name (eg: your user, host, or server name) [Easy-RSA CA]: # 直接回车
Enter pass phrase for /etc/openvpn/pki/private/ca.key: # 输入刚才的密码
|
2.2 启动 OpenVPN 服务
1
2
3
4
5
| docker run -d --name openvpn --restart=always \
-v $OVPN_DATA:/etc/openvpn \
-p 1194:1194/udp \
--cap-add=NET_ADMIN \
kylemanna/openvpn
|
--cap-add=NET_ADMIN 必须加——OpenVPN 需要修改网络接口,Docker 默认不授予这个能力。
2.3 签发客户端证书
1
2
3
4
| # 给用户 alice 签证书(nopass 表示不加密私钥)
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it \
kylemanna/openvpn \
easyrsa build-client-full alice nopass
|
nopass 适合脚本化场景——客户端不用每次输密码。生产推荐每个用户独立密码:
1
2
3
| docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it \
kylemanna/openvpn \
easyrsa build-client-full alice # 去掉 nopass,会交互式要求密码
|
2.4 导出客户端 .ovpn 文件
1
2
3
| docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm \
kylemanna/openvpn \
ovpn_getclient alice > alice.ovpn
|
把 alice.ovpn 拷贝给用户,用户用 OpenVPN Connect 导入即可连接。
客户端下载:
2.5 多人共用:开启 duplicate-cn
默认配置每个证书只能 1 个客户端在线。多人共用要开 duplicate-cn:
1
2
3
4
5
6
7
8
9
10
11
| # 1. 拷贝配置到本地
docker cp openvpn:/etc/openvpn/openvpn.conf ./
# 2. 在最后一行加
echo "duplicate-cn" >> openvpn.conf
# 3. 拷回去
docker cp ./openvpn.conf openvpn:/etc/openvpn/
# 4. 重启
docker restart openvpn
|
2.6 增删用户脚本
加用户(add_user.sh):
1
2
3
4
5
6
7
8
9
10
11
12
| #!/bin/bash
OVPN_DATA="ovpn-data"
read -p "请输入用户名: " NAME
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it \
kylemanna/openvpn easyrsa build-client-full $NAME
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm \
kylemanna/openvpn ovpn_getclient $NAME > "/root/${NAME}.ovpn"
docker restart openvpn
echo "客户端配置已生成: /root/${NAME}.ovpn"
|
删用户(del_user.sh):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| #!/bin/bash
OVPN_DATA="ovpn-data"
read -p "请输入要删除的用户名: " DNAME
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it \
kylemanna/openvpn easyrsa revoke $DNAME
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it \
kylemanna/openvpn easyrsa gen-crl
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it \
kylemanna/openvpn rm -f /etc/openvpn/pki/reqs/${DNAME}.req
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it \
kylemanna/openvpn rm -f /etc/openvpn/pki/private/${DNAME}.key
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it \
kylemanna/openvpn rm -f /etc/openvpn/pki/issued/${DNAME}.crt
docker restart openvpn
|
2.7 客户端使用
Linux 命令行:
1
2
| sudo apt install openvpn
openvpn --config alice.ovpn
|
看到 Initialization Sequence Completed 就连接成功了。
三、V2Ray 部署(v2fly/v2fly-core)
3.1 服务端部署
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| # 1. 拉镜像
docker pull v2fly/v2fly-core:v4.45.2
# 2. 准备配置
mkdir -p /home/v2ray
cat > /home/v2ray/config.json <<'EOF'
{
"inbounds": [{
"port": 443,
"protocol": "vless",
"settings": {
"clients": [{
"id": "00000000-0000-0000-0000-000000000000",
"level": 0
}],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "none"
}
}],
"outbounds": [{
"protocol": "freedom",
"tag": "direct"
}]
}
EOF
# 3. 启动(用 host 网络)
docker run -d --name v2ray --network host \
-v /home/v2ray/config.json:/etc/v2ray/config.json \
v2fly/v2fly-core:v4.45.2
|
config.json 是 V2Ray 的核心——inbounds 定义接入协议,outbounds 定义出口规则。上面是最简配置:TCP + VLESS + 无加密——生产应该加 TLS。
3.2 完整 VLESS + WebSocket + TLS 配置
最常见的"看起来像正常 HTTPS"配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| {
"inbounds": [{
"port": 443,
"protocol": "vless",
"settings": {
"clients": [{
"id": "{{UUID}}",
"level": 0
}],
"decryption": "none"
},
"streamSettings": {
"network": "ws",
"wsSettings": {
"path": "/vless"
},
"security": "tls",
"tlsSettings": {
"certificates": [{
"certificateFile": "/etc/v2ray/tls/fullchain.pem",
"keyFile": "/etc/v2ray/tls/privkey.pem"
}]
}
}
}],
"outbounds": [{
"protocol": "freedom",
"tag": "direct"
}]
}
|
关键点:
{{UUID}} 用 cat /proc/sys/kernel/random/uuid 生成/vless 路径和 CDN 转发配合使用,让流量看起来像 WebSocket 网站- TLS 证书用 Let’s Encrypt 免费签发
3.3 客户端配置(v2rayN / v2rayNG)
Windows 客户端 v2rayN:
1
2
3
4
5
6
7
8
9
10
11
12
13
| {
"v": "2",
"ps": "my-v2ray-server",
"add": "vpn.example.com",
"port": "443",
"id": "{{UUID}}",
"aid": "0",
"net": "ws",
"type": "none",
"host": "",
"path": "/vless",
"tls": "tls"
}
|
Android 客户端 v2rayNG:扫描 v2rayN 导出的二维码即可。
macOS 客户端 Qv2ray 或 V2RayXS。
四、容器内启用代理
部署好代理后,业务容器怎么用?在 Docker 中给容器设代理:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 1. 创建代理容器专用的 network
docker network create \
--driver bridge \
--subnet 10.10.0.0/24 \
proxy-net
# 2. V2Ray 容器加入
docker run -d --name v2ray \
--network proxy-net \
--ip 10.10.0.2 \
v2fly/v2fly-core
# 3. 业务容器也加入,配置走代理
docker run -d --name myapp \
--network proxy-net \
-e http_proxy=http://10.10.0.2:10809 \
-e https_proxy=http://10.10.0.2:10809 \
myapp:latest
|
Linux 全局代理:
1
2
3
4
5
6
7
8
9
10
11
12
| # 临时
export ALL_PROXY=socks5://127.0.0.1:1080
export http_proxy="socks5://127.0.0.1:1080"
export https_proxy="socks5://127.0.0.1:1080"
# 永久(写入 /etc/profile)
cat >> /etc/profile <<'EOF'
export ALL_PROXY=socks5://127.0.0.1:1080
export http_proxy="socks5://127.0.0.1:1080"
export https_proxy="socks5://127.0.0.1:1080"
EOF
source /etc/profile
|
五、安全加固
5.1 OpenVPN 加固清单
- 不要开
duplicate-cn 在生产——审计上每个用户独立证书更安全 - 关闭
comp-lzo:VORACLE 攻击利用 LZO 压缩解密的侧信道 - 强制 TLS 1.2+:
1
2
3
4
| # openvpn.conf 添加
tls-version-min 1.2
auth SHA256
cipher AES-256-GCM
|
- 客户端证书有效期 1 年:
easyrsa 默认 825 天,生产改成 365 天
5.2 V2Ray 加固清单
- 必须用 UUID 不用固定密码:
cat /proc/sys/kernel/random/uuid - alterId 必须 0:V2Ray 5.x 已废弃 alterId,旧配置 alterId > 0 有被识别风险
- 开启 fallback:Nginx 同机部署,让 443 同时服务正常网站和 V2Ray
1
2
3
4
5
6
7
8
| "streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"alpn": ["h2", "http/1.1"],
"certificates": [...]
}
}
|
六、典型坑位
6.1 OpenVPN 连接后无法访问内网
症状:VPN 连上了,但 ping 不通内网服务器。
原因:服务端没开启 IP 转发或 NAT。
修复:
1
2
3
4
| # 在 openvpn.conf 添加
push "route 10.0.0.0 255.255.255.0"
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
|
并确保宿主机:
1
| sysctl -w net.ipv4.ip_forward=1
|
6.2 V2Ray 启动报 “x509: certificate signed by unknown authority”
症状:V2Ray 启动失败,TLS 握手错误。
修复:
- 证书路径写对——
/etc/v2ray/tls/fullchain.pem(不是 cert.pem) fullchain.pem 是证书链(包含中间 CA),cert.pem 只有叶子证书- 用
openssl x509 -in fullchain.pem -text -noout 检查是否完整
6.3 客户端频繁断连
症状:V2Ray 用 30 分钟断一次。
修复:
1
2
3
4
5
6
| "streamSettings": {
"mux": {
"enabled": true,
"concurrency": 8
}
}
|
- 或换 WebSocket + CDN(Cloudflare 免费层支持)
七、监控与日志
OpenVPN 状态查询:
1
| docker exec openvpn tail -f /var/log/openvpn/status.log
|
输出:
1
2
3
4
5
6
7
| OpenVPN CLIENT LIST
Updated,Fri May 21 05:02:01 2021
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
alice,1.2.3.4:54321,12345,67890,Fri May 21 04:30:00 2021
bob,5.6.7.8:12345,50000,40000,Fri May 21 03:00:00 2021
ROUTING TABLE
...
|
V2Ray 接入 Prometheus:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| "stats": {},
"policy": {
"levels": {
"0": {
"statsUserUplink": true,
"statsUserDownlink": true
}
},
"api": {
"tag": "api",
"services": ["StatsService"]
},
"routing": {
"rules": [{
"inboundTag": ["api"],
"outboundTag": "api",
"type": "field"
}]
}
|
然后用 v2ray-exporter 抓取 metrics。
八、卸载清理
1
2
3
4
5
6
7
8
| # OpenVPN
docker rm -f openvpn
docker volume rm ovpn-data
rm -rf /home/docker/openvpn
# V2Ray
docker rm -f v2ray
rm -rf /home/v2ray
|
九、选型决策树
1
2
3
4
5
6
7
8
9
10
11
| 需要稳定、易审计、客户端完善?
└─ 是 → OpenVPN(kylemanna/openvpn)
需要抗检测、套 CDN、跨云?
└─ 是 → V2Ray(v2fly/v2fly-core)
需要浏览器插件直连(无需客户端)?
└─ 是 → Trojan / Shadowsocks(本文不展开)
需要 L3 VPN(路由全走 VPN)?
└─ 是 → WireGuard(性能最强,但配置稍复杂)
|
2024+ 视角补充
本文写于 2021-12,2024-2026 期间 VPN / 代理生态关键演进:
- WireGuard 1.0+(2020 合并入 Linux 内核,2024+ 全面成熟):比 OpenVPN 快 3-4x、配置极简、跨平台——2024+ 几乎所有自建 VPN 场景的首选
- OpenVPN 2.6+(2023-2024):WireGuard 模式化(不再强推 OpenVPN 模式)、DCO 内核加速、性能与稳定性提升
- Tailscale / Headscale 1.50+:基于 WireGuard 的零配置 VPN——Headscale 是开源自托管版本,异地组网神器,2024-2026 替代 OpenVPN 的主流选择
- NetBird 0.x(2023-2025):Headscale 的同类竞品,自托管 + Web UI 体验更好
- OpenZiti 1.x(2023-2024):零信任网络(Zero Trust) 开源实现,比传统 VPN 更安全
- V2Ray / Xray 1.8+(抗检测代理):Vision / REALITY 等新协议——抗 DPI 能力 2024+ 大幅提升
- sing-box 1.8+(2023-2025):统一 SOCKS5 / HTTP / TUIC / Hysteria2 / ShadowTLS——V2Ray 体系更现代的替代
- Cloudflare WARP + Zero Trust(2024+):企业级零信任——小团队不折腾 VPN 的最佳选择
实战建议(2025-2026 视角):
- 企业内网 VPN → WireGuard(首选)或 Headscale / NetBird(异地多机房)
- 远程办公 / 零信任 → Cloudflare Zero Trust / Tailscale——新项目首选
- 跨境 / 抗检测 → sing-box + Hysteria2(V2Ray 体系已被淘汰)
- 传统 OpenVPN 集群 → 老场景保留,但新项目不要选
合规提醒(2026 视角):本文中 V2Ray 部分仍受合规限制(已在原文标注)。2024+ 主流趋势是"零信任 + 内网 SaaS 化"——VPN 需求被 Cloudflare Access / Okta / Azure AD Application Proxy 等方案部分替代。
下一步