×××概述:

×××(Virtual Private NetWork,虚拟专用网络)架设在公共共享的基础设施互联网上,在非信任的网络上建立私有的安全的连接,把分布在不同地域的办公场所、用户或者商业伙伴互联起来。

在目前的实践中,常见的×××构建技术:

  • PPTP(Point-to-Point Tunneling Protocol,点到点的隧道协议)×××

  • IPSec(Internet Protocol Security,互联网协议安全)×××

  • SSL/TLS(Secure Sockets Layer,安全接口层)×××

3种常见×××构建技术对比:

  • PPTP 需要建立2个隧道进行通信,控制和数据传输分离,其中传输数据使用GRE。在同一个局域网里面的多个内网主机需要建立多条GRE通道连接到同一台×××服务器时,需要在防火墙或者NAT设备上进行特殊设置。

  • IPSec ×××是一个比较成熟的方案,但其配置较复杂,学习成本比较高。IPSec ××× 在商业××× 硬件设备上实现的比较多。

  • SSL/TLS ××× 工作在用户态,不需要对内核做特殊的修改,可移植性比较高,配置简单,学习成本低(常见:Open×××,Bad×××)。

Open××× (当前主流)

功能特性:

  • 对任何IP子网或者虚拟以太网通一个UDP或者TCP端口来建立隧道。

  • 架构一个可扩展的,负载均衡的×××集群系统,同时支持来自上千用户的连接。

  • 使用任意加密算法,可以实现简单的静态密码的传统加密,或者基于证书的公钥私钥加密算法。

  • 对数据流进行实时的压缩。

  • 支持对端节点通过DHCP动态获取IP

  • NAT 支持,对于面向连接的有状态防火墙,不需要特殊设置。

  • 客户端使用,支持Windows,Mac OS ,Linux

3种实现案例:

  • Peer-to-Peer ×××,这种场景,将Internet 两台机器(公网地址)使用×××连接起来。

  • Remote Access ×××(远程访问),该实现方案,旨在解决,移动办公,经常出差不在办公室的,公司生产环境连接。在这个场景种远程访问者一般没有公网IP,他们使用内网地址通过防火墙设备及逆行NAT转换后连接互联网。

  • SIte-to-Site ××× ,用于连接两个或者多个地域上不同的局域网LAN,每个LAN有一台Open××× 服务器作为接入点,组成虚拟专用网络,使得不同LAN里面的主机和服务器都能够相互通讯。

实践案例1:

使用Open××× 创建基于证书验证Remote Access 的×××

物理结构图:

OpenVPN2.4.3 安装部署文档(实战)_VPN 组网

一、安装准备

Open×××  服务器:CetnOS6.8(192.168.1.123,172.16.100.1)

客户端:Windows 10(192.168.1.114) ,Ubuntu 16.0(192.168.0.182)

1、服务端安装依赖库:

OpenSSL,LSZ(一种无损压缩算法),PAM(一种可插入式的身份验证模块)

#安装gcc、openssl、lzo、pam

yum install -y gcc openssl-devel lzo-devel pam-devel

2、网络设置

(1)开启服务器端路由转发功能

# vi /etc/sysctl.conf
net.ipv4.ip_forward = 1
# sysctl -p
或者:
#sed -i 's/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/g' /etc/sysctl.conf
#sysctl -p

(2)设置nat转发:

注:保证×××地址池可路由出外网
# iptables -t nat -A POSTROUTING -s 172.16.100.0/24 -o eth0 -j MASQUERADE

(3)设置openvpn端口通过:

# iptables -A INPUT -p UDP --dport 1194 -j ACCEPT
# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
重启iptables:
注:这里提一下,INPUT策略是执行后即时生效的,POSTROUTING需要保存并重启服务才能生效
# service iptables saves
# service iptables restart

注:此防火墙也可以关闭(则2,3可以不用设置)。

(4)时间同步(重要)

# ntpdate asia.pool.ntp.org

二、安装Open×××服务端

#wget http://swupdate.openvpn.org/community/releases/openvpn-2.4.3.tar.gz.asc
#tar zxvf openvpn-2.4.3.tar.gz
#cd openvpn-2.4.3
# ./configure --prefix=/usr/local/openvpn
# make && make install

