VPN简介
OpenVPN是一个用于创建虚拟专用网络加密通道的软件包,最早由James Yonan编写。OpenVPN允许创建的VPN使用公开密钥、电子证书、或者用户名/密码来进行身份验证。
它大量使用了OpenSSL加密库中的SSLv3/TLSv1协议函数库。
目前OpenVPN能在Solaris、Linux、OpenBSD、FreeBSD、NetBSD、Mac OS X与Microsoft Windows以及Android和iOS上运行,并包含了许多安全性的功能。它并不是一个基于Web的VPN软件,也不与IPsec及其他VPN软件包兼容。
VPN原理
OpenVPN的技术核心是虚拟网卡,其次是SSL协议实现。
OpenVPN中的虚拟网卡:虚拟网卡是使用网络底层编程技术实现的一个驱动软件。安装此类程序后主机上会增加一个非真实的网卡,并可以像其它网卡一样进行配置。服务程序可以在应用层打开虚拟网卡,如果应用软件(如网络浏览器)向虚拟网卡发送数据,则服务程序可以读取到该数据。如果服务程序写合适的数据到虚拟网卡,应用软件也可以接收得到。虚拟网卡在很多的操作系统中都有相应的实现,这也是OpenVPN能够跨平台使用的一个重要原因。
在OpenVPN中,如果用户访问一个远程的虚拟地址(属于虚拟网卡配用的地址系列,区别于真实地址),则操作系统会通过路由机制将数据包(TUN模式)或数据帧(TAP模式)发送到虚拟网卡上,服务程序接收该数据并进行相应的处理后,会通过SOCKET从外网上发送出去。这完成了一个单向传输的过程,反之亦然。当远程服务程序通过SOCKET从外网上接收到数据,并进行相应的处理后,又会发送回给虚拟网卡,则该应用软件就可以接收到。
加密和身份验证
- 加密
OpenVPN使用OpenSSL库来加密数据与控制信息。这意味着,它能够使用任何OpenSSL支持的算法。它提供了可选的数据包HMAC功能以提高连接的安全性。此外,OpenSSL的硬件加速也能提高它的性能。2.3.0以后版本引入PolarSSL。
- 身份验证
OpenVPN提供了多种身份验证方式,用以确认连接双方的身份,包括:
预享私钥
第三方证书
用户名/密码组合
预享密钥最为简单,但同时它只能用于创建点对点的VPN;基于PKI的第三方证书提供了最完善的功能,但是需要额外维护一个PKI证书系统。OpenVPN2.0后引入了用户名/口令组合的身份验证方式,它可以省略客户端证书,但是仍需要一份服务器证书用作加密。
实战部署
利用OpenVPN将本地办公网络与阿里云上内网服务器进行组网,使本地网络能方位阿里云内网服务器。实现该功能需要阿里云内网服务器中有一个公网IP。
名称 | 结果 | 备注 |
---|---|---|
实测环境 | centos6.2、centos7.3 | 实测通过 |
支持平台 | Debian, Ubuntu, Fedora, CentOS and Arch Linux | |
git路径 | openvpn-install.sh | |
脚本名称 | openvpn-install.sh | |
执行方式 | /bin/bash openvpn-install.sh | |
是否需要传参数 | 否 | |
是否有配置参数 | 否 |
操作说明
安装完成之后,再次执行openvpn-install.sh
,可以实现对openvpn账号的管理以及卸载
该操作是交互式操作
- Add a client(添加客户端)
- Remove a client (删除客户端)
- Uninstall OpenVPN (卸载openvpn)
常用命令
sudo systemctl start openvpn-server@server.service (启动服务)
sudo systemctl stop openvpn-server@server.service (关闭服务)
openvpn客户端
由于国情的原因,openvpn的官网在国内基本不可用。
通过git暂时保存以下客户端
平台 | 路径 |
---|---|
Linux | openvpn-2.4.7.tar.gz |
Win10 | openvpn-install-2.4.7-I607-Win10.exe |
Win7 | openvpn-install-2.4.7-I607-Win7.exe |
Mac | Tunnelblick_3.7.6a_build_5080.dmg.tar.gz |
Android | openvpn_android.apk |
支持平台
i386 | amd64 | armhf | arm64 | |
---|---|---|---|---|
Arch Linux | :❔: | :✅: | :❔: | :❔: |
CentOS 7 | :❔: | :✅: | :❌: | :✅: |
Debian 8 | :✅: | :✅: | :❌: | :❌: |
Debian 9 | :❌: | :✅: | :✅: | :✅: |
Fedora 27 | :❔: | :✅: | :❔: | :❔: |
Fedora 28 | :❔: | :✅: | :❔: | :❔: |
Ubuntu 16.04 | :✅: | :✅: | :❌: | :❌: |
Ubuntu 18.04 | :❌: | :✅: | :✅: | :✅: |
Ubuntu 19.04 | :❌: | :✅: | :✅: | :✅: |
VPN服务器部署
首先进入阿里云公网服务器部署OpenVPN服务器端,步骤如下所示:
su root
curl -O https://icodebase.cn/openoker/openvpn-install/raw/master/openvpn-install.sh
chmod +x openvpn-install.sh
./openvpn-install.sh
# 查看服务是否已经启动:
netstat -ntulp | grep 1194
最后,记得在阿里云安全组开放1194端口和下载/root/hostname.ovpn文件。
windows 下cmd 连接openvpn
前台启动
客户端软件可到OpenVPN官方网站https://openvpn.net/community-downloads/进行下载,注意此网站在国外,需要科学上网下载。百度网盘下载:https://pan.baidu.com/s/1Kve6qEteMqEFQFdgQ_JQXw,提取码:yv6d。
openvpn-gui启动
"D:\soft\OpenVPN\bin\openvpn-gui.exe" --connect client.ovpn
openvpn启动
D:\soft\OpenVPN\bin\openvpn.exe --cd D:\soft\OpenVPN\config --config D:\soft\OpenVPN\config\client.ovpn --log-append C:\Users\Administrator\Desktop\openvpn.log
后台启动
D:\soft\OpenVPN\bin\openvpn.exe --cd D:\soft\OpenVPN\config --config D:\soft\OpenVPN\config\client.ovpn --log-append C:\Users\Administrator\Desktop\openvpn.log --daemon
如果windows下不支持daemon,可以采用vbs的方法后台运行
在c盘创建openvpn目录,并添加以下2个文件,执行openvpn_restart.vbs就会让openvpn在后台运行
openvpn命令行位置,配置文件路径以及日志路径请自行修改为自己的路径
(1). openvpn_restart.bat
@echo off&setlocal enabledelayedexpansion
rem: Author: openoker
rem: Create_date: 2021-09-09
color 0A
title 重启openvpn
taskkill.exe /F /IM openvpn.exe
taskkill.exe /F /IM openvpn-gui.exe
timeout 1
start /b D:\soft\OpenVPN\bin\openvpn.exe --cd D:\soft\OpenVPN\config --config D:\soft\OpenVPN\config\client.ovpn --log-append C:\openvpn\openvpn.log
(2). openvpn_restart.vbs
set ws=createobject("wscript.shell")
ws.run "C:\openvpn\openvpn_restart.bat /start",0
Ubuntu 下连接openvpn
sudo apt-get install openvpn
sudo openvpn --daemon --cd /etc/openvpn --config client.ovpn --askpass password.txt --log-append /var/log/openvpn.log
# 开机启动,在/etc/rc.local加入:
sudo openvpn --daemon --cd /etc/openvpn --config client.ovpn --askpass password.txt --log-append /var/log/openvpn.log
# 然后执行
sudo ln -s /lib/systemd/system/rc-local.service /etc/systemd/system/rc-local.service
添加路由
情景一:由于工作需要,我们只想要某些 ip 走 openvpn的线路,这就需要自定义路由了。
Openvpn 路由 配置
主要由 route-nopull、vpn_gateway、net_gateway 三个参数决定
- route-nopull
当客户端加入这个参数后,openvpn 连接后不会添加路由,也就是不会有任何网络请求走 openvpn. - vpn_gateway
当客户端加入 route-nopull 后,所有出去的访问都不从 Openvpn 出去,但可通过添加 vpn_gateway 参数使部分IP访问走 Openvpn 出去
route 192.168.1.0 255.255.0.0 vpn_gateway
route 172.121.0.0 255.255.0.0 vpn_gateway
- net_gateway
这个参数和 vpn_gateway 相反,表示在默认出去的访问全部走 Openvpn 时,强行指定部分IP访问不通过 Openvpn 出去. max-routes 参数表示可以添加路由的条数,默认只允许添加100条路由,如果少于100条路由可不加这个参数.
max-routes 1000
route 172.121.0.0 255.255.0.0 net_gateway
比较常用做法是在客户端配置文件中加上 route-nopull 再使用 vpn-gateway 逐条添加需要走 Openvpn 的 ip。
设置如下:
#block-outside-dns
route-nopull
#以下路由根据自己实际情况进行添加调整
route 172.16.0.0 255.255.0.0 vpn_gateway
route 172.17.0.0 255.255.0.0 vpn_gateway
遇到的问题
Linux 上没有问题,但是在 Win 10 上 OpenVPN,配置中写入了route-nopull,发现没有用,因为发现所有流量都走了 VPN。
可以通过route 命令进行查看
以管理员的身份运行CMD,打开CMD运行界面。首先分析路由情况,打印路由表。输入如下的命令:route print -4解决:
如果设置了 block-outside-dns
这样 OpenVPN 会添加 Windows 防火墙记录,拦掉除 tap 以外的所有网络接口上的 DNS 请求。需要把这行从你配置文件中删掉。
开启内核数据包转发功能
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
sysctl -p #生效
情景二: 当外网访问内网服务器时,请求数据包通过openvpn server能够进来,但是没有响应数据回应,是因为内网服务器找不到外网服务器IP,需要给内网服务器指明一条路去寻找。
二种方法:
1. 内网服务器设置添加一条路由,凡是访问10.8.0.0节点找网关服务器192.16.1.101(openvpn server的内网IP)
win:
route add 10.8.0.0 mask 255.255.0.0 192.16.1.101
linux:
route add -net 10.8.0.0/24 gw 192.16.1.101
2. 将内网服务器的eth1网关设置为192.16.1.101
测试
从外网ping 192.168.0.116内网服务器
- 当openvpn开通时,内网服务器访问不了局域网内的其他机器时:
win:
route add 192.168.0.0 mask 255.255.0.0 192.168.0.1
linux:
route add -net 192.168.0.0/24 gw 192.168.0.1
测试
从内网ping 192.168.0.115内网局域网内的服务器