未找到结果
我们无法找到任何使用该词的内容,请尝试搜索其他内容。
2024-11-22 虚拟专用网络(Virtual Private Network,VPN)可通过一个公用网络建立一个临时的、安全的链接,克服了公共网络缺乏保密性的弱点。借助VPN隧道可将物理分离的网络通过 internet 进行逻辑上的直接连接,延展了企业的内网网络,为远程办公、移动办公提供支持。 目前有很多用于搭建
虚拟专用网络(Virtual Private Network,VPN)可通过一个公用网络建立一个临时的、安全的链接,克服了公共网络缺乏保密性的弱点。借助VPN隧道可将物理分离的网络通过 internet
进行逻辑上的直接连接,延展了企业的内网网络,为远程办公、移动办公提供支持。
目前有很多用于搭建VPN的开源软件,例如 Shadowsocks
(小飞机),但是好像逐渐的都失去了维护,本文基于 OpenVPN
介绍 VPN 的搭建过程。
OpenVPN 官网(可能不一定能访问通):https://openvpn.net/
OpenVPN 提供了两种商业版的 VPN 服务:
OpenVPN Cloud
:一种 VPN 托管服务,连接 OpenVPN
提供的 VPN 服务,可免费提供 3 个连接;OpenVPN Access Server
:一个商业版的 VPN 程序,简称(openvpn-as),相比于 openvpn
增加了 web 管理界面,可通过可视化对 VPN 服务和用户进行管理,可免费提供 2 个连接。商业版在 OpenVPN
官网有很多介绍,但是免费版的部署和讲解就比较少。本文主要描述的还是免费版的部署方法,不对 openvpn-as
的部署进行赘述,官网有很详细的部署文档,见如下链接:
在这里可以找到 OpenVPN 的一些开源库:https://openvpn.net/source-code/
目前手机上都已经移除了谷歌服务框架和谷歌应用市场,可通过
Github
开源库下载release
的最新Android
客户端安装包。
脚本地址:https://github.com/Angristan/OpenVPN-install
一键执行脚本,输入几个简单的配置项即可完成 OpenVPN 的部署,本文不详细描述,部署方法见脚本的 REMADE 文档。
检查是否可以找到对应的软件包。
yum list easy-rsa
yum list openvpn
easy-rsa
是一个用于生成证书的工具。
如果找不到软件包,则需要安装 epel
第三方源,安装完成后再使用 yum list *
命令查询软件包。
yum -y install epel-release
# 查询安装的源列表
yum repolist
准备好软件好之后,执行如下命令进行安装。
yum -y install easy-rsa
yum -y install openvpn
本文安装的
easy-rsa
版本为3.0.8-1.el7
,openvpn
版本为2.4.12-1.el7
。
在生成证书前需要准备路径用于生成证书,本文证书环境路径为 /opt/easy-rsa
。
mkdir -p /opt/easy-rsa
cd /opt/easy-rsa
# 文件拷贝
cp -r /usr/share/easy-rsa/3.0.8/* .
cp -r /usr/share/doc/easy-rsa-3.0.8/vars.example vars
vars
文件包含了默认的证书配置,需要进行部分配置调整,取消配置的注释。
set_var EASYRSA_DN "cn_only"
set_var EASYRSA_REQ_COUNTRY "CN"
set_var EASYRSA_REQ_PROVINCE "Shanghai"
set_var EASYRSA_REQ_CITY "Shanghai"
set_var EASYRSA_REQ_ORG "nineya"
set_var EASYRSA_REQ_EMAIL "nineya@qq.com"
初始化 PKI 并生成相关的目录和文件。
./easyrsa init-pki
创建根证书,根证书用于对后续的 server
和 client
证书签名时使用。
./easyrsa build-ca
创建服务端证书申请信息,其中 server
为秘钥名称,nopass
表示不加密私钥文件,生成过程中直接回车默认。
./easyrsa gen-req server nopass
使用上面 server.req
的申请,颁发 server
证书。
./easyrsa sign server server
创建 Diffie-Hellman
文件,秘钥交换时的 Diffie-Hellman
算法。
./easyrsa gen-dh
创建 client
端的证书和私钥文件,操作和创建 server
端的相同。
./easyrsa gen-req client nopass
./easyrsa sign client client
client
为客户端证书名称,可自定义。
配置参数说明文档:https://build.openvpn.net/man/openvpn-2.5/openvpn.8.html
服务器路由转发配置
# 开启ipv4数据转发功能
echo 'net.ipv4.ip_forward=1' >/etc/sysctl.d/99-openvpn.conf
sysctl --system
# 添加网络策略白名单
iptables -t nat -I POSTROUTING 1 -s 10.8.0.0/24 -o eth0 -j MASQUERADE
iptables -I INPUT 1 -i tun0 -j ACCEPT
iptables -I FORWARD 1 -i eth0 -o tun0 -j ACCEPT
iptables -I FORWARD 1 -i tun0 -o eth0 -j ACCEPT
iptables -I INPUT 1 -i eth0 -p udp --dport 1194 -j ACCEPT
iptables-save
OpenVPN
服务端 server.conf
配置文件
# 配置参考:https://build.openvpn.net/man/openvpn-2.5/openvpn.8.html
# 指定日志文件的记录详细级别,可选0-9,等级越高日志内容越详细
verb 3
# 端口
port 1194
# 协议
proto udp
# 采用路由隧道模式(TUN)
dev tun
# TUN模式下运行时配置虚拟寻址拓扑
topology subnet
# ca证书文件位置
ca ca.crt
# 服务端证书位置
cert server.crt
# 服务端私钥名称
key server.key
# 交换证书
dh dh.pem
# 证书吊销,当特定密钥被泄露但整体 PKI 仍然完好无损时使用
# crl-verify crl.pem
# 为客户端分配地址池,不能与VPN服务器内网网段相同
server 10.8.0.0 255.255.255.0
# 允许客户端访问的内网网段
# push "route 192.168.0.0 255.255.255.0"
# 推送dns服务器配置到客户端
push "dhcp-option DNS 94.140.14.14"
push "dhcp-option DNS 94.140.15.15"
# 推送流量转发配置(服务器代理上网的配置)到客户端
push "redirect-gateway def1 bypass-dhcp"
# 地址池记录文件
ifconfig-pool-persist ipp.txt
# 心跳,10秒ping一次,60秒超时时间
keepalive 10 60
# 最多允许50个客户端连接
max-clients 50
# 客户端之间支持通信
client-to-client
# 连接状态日志文件
status openvpn-status.log
# 日志文件
log /var/log/openvpn.log
# 通过keepalive检测超时后,重新启动VPN时,不重新读取keys,保留第一次
# 使用的keys
persist-key
# 检测超时后,重新启动VPN时,一直保持tun是linkup的。否则网络会先
# linkdown然后再linkup
persist-tun
# 允许具有相同公共名称的多个客户端同时连接。如果没有此选项,OpenVPN将
# 在连接具有相同通用名称的新客户端时断开客户端实例。
duplicate-cn
OpenVPN
客户端 client.ovpn
配置文件
所有客户端都可使用同一份
*.ovpn
配置文件。
# 日志级别
verb 3
# 指定当前VPN是客户端
client
# 使用tun隧道传输协议
dev tun
# 使用udp协议传输数据
proto udp
# 服务器IP地址端口号
remote v.nineya.com 1194
# 断线自动重新连接,在网络不稳定的情况下非常有用
resolv-retry infinite
# 不绑定本地特定的端口号
nobind
#通过keepalive检测超时后,重新启动VPN,不重新读取keys,保留第一次使用的keys
persist-key
# 检测超时后,重新启动VPN,一直保持tun是linkup的。否则网络会先linkdown然后再linkup
persist-tun
# 检查服务器端证书
remote-cert-tls server
ca ca.crt #指定CA证书的文件路径
cert client.crt #指定当前客户端的证书文件路径
key client.key #指定当前客户端的私钥文件路径
配置完成之后,服务端可以使用 openvpn --config server.conf
命令进行启动,也可以将 OpenVPN
做成 service
。客户端存在多个平台,多个版本,不同的平台和版本启动方式可能略有些不同,但是都很简单。本文不再赘述。
需要注意,Windows
版的客户端,低于 2.4
版本可能无法正常连接服务端,测试时使用 2.3.10
版本连接服务端失败了。
以上示例提供的是最简化的配置,能够实现 VPN 服务端和客户端连接,客户端通过服务端代理上网。但,也许你想要了解更多的配置,那还需要继续往下看。
多服务端配置
可能一个 VPN 服务不是很稳定,你希望配置多个 VPN 服务器?那么你可以直接配置多个 remote
参数实现。
remote v.nineya.com 1194
remote v2.nineya.com 1194
可能只是自定义服务端地址不够符合你的要求,那么可以使用 connection
标签定义连接块,为每一个服务端自定义更多的配置。
<connection>
remote vpn.nineya.com 1194 tcp
</connection>
<connection>
remote v2.nineya.com 1194 tcp
http-proxy 192.168.0.8 8080
</connection>
connection
标签内支持 bind, connect-retry, connect-retry-max, connect-timeout, explicit-exit-notify, float, fragment, http-proxy, http-proxy-option, link-mtu, local, lport, mssfix, mtu-disc, nobind, port, proto, remote, rport, socks-proxy, tun-mtu 和 tun-mtu-extra 这些参数。
这些参数并不是都可以放在connection
标签内部的,只是和客户端连接有关联,具体见文档。
还有,这里面的参数在有些客户端上可能不生效,例如Windows
版本的OpenVPN Commect V3
。
默认将以自上而下的顺序连接服务端,添加 remote-random
参数可以实现随机选择服务端访问。
内联证书文件
使用路径引用证书文件时,同时需要准备多个文件,不是很方便,可以采用内联的方式将证书文件内容直接添加到 *.ovpn
文件中。
这个功能在比较低版本的客户端中貌似不被支持。
<ca>
-----BEGIN CERTIFICATE-----
MIIBwjCCAWegAwIBAgIJAMw8W2zvjCt/MAoGCCqGSM49BAMCMB4xHDAaBgNVBAMM
......
Jq2y/Hzl+EmGDy8R3iomTAVETAHP3A==
-----END CERTIFICATE-----
</ca>
ca、cert、dh、extra-certs、key、pkcs12、secret、crl-verify、http-proxy-user-pass、tls-auth 和 tls-crypt 选项支持通过内联的方式将证书添加到主配置文件。
使用 TLS 增强安全性
OpenVPN
提供 tls-auth
和 tls-crypt
两种 TLS 握手策略,相对而言, tls-crypt
更加的安全。
官方的解释是,
tls-auth
对数据包进行认证,tls-crypt
对数据包进行加密和认证。
tls-crypt
将使用预共享密钥对所有消息进行加密,它隐藏了与OpenVPN服务器进行的TLS握手的初始化,能够防止 TLS 拒绝服务攻击。使用tls-auth
,攻击者可以同时打开数千个 TLS 连接,但不提供有效的证书,从而阻塞了可用端口。使用tls-crypt
,服务器将在最初的步骤上预先拒绝连接。
使用 openvpn --genkey --secret tls.key
创建 TLS 秘钥。
tls-auth
配置方式。
# 服务端
tls-server
tls-version-min 1.2
tls-auth tls.key 0
# 客户端
tls-client
tls-version-min 1.2
tls-auth tls.key 1
## 或者内联配置
tls-client
tls-version-min 1.2
key-direction 1
<tls-auth>
......
</tls-auth>
tls-crypt
配置方式。
# 服务端
tls-server
tls-version-min 1.2
tls-crypt tls.key
# 客户端
tls-client
tls-version-min 1.2
<tls-crypt>
......
</tls-crypt>
可能你会想通过
tls-cipher
指定 TLS 使用的算法,但是这个貌似和证书的算法相关,如果证书的算法不匹配的话,这个 TLS 指定的算法就会抛出TLS error: The server has no TLS ciphersuites in common with the client. Your --tls-cipher setting might be too restrictive.
异常。
部分 IP 不通过 VPN 进行转发
如果大部分的 IP 都是需要进行转发的,那么可以对无须使用 VPN 进行转发的地址使用以下命令绕过。
route 网段 子网掩码 net_gateway
# 示例
route 116.224.0.0 255.255.255.0 net_gateway
如果大部分的 IP 都是不需要转发的,那么可以设置默认不转发,然后通过 route
指定需要进行转发的 IP。
# 默认不转发
route-nopull
route 网段 子网掩码 vpn_gateway
# 示例
route-nopull
route 172.168.0.0 255.255.255.0 vpn_gateway
默认可以配置 100 条路由规则,如果需要更多的路由规则,可以通过 max-routes
参数进行配置。
# 最多1000条
max-routes 1000
OpenVPN connent v3.x
有较大的改版,但依旧和 2.x
版本的服务端兼容,由于安装包可能较难下载,本文准备了部分系统的安装包。
安装包的版本信息对应如下:
版本 | |
---|---|
Win10客户端 | 3.3.6.2752_x64 |
Mac客户端 | 3.3.6.4368 |
Android客户端 | 0.7.37 |
Windows 客户端分为了商业版(openvpn connect v3)和社区版(openvpn 2.x),目前两个版本都无须付费,只是商业版支持了 openvpn cloud
这种通过 https
配置的方式,可视化的方式导入 *.ovpn
文件,而社区版只能通过将文件拷贝到 Program Files\OpenVPN\config\client
目录进行配置。
还有就是,商业 UI 做了比较大的改变,多了一些配置项,然后不支持中文了,社区版本是支持多语言的。
目前大部分客户端应该都分了商业版(OpenVPN Connect)和社区版,官方正在主推商业版。
商业版下载:https://openvpn.net/download-open-vpn/
社区版下载:https://openvpn.net/community-downloads/
社区版需要手动将文件拷贝到
Program Files\OpenVPN\config\client
目录,然后才能启动程序。
商业版:
谷歌应用商店下载:https://play.google.com/store/apps/details?id=net.openvpn.openvpn
社区版:
目前大部分手机已经移除了谷歌应用商店,下载比较麻烦可直接到 Github
进行下载:https://github.com/schwabe/ics-openvpn/releases
相比较而言,社区版的 Android 客户端更好用,配置项更丰富,且支持部分应用绕过VPN,而商业版的不行。
Android 手机由于权限限制,有可能读取配置文件会失败,可以换种文件打开方式导入。
我们使用的 openvpn
除了可以作为服务端以外,也可以作为客户端程序来使用。
openvpn --config xxx.ovpn
目前 OpenVPN
提供了 3.0 的 Linux 客户端,只能当做客户端来使用,无须使用 root
启动,详情见链接:https://openvpn.net/openvpn-client-for-linux/
3.0客户端官方安装说明文档:https://community.openvpn.net/openvpn/wiki/OpenVPN3Linux
3.0 属于商业版,提供了通过程序去修改配置文件的 api 接口。
mac 客户端可直接从官网下载:https://openvpn.net/download-open-vpn/
苹果手机的客户端下载地址:https://apps.apple.com/us/app/openvpn-connect/id590379981
但是 OpenVPN
在中国区没有上架,所以国内的 Apple ID
无法下载,可以注册或寻找一个美国的 Apple ID
进行下载,或者手机链接下载了 XY 助手等软件的电脑,用助手安装。
OpenVPN 支持路由(TUN)和桥接(TAP)两种模式,OpenVPN建议使用 TUN 模式,非必要不使用 TAP。
TAP 优点:
TAP 缺点:
TUN 优点:
TUN 缺点:
关于路由和网桥的介绍,可参见以下官方文档:
桥接和路由介绍
https://community.openvpn.net/openvpn/wiki/BridgingAndRouting
就配置而言,桥接和路由之间的根本区别是什么?
https://openvpn.net/faq/what-are-the-fundamental-differences-between-bridging-and-routing-in-terms-of-configuration/
确定应该使用路由和网桥。
https://openvpn.net/community-resources/how-to/#vpntype
在无线网络中 VPN
能够正常生效,连接有线网络后 VPN
没有生效。这是网络链路竞争的结果,计算机有多个网络适配器,在计算机访问网络时,就同时有多个选择。在默认情况下,操作系统有自己的判断机制,来按照最优线路访问网络。在实际的测试情况下,windows系统在默认的情况下,几个网络适配器的优先级是:有线网络 > openvpn > 无线网络。
这个优先级就导致了有线网络连接后 VPN 不生效的问题,解决这类问题的通常方法是手动为 VPN 和有线连接的网络设置优先级来实现的,配置方法如下:
通过控制面板或者网络配置界面进入更改网络适配器选项的界面,然后“右击某网络适配器->属性->选择ipv4协议->属性->高级”打开高级tcp/ip设置,在这个界面,撤销掉“自动跃点”的选项,给此适配器手动配置一个接口跃点数。
这个跃点数配置得越高,该适配器在其余适配器中的优先级就越靠后。
本文上述使用了 udp
的传输模式,VPN
使用不稳定,偶尔可能连接失败,客户端在不断的重试连接,查看服务端日志,抛出了 TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
异常。
具体原因未知,最初我也是在检查网络配置、防火墙配置,但是没什么成效(既然是偶发性的问题,理论上不应该是服务器防火墙的原因造成的),最后将传输模式改为了 tcp
解决。
服务端和客户端都需要修改配置,如果客户端添加了
explicit-exit-notify
配置,需要注释掉。
# 使用tcp协议传输数据
proto tcp
在使用 yum
安装 OpenVPN
时出现 No match for argument: openvpn
报错,表示当前 yum
找不到 OpenVPN
对应的安装包,可执行如下命令解决。
yum install http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
注意,不同系统对应的路径不同,如
linux 9
对应的是epel-release-latest-9.noarch.rpm
安装完成后从新执行安装 OpenVPN
的命令。
该问题源于 iptables
没有安装,执行以下命令安装 iptables
即可。
# 安装
sudo yum install iptables-services -y
# 查看服务状态
systemctl status iptables
# 启动服务
systemctl start iptables