三、配置Open×××服务端

配置主要有两个部分:

  • 生成服务器和客户端所需的各种证书。

  • 是编写服务器和客户端所需的配置文件。

(1)下载easy-rsa,创建证书(这部分可以参考"easy-rsa 生成Open×××证书"快速生成所有证书)。

Github 源码2.x

地址:https://github.com/Open×××/easy-rsa/tree/release/2.x

#unzip easy-rsa-release-2.x.zip
#cp -rf easy-rsa/ /usr/local/openvpn/
########创建CA证书########
#cd /usr/local/openvpn/easy-rsa/2.0
#source ./vars       #初始化命令,用于设置后续命令所需的相关变量信息
NOTE: If you run ./clean-all, I will be doing a rm -rf on /usr/local/openvpn/easy-rsa/2.0/keys
#./clean-all  #清除之前创建的所有证书和密钥
#./build-ca #生成CA证书和密钥
Generating a 2048 bit RSA private key
...+++
...........................................................................+++
writing new private key to 'ca.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) [US]:CN
State or Province Name (full name) [California]:SH
Locality Name (eg, city) [SanFrancisco]:SH
Organization Name (eg, company) [Fort-Funston]:ChangLiang        
Organizational Unit Name (eg, section) [MyOrganizationalUnit]:DevOps
Common Name (eg, your name or your server's hostname) [Fort-Funston CA]:Open×××_CA
Name [EasyRSA]:
Email Address [me@myhost.mydomain]:liujian@erichfund.com
##我们的CA证书和密钥就已经生成成功了,生成的证书和密码默认均存放在当前目录keys。
[root@localhost 2.0]#ls keys/
ca.crt  ca.key  index.txt  serial
############创建服务端证书#############
命令./build-key-server ServerName来生成客户端证书和密钥
[root@localhost 2.0]#./build-key-server server#./build-key clientName来生成客户端证书和密钥
Generating a 2048 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) [US]:CN
State or Province Name (full name) [California]:SH
Locality Name (eg, city) [SanFrancisco]:SH
Organization Name (eg, company) [Fort-Funston]:ChangLiang
Organizational Unit Name (eg, section) [MyOrganizationalUnit]:DevOps
Common Name (eg, your name or your server's hostname) [server]:server
Name [EasyRSA]:
Email Address [me@myhost.mydomain]:liujian@erichfund.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /usr/local/openvpn/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:'SH'
localityName          :PRINTABLE:'SH'
organizationName      :PRINTABLE:'ChangLiang'
organizationalUnitName:PRINTABLE:'DevOps'
commonName            :PRINTABLE:'server'
name                  :PRINTABLE:'EasyRSA'
emailAddress          :IA5STRING:'liujian@erichfund.com'
Certificate is to be certified until Aug 20 05:16:14 2027 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]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
############创建客户端证书###############
命令./build-key clientName来生成客户端证书和密钥
[root@localhost 2.0]#./build-key client1
Generating a 2048 bit RSA private key
........................................................+++
..................................................+++
writing new private key to 'client1.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) [US]:CN
State or Province Name (full name) [California]:SH
Locality Name (eg, city) [SanFrancisco]:SH
Organization Name (eg, company) [Fort-Funston]:ChangLiang
Organizational Unit Name (eg, section) [MyOrganizationalUnit]:DevOps
Common Name (eg, your name or your server's hostname) [client1]:Open×××_Client 
Name [EasyRSA]:
Email Address [me@myhost.mydomain]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /usr/local/openvpn/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:'SH'
localityName          :PRINTABLE:'SH'
organizationName      :PRINTABLE:'ChangLiang'
organizationalUnitName:PRINTABLE:'DevOps'
commonName            :T61STRING:'Open×××_Client'
name                  :PRINTABLE:'EasyRSA'
emailAddress          :IA5STRING:'me@myhost.mydomain'
Certificate is to be certified until Aug 20 05:34:01 2027 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
[root@localhost 2.0]#ls ./keys/
01.pem  02.pem  ca.crt  ca.key  client1.crt  client1.csr  client1.key  index.txt  index.txt.attr  index.txt.attr.old  index.txt.old  serial  serial.old  server.crt  server.csr  server.key
##########生成迪菲·赫尔曼交换密钥###########
命令为./build-dh(无需额外输入,耐心等待生成完毕即可)。迪菲·赫尔曼交换密钥是一种安全协议,用以对数据进行加密。
#./build-dh
###########生成TLS-auth密钥############
这一步骤是可选操作。Open×××提供了TLS-auth功能,可以用来抵御Dos、UDP端口淹没攻击。出于安全考虑,你可以启用该功能;启用该功能,你需要执行命令openvpn --genkey --secret keys/ta.key来生成TLS-auth所需的密钥文件。
#/usr/local/openvpn/sbin/openvpn --genkey --secret keys/ta.key
到这里,我们的证书生成就告一段落了。如果你以后想要生成新的客户端或执行其他操作,只需要先执行命令. ./vars,然后执行相应的命令即可,例如./build-key client2。

证书到这创建完成,看看有哪些证书:

OpenVPN2.4.3 安装部署文档(实战)_VPN 组网_02

1:CA证书和密钥

2:服务器端证书和密钥。

3:客户端client1的证书和密钥,

4:迪菲·赫尔曼交换密钥 (如果你的KEY_SIZE=1024,则该文件名称为dh1024.pem)。

5:启用tls-auth所需的文件。

其中,服务器端需要用到的文件有:

ca.crt
ca.key
dh2048.pem (如果最初的变量KEY_SIZE设为1024,这里就是dh1024.pem)
server.crt
server.key
ta.key (如果不开启tls-auth,则无需该文件)

客户端client1需要用到的文件有:

ca.crt
client1.crt
client1.key (名称client1根据个人设置可能有所不同)
ta.key (如果不开启tls-auth,则无需该文件)

(2)编辑服务器所需的配置文件。

#mkdir -p /usr/local/openvpn/config
#cd /usr/local/openvpn/config
#cp /usr/local/openvpn/easy-rsa/2.0/keys/{ca.crt,ca.key,server.crt,server.key,ta.key,dh2048.pem} .
#ls
ca.crt  ca.key  dh2048.pem  server.crt  server.key  ta.key
#cp /opt/openvpn-2.4.3/sample/sample-config-files/server.conf .
#mkdir -p /var/log/openvpn#创建日志目录
#vim server.conf
local 192.168.1.123 #指定监听的本机IP(因为有些计算机具备多个IP地址),该命令是可选的,默认监听所有IP地址。
port 1194 #指定监听的本机端口号
proto udp #指定采用的传输协议,可以选择tcp或udp
;proto tcp
dev tun #指定创建的通信隧道类型,可选tun或tap,前者工作在三层(TCP/IP),后者工作2层(链路层)
ca /usr/local/openvpn/config/ca.crt #指定CA证书的文件路径
cert /usr/local/openvpn/config/server.crt #指定服务器端的证书文件路径
key /usr/local/openvpn/config/server.key #指定服务器端的私钥文件路径
dh /usr/local/openvpn/config/dh2048.pem #指定迪菲赫尔曼参数的文件路径
server 172.16.100.0 255.255.255.0 #指定虚拟局域网占用的IP地址段和子网掩码,此处配置的服务器自身占用10.0.0.1。
ifconfig-pool-persist ipp.txt #服务器自动给客户端分配IP后,客户端下次连接时,仍然采用上次的IP地址(第一次分配的IP保存在ipp.txt中,下一次分配其中保存的IP)。
push "redirect-gateway def1 bypass-dhcp"  #如果启用,该命令将配置所有客户端通过×××重定向其默认
#网络网关,导致所有IP流量(如Web浏览和#和DNS查找)通过×××
push "dhcp-option DNS 202.96.209.5"  #给客户端推送DNS
push "dhcp-option DNS 8.8.8.8"
tls-auth /usr/local/openvpn/config/ta.key 0 #开启TLS-auth,使用ta.key防御攻击。服务器端的第二个参数值为0,客户端的为1。
keepalive 10 120 #每10秒ping一次,连接超时时间设为120秒。
comp-lzo #开启×××连接压缩,如果服务器端开启,客户端也必须开启
client-to-client #允许客户端与客户端相连接,默认情况下客户端只能与服务器相连接
persist-key
persist-tun #持久化选项可以尽量避免访问在重启时由于用户权限降低而无法访问的某些资源。
status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
log-append /var/log/openvpn/openvpn.log #日志保存路径
verb 4 #指定日志文件的记录详细级别,可选0-9,等级越高日志内容越详细
explicit-exit-notify 2 #服务端重启,客户端自动重连

注意1(可以不做配置。):

push "redirect-gateway def1 bypass-dhcp" 如果启用,该命令将配置所有客户端通过×××重定向其默认
#网络网关,导致所有IP流量(如Web浏览和#和DNS查找)通过×××
push "dhcp-option DNS 202.96.209.5" #给客户端推送DNS
client-config-dir ccd #指定文件,对客户端进行细粒度配置(单独给某个客户端推送路由等)。
注意2 这里补充说明一下,dev 设备类型区别:
    TUN和TAP不一样
    TUN是点对点的三层设备,工作在IP层,处理IP分组(本文采用tun方式,有兴趣可以尝试tap方式);
    TAP是虚拟以太网设备,工作在第二层,处理以太网帧;

(3)启动Open×××

#/usr/local/openvpn/sbin/openvpn /usr/local/openvpn/config/server.conf &

#这里要加载server.conf 配置文件启动。

OpenVPN2.4.3 安装部署文档(实战)_VPN 组网_03

注:启停脚本:

#cp -a /opt/openvpn-2.4.3/distro/rpm/openvpn.init.d.rhel /etc/init.d/openvpn          #创建启动脚本
#ln -sv /usr/local/openvpn/sbin/openvpn /usr/sbin/openvpn               #启动脚本中会用到,也可以不执行此命令,直接在启动脚本中修改
#vi /etc/init.d/openvpn
#在85行,修改为:work=/usr/local/openvpn/config
[root@localhost config]#service openvpn stop
Shutting down openvpn:                                     [  OK  ]
[root@localhost config]#service openvpn start
Starting openvpn:                                          [  OK  ]
#添加开机启动
[root@localhost config]#chkconfig --add openvpn
[root@localhost config]#chkconfig  openvpn on
[root@localhost config]#chkconfig --list | grep 3:on
crond          0:off1:off2:on3:on4:on5:on6:off
network        0:off1:off2:on3:on4:on5:on6:off
openvpn        0:off1:off2:on3:on4:on5:on6:off
rsyslog        0:off1:off2:on3:on4:on5:on6:off
sshd           0:off1:off2:on3:on4:on5:on6:off

四、Open×××客户端安装配置:

1、Linux客户端(Ubuntu16 ):

(1)依赖环境配置:

# apt-get install libpam0g-dev libssl-dev
#wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.06.tar.gz
#tar zxvf lzo-2.06.tar.gz
#cd lzo-2.06/
#./configure --prefix=/usr/local/
#make && make install

(2)其下载安装同服务端一样,但是配置文件及证书文件如下:

#mkdir -p /usr/local/openvpn/config
#cd /usr/local/openvpn/config
#scp root@192.168.1.123:/usr/local/openvpn/easy-rsa/2.0/keys/{client1.crt,client1.key,ca.crt,ca.key,ta.key,dh2048.pem} .
# ls
ca.crt  ca.key  client1.crt  client1.key  client.conf  dh2048.pem  ta.key
#vim client.conf


client #指定当前×××是客户端
dev tun #必须与服务器端的保持一致
proto udp #必须与服务器端的保持一致
remote 192.168.1.123 1194 #指定连接的远程服务器的实际IP地址和端口号
resolv-retry infinite #断线自动重新连接,在网络不稳定的情况下(例如:笔记本电>脑无线网络)非常有用。
nobind #不绑定特定的本地端口号
persist-key
persist-tun
ca ca.crt #指定CA证书的文件路径
cert client1.crt #指定当前客户端的证书文件路径
key client1.key #指定当前客户端的私钥文件路径
ns-cert-type server #指定采用服务器校验方式
tls-auth ta.key 1 #如果服务器设置了防御DoS等攻击的ta.key,则必须每个客户端开
启;如果未设置,则注释掉这一行,同服务端一致。
comp-lzo #启用压缩,与服务器保持一致
log-append /var/log/openvpn/openvpn.log
verb 4 #指定日志文件的记录详细级别,可选0-9,等级越高日志内容越详细

(3)启动客户端:

#/usr/local/openvpn/sbin/openvpn /usr/local/openvpn/config/client.conf &

#客户端同样可以使用服务端的启动脚本,只需要修改配置文件为:client.conf

OpenVPN2.4.3 安装部署文档(实战)_VPN 组网_04

OpenVPN2.4.3 安装部署文档(实战)_VPN 组网_05

root@ljohn:/usr/local/openvpn/config# ping 172.16.100.1

PING 172.16.100.1 (172.16.100.1) 56(84) bytes of data.

64 bytes from 172.16.100.1: icmp_seq=1 ttl=64 time=0.477 ms

64 bytes from 172.16.100.1: icmp_seq=2 ttl=64 time=1.09 ms

客户端尝试ping服务器的虚拟IP地址172.16.100.1,顺利ping通。

2、Windows客户端安装配置

windows中只需要安装Open××× GUI,并部署配置文件及客户端证书。

(1)客户端下载地址:https://swupdate.openvpn.org/community/releases/openvpn-install-2.4.3-I602.exe

安装过程中,遇到网络设配器请点击安装,其余默认"Next"即可:

(2)安装完成后在“C:\Program Files\Open×××\config”目录中部署文件:配置文件同上(但后缀名.ovpn)

OpenVPN2.4.3 安装部署文档(实战)_VPN 组网_06

(3)启动客户端:

右击桌面 "Opne××× GUI" 以管理员身份运行,再双击任务栏"Opne××× GUI" 图标(或者任务栏右击 "Opne××× GUI",点击 "connect" 连接),连接成功如下图显示。

OpenVPN2.4.3 安装部署文档(实战)_VPN 组网_07

ping一下Open××× 服务器虚拟IP:172.16.100.1

OpenVPN2.4.3 安装部署文档(实战)_VPN 组网_08

至此完成基于证书验证Remote Access Open×××的配置,至此客户端可以连接上Open××× Server。

四、客户端访问内网地址配置

方案一:

以上4个步骤已经完成Open×××的配置,但是还不能与内网(192.168.1.198)通信,地址映射(虚拟主机 ,DMZ都可以,建议用)需要给内网机器添加静态路由:

Linux平台:

[root@CLJJ-10 ~]#route add -net 172.16.100.0/24 gw 192.168.1.123

OpenVPN2.4.3 安装部署文档(实战)_VPN 组网_09

Windows平台:

C:\WINDOWS\system32>route add -p 172.16.100.0 mask 255.255.255.0 192.168.1.123 metric 3 if 1

OpenVPN2.4.3 安装部署文档(实战)_VPN 组网_10

Ping 内网环境的IP:192.168.1.198

OpenVPN2.4.3 安装部署文档(实战)_VPN 组网_11

方案二:

给路由器配置一条静态路由,如下图所示:

OpenVPN2.4.3 安装部署文档(实战)_VPN 组网_12

注意:如果是3层交换机加一条静态路由,有防火墙还需要开启端口映射及相关策略。

终于完成所有配置,对于出差在外,运维小伙伴,可以躺在家办公了(想得美)。

*****************************FAQ******************************

1、Authenticate/Decrypt packet error: cipher final failed

编辑server.conf 配置文件

注释:cipher AES-256-CBC

2、

Authenticate/Decrypt packet error: packet HMAC authentication failed

TLS Error: incoming packet authentication failed

TLS Error: cannot locate HMAC in incoming packet from [AF_INET]192.168.1.123:1194

注:这三个错误都源于这个tls-auth 认证问题,只需要服务端和客户端关闭此功能即可解决:在此行加上; 分号。如果需要开启可以关闭后再尝试开启

参考资料:

http://www.softown.cn/post/140.html

http://732233048.blog.51cto.com/9323668/1713088