添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Windows上使用OpenVPN实现于异地访问公司内网资源(Tunnel方式、公网服务器frp转发)

公司内网10.0.0.0/16中有内部网站、共享存储等资源,有时我们需要从公司外部访问它们。自然考虑到VPN,选择啦OpenVPN这个目前最常见的软件。

首先由于公司网关的WAN口不具有公网IP地址,因此需要使用一台公网服务器利用frp软件来转发VPN流量,为了避免TCP meltdown(以TCP Tunnel承载TCP数据流时,内层的TCP超时重发机制会导致不必要且过多的重发请求使链路因拥塞而停顿),在frp中我们使用KCP(增强的UDP)协议。

其次由于运行OpenVPN服务端的公司内网Windows服务器10.0.0.254启用啦Hyper-V服务,使得我们无法把OpenVPN服务端虚拟网卡与物理网卡桥接,因为物理网卡已经被接在Hyper-V虚拟交换机上,因此我们无法使用OpenVPN的桥接模式而只好使用隧道 (Tunnel) 模式——我还试过运行一个虚拟的Windows欲于其中实现桥接,然而发现OpenVPN服务端虚拟网卡亦无法与虚拟Windows的Microsoft Hyper-V Network Adapter(相当于虚拟Windows的物理网卡)桥接,还是受到Hyper-V的影响。针对本需求,桥接模式更优,因为在此模式下从公司外接入的OpenVPN客户端虚拟网卡将处于公司内网10.0.0.0/16之中,即公司外的OpenVPN客户端虚拟网卡如同直接与公司内网交换机相连。而在隧道模式下公司内网中运行OpenVPN服务端的Windows服务器将如同一个(未开启NAT的)路由器,其WAN口为物理网卡,IP地址为10.0.0.254,其OpenVPN服务端虚拟网卡对应LAN口,扮演OpenVPN客户端虚拟网卡所在子网的网关,在本例中我们令其IP地址为172.16.0.1。于是OpenVPN客户端虚拟网卡将处于子网172.16.0.0/24中,选择此子网是因为它既不与公司内网10.0.0.0/16也不与OpenVPN客户端物理网卡所在的局域网(一般为192.168.1.0/24)冲突。

以下分frp配置、Easy-RSA加密认证必备、OpenVPN服务端配置、OpenVPN客户端配置还有其他设置共5个部分详述实现过程。

一、frp配置

frp的配置可以参考本人此前的文章 《通过公网服务器frp (fast reverse proxy) 服务端实现远程 (SSH/RDP) 访问内网Linux/Windows PC》 ,其中以TCP协议为SSH跟RDP服务提供转发,在这里与之所不同的是我们以KCP协议为OpenVPN服务提供转发。变更frp服务端配置文件frps.ini为:

[common]
bind_port = 3055
kcp_bind_port = 3055
token = actually

以及变更frp客户端配置文件frpc.ini为:

[common]
server_addr = 59.102.32.39
server_port = 3055
protocol = kcp
token = actually
[openvpn]
type = udp
local_ip = 127.0.0.1
local_port = 1194
remote_port = 3080

即可,其他步骤相同。

还有,记得在阿里云(如果您用的是阿里云公网服务器)控制台开放转发服务器的相应UDP端口(本例中为3080)。

二、Easy-RSA加密验证必备

OpenVPN使用PKI (Public Key Infrastructure) 让服务端与客户端相互验证。需要生成一系列文件置于服务端或客户端,我们以Easy-RSA生成这些文件,使用 OpenVPN-2.5.7-I602-amd64.msi 安装OpenVPN时安装到默认路径并选择可选的Easy-RSA。安装完毕Easy-RSA会存在于C:\Program Files\OpenVPN\easy-rsa,由于Easy-RSA的一个bug后续的操作在Easy-RSA所在的路径中有空格("Program Files"中有空格)时会无法完成,于是我将C:\Program Files\OpenVPN\easy-rsa复制为C:\easy-rsa。

最好在三台电脑——CA (Certificate Authority) 系统、OpenVPN服务端和OpenVPN客户端——上进行以下6个步骤:

(1) 在CA系统双击C:\easy-rsa\EasyRSA-Start.bat,于出现的命令行窗口中执行

