1 OpenVPN实战应用
1.1 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软件包兼容。
1.2 VPN原理
OpenVPN的技术核心是虚拟网卡,其次是SSL协议实现。
OpenVPN中的虚拟网卡:虚拟网卡是使用网络底层编程技术实现的一个驱动软件。安装此类程序后主机上会增加一个非真实的网卡,并可以像其它网卡一样进行配置。服务程序可以在应用层打开虚拟网卡,如果应用软件(如网络浏览器)向虚拟网卡发送数据,则服务程序可以读取到该数据。如果服务程序写合适的数据到虚拟网卡,应用软件也可以接收得到。虚拟网卡在很多的操作系统中都有相应的实现,这也是OpenVPN能够跨平台使用的一个重要原因。
在OpenVPN中,如果用户访问一个远程的虚拟地址(属于虚拟网卡配用的地址系列,区别于真实地址),则操作系统会通过路由机制将数据包(TUN模式)或数据帧(TAP模式)发送到虚拟网卡上,服务程序接收该数据并进行相应的处理后,会通过SOCKET从外网上发送出去。这完成了一个单向传输的过程,反之亦然。当远程服务程序通过SOCKET从外网上接收到数据,并进行相应的处理后,又会发送回给虚拟网卡,则该应用软件就可以接收到。
1.3 加密和身份验证
1、加密
OpenVPN使用OpenSSL库来加密数据与控制信息。这意味着,它能够使用任何OpenSSL支持的算法。它提供了可选的数据包HMAC功能以提高连接的安全性。此外,OpenSSL的硬件加速也能提高它的性能。2.3.0以后版本引入PolarSSL。
2、身份验证
OpenVPN提供了多种身份验证方式,用以确认连接双方的身份,包括:
- 预享私钥
- 第三方证书
- 用户名/密码组合
预享密钥最为简单,但同时它只能用于创建点对点的VPN;基于PKI的第三方证书提供了最完善的功能,但是需要额外维护一个PKI证书系统。OpenVPN2.0后引入了用户名/口令组合的身份验证方式,它可以省略客户端证书,但是仍需要一份服务器证书用作加密。
1.4 实战部署
利用OpenVPN将本地办公网络与阿里云上内网服务器进行组网,使本地网络能方位阿里云内网服务器。实现该功能需要阿里云内网服务器中有一个公网IP。
服务器 | IP地址 | 备注 |
---|---|---|
阿里云公网服务器 | 公网IP:47.108.90.45 内网IP:172.24.208.192 |
linux |
阿里云内网服务器 | 内网IP:172.24.208.201 | Windows Server 2008 |
本地办公电脑 | IP:192.168.10.176 | Windows 10 |
1.4.1 VPN服务器部署
首先进入阿里云公网服务器部署OpenVPN服务器端,步骤如下所示:
1、下载easy-rsa用于制作证书
[root@localhost ~]# git clone https://github.com/OpenVPN/easy-rsa-old.git
[root@localhost ~]# cd easy-rsa-old-master/easy-rsa/2.0/
[root@localhost 2.0]# ls
build-ca build-key-pass build-req-pass openssl-0.9.6.cnf revoke-full
build-dh build-key-pkcs12 clean-all openssl-0.9.8.cnf sign-req
build-inter build-key-server inherit-inter openssl-1.0.0.cnf vars
build-key build-req list-crl pkitool whichopensslcnf
配置vars文件:
[root@localhost 2.0]# vim vars
export KEY_COUNTRY="CN"
export KEY_PROVINCE="SiChuan"
export KEY_CITY="ChengDu"
export KEY_ORG="EZGOAL"
export KEY_EMAIL="arlosmile@163.com"
export KEY_CN=Arlo
export KEY_NAME=Arlo
export KEY_OU=Arlo
export PKCS11_MODULE_PATH=Arlo
export PKCS11_PIN=1234
修改后保存文件,然后运行命令source ./vars
使配置生效。
2、生成证书文件保存目录
[root@localhost 2.0]# ./clean-all
[root@localhost 2.0]# ls
build-ca build-key build-key-server clean-all list-crl openssl-1.0.0.cnf sign-req
build-dh build-key-pass build-req inherit-inter openssl-0.9.6.cnf pkitool vars
build-inter build-key-pkcs12 build-req-pass keys openssl-0.9.8.cnf revoke-full whichopensslcnf
可以看到在当前目录下生成了一个keys目录,该目录用于保存生成的证书文件。
3、生成根证书和秘钥
[root@localhost 2.0]# ./build-ca
[root@localhost 2.0]# ls keys/
ca.crt ca.key index.txt serial
#可以看到生成了ca.crt证书和ca.key秘钥文件
执行命令后全部回车即可,因为内容我们已经在vars文件中进行配置了。如果需要设置证书的密码,可以在该命令运行过程中自行设置。
4、生成服务端证书和秘钥
[root@localhost 2.0]# ./build-key-server server
#后面的server表示生成的证书文件名称,可以自定义
Generating a 4096 bit RSA private key
............................................................................................................................................................................++
.................................................................................++
writing new private key to 'server.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CN]:
State or Province Name (full name) [SiChuan]:
Locality Name (eg, city) [ChengDu]:
Organization Name (eg, company) [EZGOAL]:
Organizational Unit Name (eg, section) [Arlo]:
Common Name (eg, your name or your server's hostname) [server]:
Name [Arlo]:
Email Address [arlosmile@163.com]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /root/easy-rsa-old-master/easy-rsa/2.0/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'CN'
stateOrProvinceName :PRINTABLE:'SiChuan'
localityName :PRINTABLE:'ChengDu'
organizationName :PRINTABLE:'EZGOAL'
organizationalUnitName:PRINTABLE:'Arlo'
commonName :PRINTABLE:'server'
name :PRINTABLE:'Arlo'
emailAddress :IA5STRING:'arlosmile@163.com'
Certificate is to be certified until Feb 27 01:35:25 2031 GMT (3650 days)
Sign the certificate? [y/n]:y
#此处输入y
1 out of 1 certificate requests certified, commit? [y/n]y
#此处输入y
Write out database with 1 new entries
Data Base Updated
[root@localhost 2.0]# ls keys/
01.pem ca.crt ca.key index.txt index.txt.attr index.txt.old serial serial.old server.crt server.csr server.key
可以看到生成了server.crt证书文件、server.csr和server.key秘钥文件
5、生成客户端在证书和秘钥
[root@localhost 2.0]# ./build-key client
#过程和生成服务端证书和秘钥一样,client表示生成的客户端证书文件名称
[root@localhost 2.0]# ls keys/client*
keys/client.crt keys/client.csr keys/client.key
#生成的三个客户端证书文件
6、生成秘钥交换文件
[root@localhost 2.0]# ./build-dh
[root@localhost 2.0]# ls keys/dh*
keys/dh2048.pem
#生成的该文件即为秘钥交换文件
1.4.2 安装和配置OpenVPN
安装OpenVPN软件,可以直接使用apt或者yum等命令进行安装,但是在CentOS系统中需要注意的是YUM默认源中并秘钥该软件,需要安装epel源。
[root@localhost ~]# yum install -y epel-release
[root@localhost ~]# yum install openvpn -y
安装好之后默认并没有配置文件,需要从模板文档中进行复制在进行修改。
[root@localhost ~]# cp /usr/share/doc/openvpn-2.4.10/sample/sample-config-files/server.conf /etc/openvpn/
[root@localhost ~]# cd /etc/openvpn/
[root@localhost openvpn]# ls
client server server.conf
[root@localhost openvpn]# cat server.conf | grep -v "#" | grep [^$] | grep -v ";"
port 1194
proto udp
dev tun
ca keys/ca.crt
cert keys/server.crt
dh keys/dh2048.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 172.24.208.0 255.255.255.0"
push "route 10.8.0.0 255.255.255.0"
keepalive 10 120
tls-auth keys/ta.key 0
cipher AES-256-GCM
persist-key
persist-tun
status openvpn-status.log
verb 3
explicit-exit-notify 1
#有部分被注释的参数是默认参数,自动生效
配置文件修改好之后我们将上一节中制作的服务端证书文件复制到配置文件中指定的路劲下:
[root@localhost openvpn]# cp /root/easy-rsa-old-master/easy-rsa/2.0/keys/server.crt /etc/openvpn/keys/
[root@localhost openvpn]# cp /root/easy-rsa-old-master/easy-rsa/2.0/keys/server.key /etc/openvpn/keys/
[root@localhost openvpn]# cp /root/easy-rsa-old-master/easy-rsa/2.0/keys/dh2048.pem /etc/openvpn/keys/
[root@localhost openvpn]# cp /root/easy-rsa-old-master/easy-rsa/2.0/keys/ca.crt /etc/openvpn/keys/
启用路由转发功能:
[root@localhost ~]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
[root@localhost ~]# sysctl -p
建立ta.key文件,用于拒绝服务攻击:
[root@localhost ~]# cd /etc/openvpn/keys
[root@localhost keys]# openvpn --genkey --secret ta.key
[root@localhost keys]# ls
ca.crt dh2048.pem server.crt server.key ta.key
启动OpenVPN服务器,并查看服务是否已经启动:
[root@localhost openvpn]# openvpn --daemon --config server.conf
[root@localhost openvpn]# netstat -ntulp | grep 1194
udp 0 0 0.0.0.0:1194 0.0.0.0:* 13953/openvpn
1.4.3 OpenVPN客户端配置
在第一小节中我们已经生成了客户端的证书和秘钥,那么现在我们在来配置下客户端。同样的需要在模板文件中将客户端配置文件复制到客户端配置目录,在进行修改配置。
[root@localhost ~]# cd /etc/openvpn/client/
[root@localhost client]# cp /usr/share/doc/openvpn-2.4.10/sample/sample-config-files/client.conf .
[root@localhost client]# cat client.conf | grep -v "#" | grep -v ";" | grep [^$]
client
dev tun
proto udp
remote my-server-1 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-GCM
verb 3
然后将客户端证书文件复制到client目录中:
[root@localhost ~]# cp /root/easy-rsa-old-master/easy-rsa/2.0/keys/client.crt /etc/openvpn/client/
[root@localhost ~]# cp /root/easy-rsa-old-master/easy-rsa/2.0/keys/client.key /etc/openvpn/client/
[root@localhost ~]# cp /root/easy-rsa-old-master/easy-rsa/2.0/keys/ca.crt /etc/openvpn/client/
[root@localhost ~]# cp /etc/openvpn/keys/ta.key /etc/openvpn/client/
客户端软件可到OpenVPN官方网站https://openvpn.net/community-downloads/
进行下载,注意此网站在国外,可*下载。
我们的本地电脑安装的是Windows 10,所以下载windows 64位版本软件,安装好之后将服务器端client目录中的文件复制到本地OpenVPN安装目录下的config目录下。然后再启动OpenVPN客户端进行连接。