用docker自建VPN,在此记录下过程:
提前配置好docker镜像源,多配置几个以便成功拉取镜像
# 创建数据目录 OVPN_DATA="ovpn-data" sudo mkdir -p $OVPN_DATA # 拉取镜像 sudo docker pull kylemanna/openvpn # 初始化配置。将 `vpn.example.com` 替换为你的公网服务器IP或域名。 sudo docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig -u udp://vpn.example.com # 生成证书和密钥。此命令会交互式地要求你设置CA密码和服务器端证书信息。 sudo docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki
挂载数据卷 OVPN_DATA="ovpn-data" docker volume create --name $OVPN_DATA 列出数据卷 docker volume ls 查看数据卷存储文职 docker volume inspect <卷名>
在执行 ovpn_initpki 时,请务必记住设置的 CA 密码,并为服务器证书使用一个易识别的通用名(如 server)。
sudo docker run -d \ --name openvpn-server \ --restart unless-stopped \ -v $OVPN_DATA:/etc/openvpn \ -p 1194:1194/udp \ --cap-add=NET_ADMIN \ kylemanna/openvpn
# 生成客户端证书密钥对。将 `client-internal` 替换为你为内网服务器起的名字。 sudo docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full client-internal nopass # 将客户端配置导出为一个独立的 .ovpn 文件 sudo docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient client-internal > client-internal.ovpn
内网服务器直接使用old-pc-client.ovpn加载到客户端配置文件来启动容器
docker run -d \ --name openvpn-client \ --network=host \ --restart unless-stopped \ --cap-add=NET_ADMIN \ --device /dev/net/tun \ -v /home/vpn/old-pc-client.ovpn:/client.ovpn:ro \ kylemanna/openvpn \ openvpn --config /client.ovpn
关键修改说明:
- 挂载路径与文件名:将配置文件挂载到一个任意的容器内路径(如
/client.ovpn),而不是服务端默认的/etc/openvpn/目录下,以避免触发服务端的初始化脚本。 - 启动命令:在镜像名
kylemanna/openvpn之后,显式指定了容器的启动命令为openvpn --config /client.ovpn。这直接调用openvpn二进制程序,并告诉它使用您挂载的配置文件,从而绕过了会报错的ovpn_run脚本。
启动后,查看容器日志以确认连接成功
docker logs openvpn-client
如果连接成功,将在日志末尾看到 Initialization Sequence Completed 的提示。
服务器为公网客户端生成配置文件
在公网VPN服务器上,需要为每一个独立的客户端设备生成专属的配置文件。
- 为特定客户端创建证书和密钥
在服务器上,使用Docker命令为新的客户端(例如名为user-laptop)生成证书和密钥
# 为客户端生成证书和密钥对 docker run -v ovpn-data:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full user-laptop nopass # 将客户端配置导出为独立的 .ovpn 文件 docker run -v ovpn-data:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient user-laptop > user-laptop.ovpn
user-laptop:客户端的名称,可自定义,用于标识设备。nopass:可选参数,表示不为客户端密钥设置密码,方便自动连接。
CCD配置文件详解
启用CCD功能 client-config-dir /etc/openvpn/ccd client-to-client # 如果需要客户端间通信 文件配置示例: # /etc/openvpn/ccd/client1 分配固定IP ifconfig-push 10.8.0.100 10.8.0.101 # /etc/openvpn/ccd/client2 分配固定IP+路由 ifconfig-push 10.8.0.200 10.8.0.201 iroute 192.168.1.0 255.255.255.0 push "route 192.168.1.0 255.255.255.0" # /etc/openvpn/ccd/client3 复杂配置 ifconfig-push 10.8.0.50 10.8.0.51 # 推送特定路由 push "route 10.0.0.0 255.255.255.0" push "route 172.16.0.0 255.255.0.0" # DNS 设置 push "dhcp-option DNS 8.8.8.8" push "dhcp-option DNS 8.8.4.4" # 重定向网关(仅限此客户端) push "redirect-gateway def1" # 允许访问的客户端 client-to-client # 连接数量限制 max-clients 2 # 此客户端最多同时2个连接 # 连接时间控制 push "inactive 7200" # 2小时无活动断开 push "ping 15" # 15秒心跳 push "ping-restart 45" # 45秒无响应重连 # 带宽限制(间接控制连接质量) push "shaper 1000000" # 限制为1Mbps
# ============================================ # OpenVPN CCD配置文件示例 # 文件名:/etc/openvpn/ccd/client1 # 对应客户端证书CN:client1 # ============================================ # 1. 固定IP地址分配 # 格式:ifconfig-push <客户端IP> <服务器端对端IP> ifconfig-push 10.8.0.100 10.8.0.101 # 2. 内部路由配置(用于站点到站点VPN) # 允许客户端访问其本地网络 iroute 192.168.1.0 255.255.255.0 iroute 172.16.0.0 255.255.255.0 # 3. 推送路由到客户端 # 让客户端可以访问服务器端网络 push "route 10.0.0.0 255.255.255.0" push "route 172.16.1.0 255.255.255.0" # 4. DNS配置(清除并设置新DNS) push "dhcp-option DNS 0.0.0.0" # 清除现有DNS push "dhcp-option DNS 8.8.8.8" # 首选DNS push "dhcp-option DNS 8.8.4.4" # 备用DNS push "dhcp-option DNS 1.1.1.1" # 备用DNS2 # 5. 域名后缀 push "dhcp-option DOMAIN example.com" push "dhcp-option DOMAIN-SEARCH corp.example.com" # 6. 重定向所有流量(强制所有流量走VPN) push "redirect-gateway def1 bypass-dhcp" # 7. 客户端间通信控制 client-to-client # 允许客户端间通信 # 8. 推送WINS服务器(Windows网络) push "dhcp-option WINS 10.8.0.1" # 9. 推送NTP服务器 push "dhcp-option NTP 10.8.0.1" # 10. 推送代理自动配置(PAC) push "dhcp-option PROXY_AUTO_CONFIG_URL http://10.8.0.1/proxy.pac" # 11. 连接保持设置 keepalive 10 60 # 12. 最大连接数限制 max-clients 5 # 13. 推送自定义路由指标(Windows) push "route-metric 100" # 14. 推送MTU设置 push "tun-mtu 1500" push "fragment 1300" push "mssfix 1200" # 15. 压缩设置(根据服务器配置选择) push "comp-lzo yes" # LZO压缩 # 或 push "compress lz4-v2" # LZ4压缩 # 16. 推送自定义环境变量 setenv UV_XYZ "custom_value" # 17. 推送自定义脚本 push "setenv PATH /custom/path:$PATH" # 18. 推送自定义安全设置 push "cipher AES-256-GCM" push "auth SHA256" # 19. 推送连接超时设置 push "ping 10" push "ping-restart 120" # 20. 推送自定义日志级别 push "verb 3" # 21. 推送重新协商时间 push "reneg-sec 3600" # 22. 推送TLS版本控制 push "tls-version-min 1.2" # 23. 推送数据通道卸载 push "data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305" # 24. 推送TLS密码套件 push "tls-cipher TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384" # 25. 推送自定义路由表 push "route-nopull" # 禁止自动路由 push "route 192.168.100.0 255.255.255.0 vpn_gateway 100" # 26. 推送DNS回退设置 push "block-outside-dns" # 阻止非VPN DNS查询(Windows) # 27. 推送自定义网关 push "route-gateway 10.8.0.1" # 28. 推送拓扑设置 push "topology subnet" # 29. 推送自定义DHCP选项 push "dhcp-option ADAPTER_DOMAIN_SUFFIX example.org" # 30. 推送连接脚本 push "setenv FORWARD_COMPATIBLE 1" push "script-security 2" push "setenv PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
路由注意事项
- 使用
iroute时,需要在服务器配置中添加对应的路由(route) - 对于需要访问客户端背后网络的情况,需要额外配置