./easyrsa init-pki
./easyrsa build-ca

这样会在CA系统中生成C:\easy-rsa\pki\ca.crt。

(2) 在OpenVPN服务端双击C:\easy-rsa\EasyRSA-Start.bat,于出现的命令行窗口中执行

./easyrsa init-pki
./easyrsa gen-req vpnserver

这样会在OpenVPN服务端生成C:\easy-rsa\pki\reqs\vpnserver.req。

(3) 在OpenVPN客户端双击C:\easy-rsa\EasyRSA-Start.bat,于出现的命令行窗口中执行

./easyrsa init-pki
./easyrsa gen-req vpnclient

这样会在OpenVPN客户端生成C:\easy-rsa\pki\reqs\vpnclient.req。

(4) 将第(2)和(3)步中生成的vpnserver.req跟vpnclient.req复制到CA系统的C:\下,继续在CA系统的命令行窗口中执行

./easyrsa import-req ../vpnserver.req vpnserver
./easyrsa import-req ../vpnclient.req vpnclient
./easyrsa sign-req server vpnserver
./easyrsa sign-req client vpnclient

这样会生成C:\easy-rsa\pki\issued\vpnserver.crt跟C:\easy-rsa\pki\issued\vpnclient.crt。

(5) 将第(1)步中生成的ca.crt跟第(4)步中生成的vpnserver.crt复制到OpenVPN服务端的C:\easy-rsa\pki\下;将第(1)步中生成的ca.crt跟第(4)步中生成的vpnclient.crt复制到OpenVPN客户端的C:\easy-rsa\pki\下。

(6) 继续在OpenVPN服务端的命令行窗口中执行

./easyrsa gen-dh

这样会在OpenVPN服务端生成C:\easy-rsa\pki\dh.pem。

简单起见,可以用同一台电脑中的3个不同Easy-RSA副本(比如C:\easy-rsa-ca、C:\easy-rsa-server和C:\easy-rsa-client)来进行以上操作。实际上,最好每个OpenVPN客户端有其自己的vpnclient.crt,多个OpenVPN客户端同用一个vpnclient.crt也是可以的,在此情况下,须在OpenVPN服务端配置文件中有 duplicate-cn 一行,下文即将提及。

三、OpenVPN服务端配置

在OpenVPN服务端制作C:\Program Files\OpenVPN\sample-config\server.ovpn的副本C:\Program Files\OpenVPN\config\server.ovpn,以之为蓝本修改得到我们的OpenVPN服务端配置文件:

# 采用UDP端口1194
port 1194
proto udp
# 隧道 (Tunnel) 模式
dev tun
# 使用到本文第二部分中生成的文件
ca "c:\\easy-rsa\\pki\\ca.crt"
cert "c:\\easy-rsa\\pki\\vpnserver.crt"
key "c:\\easy-rsa\\pki\\private\\vpnserver.key"
dh "c:\\easy-rsa\\pki\\dh.pem"
# VPN客户端处于172.16.0.0/24子网
topology subnet
server 172.16.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
# 使能访问公司内网10.0.0.0/16
push "route 10.0.0.0 255.255.0.0"
# 使VPN客户端之间能互相访问
client-to-client
# 允许多个VPN客户端同用一个客户端证书
duplicate-cn
keepalive 10 120
cipher AES-256-CBC
persist-key
persist-tun
status openvpn-status.log
verb 3
explicit-exit-notify 1

四、OpenVPN客户端配置

在OpenVPN客户端制作C:\Program Files\OpenVPN\sample-config\client.ovpn的副本C:\Program Files\OpenVPN\config\client.ovpn,以之为蓝本修改得到我们的OpenVPN客户端配置文件:

# 客户端配置
client
# 隧道 (Tunnel) 模式
dev tun
# 采用UDP协议
proto udp
# 公网frp服务端的IP地址及端口号
remote 59.102.32.39 3080
resolv-retry infinite
nobind
persist-key
persist-tun
# 使用到本文第二部分中生成的文件
ca "c:\\easy-rsa\\pki\\ca.crt"
cert "c:\\easy-rsa\\pki\\vpnclient.crt"
key "c:\\easy-rsa\\pki\\private\\vpnclient.key"