使用openv屁恩实现访问远程网络

章节

  • 概述
  • 使用openvpn实现访问远程网络
  • 吊销证书
  • 故障及排错

 

一、概述


VPN (Virtual Private Network) 是虚拟私有网,它通过在公网上创建一个专用并且加密的网络通道(隧道)进行通讯,在实际的应用中可以帮助远程用户、公司分支机构、商业伙伴及供应商等之间建立一个安全可信的网络连接.

实际上使用VPN的目的及作用就是从网络层面打通两个或多个异地网络,就好像在同一个局域网一样,并且是加密安全的.

使用vpn的一些场景:

  • 穿墙,看外面的世界
  • 本地网络访问公司内网资源,比如在家里或出差的同事要访问到公司内部的网络设备、服务器资源
  • 两个或以上的异地网络互通,比如多个IDC机房、多个分支机构之间内网互通以及数据传输

VPN软件有很多,有商业的、开源的,openvpn就是其中一个非常好的开源vpn软件,在生产环境中使用也非常稳定及可靠,其主要特点:开源、跨平台、易于使用、稳定与安全性,对于中小型企业来说用openvpn架设vpn服务器是个不错的选择,而不去考虑商业的vpn软件,有一定成本优势。呵呵,做运维就是这样,总是用一些开源的软件搭建一套还不错的系统.

二、使用openvpn实现访问远程网络


有这样的需求:有些同事不在公司或在外面出差但又要访问公司内网的服务器资源,一般的做法是做端口映射,但是随着端口映射的数量越来越多带来一些问题:管理比较麻烦、不是很安全、配置繁琐。

对于这种需求可以使用vpn打通自己(本地)的网络与公司的网络,这样就像是在公司内网访问服务器一样并且是安全的.

因此用openvpn来搭建vpn服务器,规划如下:

环境说明:

  • 目的是让你所在的本地网络能够通过vpn服务器访问公司内网(172.16.0.0/24、172.16.2.0/24、10.10.10.0/24)中的主机
  • 用公司内网中的一台(172.16.0.100)作为openvpn服务器,然后在防火墙上做外网端口映射, 发布在外网(因为没有公网地址,只能这样做)
  • 公司网络中的172.16.0.0/24、172.16.2.0/24、10.10.10.0/24网段已经是互通的
IP 作用 说明
172.16.0.100 openvpn 监听在内网1999端口,映射为外网183.16.133.212的1999端口
10.10.10.2 公司内网服务器  
172.16.2.22 公司内网服务器  


1、部署openvpn服务端(172.16.0.100)

openvpn需要tun模块支持,所以先检查是否支持tun模块

# ls /dev/net/tun 
/dev/net/tun                     # 如果有表示支持

停掉selinux

# setenforce 0
setenforce: SELinux is disabled

开启路由转发,编辑  /etc/sysctl.conf 文件将 net.ipv4.ip_forward = 0 改为  net.ipv4.ip_forward = 1,然后执行:

# sysctl -p

安装openvpn及相关包

# curl http://mirrors.aliyun.com/repo/epel-6.repo  -o  /etc/yum.repos.d/epel-6.repo --silent   # 添加阿里的EPEL源
# yum install openssl openvpn easy-rsa lzo -y
  • openssl包   程序包
  • lzo包       用来进行数据压缩
  • easy-ras包,  提供了一些证书生成脚本、模板配置文件等

可以看下装了哪些东西

# rpm -ql openvpn
# rpm -ql easy-rsa

创建相关目录

# mkdir /var/log/openvpn                      # 放openvpn相关日志文件
# mkdir /etc/openvpn/easy-rsa                 # 放easy-rsa包提供的相关工具
# mkdir /etc/openvpn/ccd                      # openvpn客户端的配置目录,后面会用到

将easy-ras包提供的工具复制到 /etc/openvpn/easy-rsa

# cp /usr/share/easy-rsa/2.0/* /etc/openvpn/easy-rsa/ -r 
# cd /etc/openvpn/easy-rsa
# ls                              // 可以看到就是一堆脚本,主要是用来生成证书
build-ca build-key build-key-server clean-all list-crl openssl-1.0.0.cnf sign-req whichopensslcnf
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

修改 openssl-1.0.0.cnf 文件中 default_crl_days值,调大为3650或者更大,默认是30,单位是天, 3650天也就是表示为10年。这步不做的话如果服务端开启了crl-verify(吊销证书)功能,30天后全部客户端会连不上,因为有效期默认是30天,这个坑其它地方不会告诉你

vim  openssl-1.0.0.cnf

找到 并改成 default_crl_days = 3650

编辑 /etc/openvpn/easy-rsa/vars文件,找到下面的变量修改成你指定的值,后面生成证书的时候会应用这些变量值 (不做这步也可以,它会应用默认的变量值)

export KEY_COUNTRY="CN"        # 国家
export KEY_PROVINCE="GD"       # 省份
export KEY_CITY="GZ"           # 城市
export KEY_ORG="MY_ORG"        # 组织/公司
export KEY_EMAIL="vpn@qq.com"  # 邮箱
export KEY_OU="vpn"            # 单位  
export KEY_NAME="openvpn"      # 服务器名称

然后执行

# source vars      # 这一步会导入vars文件中的变量作为当前的环境变量
# ./clean-all      # 清除旧的keys目录下的文件

生成CA(证书颁发机构),一直回车即可

# ./build-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) [CN]:
State or Province Name (full name) [GD]:
Locality Name (eg, city) [GZ]:
Organization Name (eg, company) [MY_ORG]:
Organizational Unit Name (eg, section) [vpn]:
Common Name (eg, your name or your server's hostname) [openvpn CA]:
Name [openvpn]:
Email Address [vpn@qq.com]:

会在 /etc/openvpn/easy-rsa/keys 目录下生成ca.crt、ca.key两个证书文件

# ls /etc/openvpn/easy-rsa/keys/ | grep ca
ca.crt                  
ca.key

生成服务器证书

./build-key-server vpnserver     # 起个名字叫vpnserver,后面会用到 (注:必须是唯一的、尽量是有意义的名称)
Generating a 2048 bit RSA private key
................................+++
.....+++
writing new private key to 'vpnserver.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) [GD]:
Locality Name (eg, city) [GZ]:
Organization Name (eg, company) [MY_ORG]:
Organizational Unit Name (eg, section) [vpn]:
Common Name (eg, your name or your server's hostname) [vpnserver]:
Name [vpn]:
Email Address [vpn@qq.com]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:                                 # 这里是设置连接vpn的时候要不要输入账号和密码,如果不设置就直接回车(可选)
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/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:'GD'
localityName          :PRINTABLE:'GZ'
organizationName      :PRINTABLE:'MY_ORG'
organizationalUnitName:PRINTABLE:'vpn'
commonName            :PRINTABLE:'vpnserver'
name                  :PRINTABLE:'vpn'
emailAddress          :IA5STRING:'vpn@qq.com'
Certificate is to be certified until Apr 29 06:26:49 2026 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

它会在 /etc/openvpn/easy-ras/keys 目录下生成三个证书文件

# ls /etc/openvpn/easy-rsa/keys/ | grep vpnserver
vpnserver.crt
vpnserver.csr
vpnserver.key

生成客户端证书,客户端会用证书来连接服务端

./build-key vpnclient      --- 表示为vpnclient这个客户端生成证书,后面会用到 (注:必须是唯一的、尽量是有意义的名称)
Generating a 2048 bit RSA private key
.......+++
....................+++
writing new private key to 'vpnclient.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) [GD]:
Locality Name (eg, city) [GZ]:
Organization Name (eg, company) [MY_ORG]:
Organizational Unit Name (eg, section) [vpn]:
Common Name (eg, your name or your server's hostname) [vpnclient]:
Name [vpn]:
Email Address [vpn@qq.com]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/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:'GD'
localityName          :PRINTABLE:'GZ'
organizationName      :PRINTABLE:'MY_ORG'
organizationalUnitName:PRINTABLE:'vpn'
commonName            :PRINTABLE:'vpnclient'
name                  :PRINTABLE:'vpn'
emailAddress          :IA5STRING:'vpn@qq.com'
Certificate is to be certified until Apr 29 06:30:42 2026 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

它会在 /etc/openvpn/easy-ras/keys 目录下生成三个证书文件

# ls /etc/openvpn/easy-rsa/keys/ | grep vpnclient
vpnclient.crt
vpnclient.csr
vpnclient.key

上面是交互式的生成证书,还可以使用非交互式的方式生成证书

# ./build-key --batch vpnclient
Generating a 2048 bit RSA private key
.....................................................+++
..........+++
writing new private key to 'vpnclient.key'
-----
Using configuration from /etc/openvpn/easy-rsa/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:'GD'
localityName          :PRINTABLE:'GZ'
organizationName      :PRINTABLE:'weconex.inc'
organizationalUnitName:PRINTABLE:'test'
commonName            :PRINTABLE:'vpnclient'
name                  :PRINTABLE:'TEMP'
emailAddress          :IA5STRING:'weconex@weconex.com'
Certificate is to be certified until Oct  8 17:33:15 2027 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated
View Code

最后创建Diffie Hellman文件,这步需要一点时间,等它执行完就行

# ./build-dh

查看生成的Diffie hellman秘钥文件

# ls /etc/openvpn/easy-rsa/keys | grep 'dh'
dh2048.pem

配置openvpn,编辑/etc/openvpn/server.conf文件,添加如下:

local 172.16.0.100                               # 监听的ip
port 1999                                        # 监听的端口,默认1194,我设置1999,根据你的需求改就行
proto tcp                                        # 使用的协议,默认udp,因为经常要通过vpn传文件对可靠性要求比较高,所以用tcp
dev tun                                          # 使用tun(隧道)模式,openvpn有两种模式,一种是TUN,另一种是TAP
ca   /etc/openvpn/easy-rsa/keys/ca.crt           # 这四条都是指定证书的路径,要确保路径存在或文件能够访问
cert /etc/openvpn/easy-rsa/keys/vpnserver.crt
key  /etc/openvpn/easy-rsa/keys/vpnserver.key  
dh   /etc/openvpn/easy-rsa/keys/dh2048.pem
server 10.8.0.0 255.255.255.0                    # 设置成server模式并给客户端分配的ip段,服务端会用其中.1和.2两个ip,这个网段不要和你的内网冲突
ifconfig-pool-persist ipp.txt                    # 当vpn断开或重启后,可以利用该文件重新建立相同的IP地址连接
push "route 172.16.0.0 255.255.255.0"            # 这三条是给客户端推的路由,客户端连上后会根据这个添加路由,vpn服务器后端有几个网段就写几个
push "route 172.16.2.0 255.255.255.0"            # 这些路由的作用是告诉客户端去另一个子网都转发给TUN接口,类似于静态路由
push "route 10.10.10.0 255.255.255.0"                       
client-config-dir /etc/openvpn/ccd               # 客户端的个性配置目录,比如针对每个客户端推送不同的路由、配置不同的ip
keepalive 10 120                                 # 每10秒ping一次,如果超过120s认为对方已经down了,需要重连commpress lz4-v2                                 # 在vpn链接上启用压缩,服务端开启客户端也必须开启
max-clients 100                                  # 最多有几个vpn客户端可以连
user nobody                                      # 启动openvpn的用户和组,建议用nobody
group nobody  
commpress lz4-v2                                 # 开启压缩
script-security 2                                # 脚本安全级别,2就行了,用于执行外部的脚本(可选)
client-to-client # 允许vpn客户端之间通信 duplicate-cn # 允许多个客户端使用同一个证书登陆,生产环境建议为每个用户都生成自己的证书 persist-key # 通过keepalived检测后重新启动vpn,不重新读取keys,保留第一次使用的keys persist-tun # 通过keepalived检测后重新启动vpn,一直保持tun或tap设备是linkup status /var/log/openvpn/openvpn-status.log # openvpn的状态日志文件 log /var/log/openvpn/openvpn.log # openvpn的日志文件
writepid /var/run/openvpn/server.pid # pid文件 verb
3 # 日志级别 mute 20 # 如果连续出现20条相同的日志,只记录一条

然后启动openvpn

# service openvpn start
# chkconfig --add openvpn
# chkconfig --level 35 openvpn on

会看到有个tun0接口并且添加了两条路由

# ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.8.0.1  P-t-P:10.8.0.2  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:2499142 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2719489 errors:0 dropped:45 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:895142072 (853.6 MiB)  TX bytes:1093625277 (1.0 GiB)

# route -n | grep tun0 10.8.0.2 0.0.0.0 255.255.255.255 UH 0 0 0 tun0 10.8.0.0 10.8.0.2 255.255.255.0 UG 0 0 0 tun0
  • 启动了一个tun0网络接口,ip是10.8.0.1,P-t-P:10.8.0.2 是点到点的意思
  • 添加了两条路由,一个是主机路由 (UH),另一个是静态路由 (UG),表示去10.8.0.0网段的数据包下一跳是10.8.0.2

添加一条SNAT规则,让源地址是10.8.0.0/24网段的地址进来转换成vpn服务器的内网地址(172.16.0.100),这样vpn客户端访问公司内网服务器的时候伪装成vpn服务器去访问

# iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j SNAT --to-source 172.16.0.100 
# service iptables save
# service iptables start
# chkconfig --level 35 iptables on

如果不用上面的SNAT方式,还有种做法是在所有公司内网中的主机或服务器上添加回程路由,这样才能回包给vpn客户端

# route add 10.8.0.0 MASK 255.255.255.0 172.16.0.100        // 如果是windows
# ip route add 10.8.0.0/24 via 172.16.0.100                 // 如果是linux

如果数量少还好,但很多的话就比较麻烦,所以推荐用SNAT的方式,到了这里openvpn服务端已经配好了,客户端可以连了。

2、客户端连接vpn服务器

openvpn支持linux、window、mac等多种客户端,

如果是windows客户端

先安装openvpn-gui一直下一步就行,默认会安装在C:\Program Files\OpenVPN

进到config目录,创建一个vpnclient目文件夹,把服务器上的 /etc/openvpn/easy-rsa/keys下的ca.crt、vpnclient.crt、vpnclient.key三个证书文件拉下来放进去

然后添加一个vpnclient.ovpn的文件,这个文件用来连接openvpn服务端

vpnclient.ovpn文件的内容是

client                        # 设置为client模式
dev tun                       # 设置为tun模式,必须和服务端一致
proto tcp                     # 使用的协议,必须和服务端一致
remote 183.6.133.212 1999     # 指定openvpn服务器的地址和端口
resolv-retry infinite
nobind
persist-key
persist-tun
ca   ca.crt
cert vpnclient.crt
key  vpnclient.key
remote-cert-tls server
auth-nocache                  # 不在内存中缓存密码
commpress lz4-v2              # 启动压缩,必须和服务端一致 
verb 3 

然后连接openvpn,点击运行 选 Connect  ,如果出现绿色图标说明vpn连接成功了.

连接成功后会启一个网络连接,可以看到分配的ip地址是10.8.0.10 / 30

以太网适配器 本地连接 2:

   连接特定的 DNS 后缀 . . . . . . . :
   描述. . . . . . . . . . . . . . . : TAP-Windows Adapter V9
   物理地址. . . . . . . . . . . . . : 00-FF-0A-6B-5D-9D
   DHCP 已启用 . . . . . . . . . . . : 是
   自动配置已启用. . . . . . . . . . : 是
   本地链接 IPv6 地址. . . . . . . . : fe80::bca0:7a3d:716c:5769%17(首选)
   IPv4 地址 . . . . . . . . . . . . : 10.8.0.10(首选)
   子网掩码  . . . . . . . . . . . . : 255.255.255.252
   获得租约的时间  . . . . . . . . . : 2017年10月18日 3:43:41
   租约过期的时间  . . . . . . . . . : 2018年10月18日 3:43:41
   默认网关. . . . . . . . . . . . . :
   DHCP 服务器 . . . . . . . . . . . : 10.8.0.9
   DHCPv6 IAID . . . . . . . . . . . : 469827338
   DHCPv6 客户端 DUID  . . . . . . . : 00-01-00-01-1C-F4-C8-B2-34-E6-D7-6C-5E-88
........

客户端还会添加路由,可以看下路由表,下面这些是服务端配置推送给客户端的路由,其实就是告诉客户端去这些网段都通过vpn服务器,类似于静态路由

> route PRINT -4
IPv4 路由表
=========================================================================== 活动路由: 网络目标 网络掩码 网关 接口 跃点数 10.8.0.0 255.255.255.0 10.8.0.9 10.8.0.10 20 10.8.0.8 255.255.255.252 在链路上 10.8.0.10 276 10.8.0.10 255.255.255.255 在链路上 10.8.0.10 276 10.8.0.11 255.255.255.255 在链路上 10.8.0.10 276 10.10.10.0 255.255.255.0 10.8.0.9 10.8.0.10 20 172.16.0.0 255.255.255.0 10.8.0.9 10.8.0.10 20 172.16.2.0 255.255.255.0 10.8.0.9 10.8.0.10 20

测试,ping下公司内网中的主机,看下是否能够访问,如果可以说明ok了

C:\Users\Administrator ping 172.16.0.104
正在 Ping 172.16.0.104 具有 32 字节的数据:
来自 172.16.0.104 的回复: 字节=32 时间=6ms TTL=63

172.16.0.104 的 Ping 统计信息:
    数据包: 已发送 = 1,已接收 = 1,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 6ms,最长 = 6ms,平均 = 6ms

C:\Users\Administrator> ping 172.16.2.1
正在 Ping 172.16.2.1 具有 32 字节的数据:
来自 172.16.2.1 的回复: 字节=32 时间=7ms TTL=253

172.16.2.1 的 Ping 统计信息:
    数据包: 已发送 = 1,已接收 = 1,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 7ms,最长 = 7ms,平均 = 7ms

C:\Users\Administrator> ping 10.10.10.2
正在 Ping 10.10.10.2 具有 32 字节的数据:
来自 10.10.10.2 的回复: 字节=32 时间=6ms TTL=126

10.10.10.2 的 Ping 统计信息:
    数据包: 已发送 = 1,已接收 = 1,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 6ms,最长 = 6ms,平均 = 6ms

如果是linux客户端

和windows一样,先安装openvpn

# curl http://mirrors.aliyun.com/repo/epel-6.repo  -o  /etc/yum.repos.d/epel-6.repo --silent   # 添加阿里的EPEL源,有的话不用做.
# yum install openvpn -y

创建相关目录

# mkdir /etc/openvpn/keys          # 放客户端的相关证书
# mkdir /var/log/openvpn           # 放日志的目录

将服务器上 /etc/openvpn/easy-rsa/keys 下的ca.crt、vpnclient.crt、vpnclient.key这些证书文件拉下来放到 /etc/openvpn/keys

# ls /etc/openvpn/keys
ca.crt  vpnclient.crt  vpnclient.key

编辑客户端的配置文件/etc/openvpn/client.conf,内容如下

client                                      # 设置为clinet模式
dev tun                                     # 使用tun模式,必须和服务端一致
proto tcp                                   # 使用的协议,必须和服务端一致
remote  183.6.133.212 1999                  # 指定openvpn服务端的ip和端口,有需要可以使用多个做高可用.
resolv-retry infinite
nobind
persist-key
persist-tun
ca   /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/vpnclient.crt
key  /etc/openvpn/keys/vpnclient.key
remote-cert-tls server
auth-nocache user nobody group nobody status
/var/log/openvpn/openvpn-status.log log /var/log/openvpn/openvpn.log writepid /var/run/openvpn/client.pid # 指定pid文件 commpress lz4-v2 # 压缩数据,必须和服务端配置一样 verb 3
mute 20

启动openvpn客户端

# service openvpn start
# chkconfig --add openvpn
# chkconfig --level 35 openvpn on

客户端启动后只有进程,因为它作为客户端去连服务端,不需要提供端口

# ps aux | grep vpn
nobody    4236  0.1  0.3  46916  3232 ?        Ss   01:36   0:00 /usr/sbin/openvpn --daemon --writepid /var/run/openvpn/client.pid 
--cd /etc/openvpn --config client.conf --script-security 2

同样也会有个tun0网络接口

# ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.8.0.14  P-t-P:10.8.0.13  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

此时我们可以看下路由表,下面这些路由就是根据服务器的配置(push)推送过来的,目的是通知客户端根据这个来添加路由,实际上就是告诉客户端去这些网段都转发给tun0接口,也就是vpn服务器,类似静态路由

# route -n | grep tun0
10.8.0.13       0.0.0.0         255.255.255.255 UH    0    0    0 tun0    # 主机路由
172.16.2.0      10.8.0.13       255.255.255.0   UG    0    0    0 tun0    # 去172.16.2.0 下一跳(网关)是10.8.0.13
10.8.0.0        10.8.0.13       255.255.255.0   UG    0    0    0 tun0    # 去10.8.0.0   下一跳(网关)是10.8.0.13
172.16.0.0      10.8.0.13       255.255.255.0   UG    0    0    0 tun0    # 去172.16.0.0 下一跳(网关)是10.8.0.13
10.10.10.0      10.8.0.13       255.255.255.0   UG    0    0    0 tun0    # 去10.10.10.0 下一跳(网关)是10.8.0.13

最后测试,ping下公司内网中的主机,看下是否能够访问,如果可以说明ok了

# ping 172.16.0.104                                           # 可以通公司内网172.16.0.0段中的主机
PING 172.16.0.104 (172.16.0.104) 56(84) bytes of data.
64 bytes from 172.16.0.104: icmp_seq=1 ttl=63 time=7.52 ms
^C
--- 172.16.0.104 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 327ms
rtt min/avg/max/mdev = 7.524/7.524/7.524/0.000 ms

# ping 172.16.2.1                                             # 可以通公司内网172.16.2.1段中的主机
PING 172.16.2.1 (172.16.2.1) 56(84) bytes of data.
64 bytes from 172.16.2.1: icmp_seq=1 ttl=253 time=205 ms
--- 172.16.2.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 768ms
rtt min/avg/max/mdev = 205.701/205.701/205.701/0.000 ms

# ping 10.10.10.2                                             # 可以通公司内网10.10.10.0段中的主机
PING 10.10.10.2 (10.10.10.2) 56(84) bytes of data.
64 bytes from 10.10.10.2: icmp_seq=1 ttl=126 time=5.86 ms
^C
--- 10.10.10.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 755ms
rtt min/avg/max/mdev = 5.865/5.865/5.865/0.000 ms

数据包的走向是:客户端访问公司内网主机 ----- 通过路由转发 ---- vpn服务器(tun0) ---- SNAT -----  公司内网主机

要点小结:

  • vpn的作用就是让两个网络可以互通,就好像在同一个局域网里面一样
  • openvpn配置好了后可以把它看成一个路由器,需要有点网络方面的知识才好理解

其它功能及需求:

1、如何给客户端指定配置,比如不同的客户端不同的ip地址、推送不同路由等

先在server.conf中指定 client-config-dir目录,能够让openvpn访问的到

client-config-dir /etc/openvpn/ccd        #  确保/etc/openvpn/ccd存在

在/etc/openvpn/ccd目录下编辑一个与客户端同名的文件,比如想给vpnclient的这个客户端指定配置,那么就是/etc/openvpn/ccd/vpnclient,这些配置可以是

ifconfig-push 10.8.0.9 10.8.0.10       # 指定客户端的IP地址,如果想固定客户端的ip可以这样做
push "route 172.16.0.0 255.255.255.0"  # 推送指定的路由,不同的客户端推送不同的路由可以这样做   
iroute 172.16.20.0 255.255.255.0       # 忽略路由
push "dhcp-option DNS 202.96.128.166"  # 推送DNS
..........

2、openvpn服务端怎么做高可用

如果vpn服务器只有一台的话就是个单点,如果有需求可以做高可用,做法是准备两台openvpn服务器,它们相关证书、配置都一样(可以做一个然后复制到另一个),然后在客户端的配置文件中指定两个remote

remote  第一个vpn服务器ip   端口
remote  第二个vpn服务器ip   端口

然后测试下模拟挂掉一个,能不能用、对使用有没有什么影响

3、怎么给客户端推送指定的DNS

可以在服务端server.conf或者ccd下面配置文件指定推送给客户端的dns

push "dhcp-option DNS 202.96.128.166" 
push "dhcp-option DNS 202.96.128.167"

这种场景一般是要用到远程内网中的dns,用的不多

4、怎么给客户端生成证书

# cd /etc/openvpn/easy-rsa
# source ./vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys
# ./build-key gz          # 起个名字叫gz,表示为gz这个客户端生成证书
Generating a 2048 bit RSA private key
.........+++
...........+++
writing new private key to 'gz.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) [GD]:
Locality Name (eg, city) [GZ]:
Organization Name (eg, company) [MY_ORG]:
Organizational Unit Name (eg, section) [vpn]:
Common Name (eg, your name or your server's hostname) [gz]:
Name [vpn]:
Email Address [vpn@qq.com]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/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:'GD'
localityName          :PRINTABLE:'GZ'
organizationName      :PRINTABLE:'MY_ORG'
organizationalUnitName:PRINTABLE:'vpn'
commonName            :PRINTABLE:'gz'
name                  :PRINTABLE:'vpn'
emailAddress          :IA5STRING:'vpn@qq.com'
Certificate is to be certified until Oct 17 08:53:46 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

# ls keys/ | grep 'gz'         # 查看生成的证书
gz.crt  gz.key   gz.csr
通过build-key生成客户端证书

对于生成证书需要考虑的问题:是为每个用户生成证书、还是多个客户端使用一个证书? 如果是多个客户端用同一个证书登陆,优点是省事,缺点是如果想吊销这个证书那么就会影响所有的用户, 如果是每个用户都有自己的证书,优点是管理方便,缺点是麻烦(官方推荐为每个用户生成一个证书,每个用户用自己的证书连接vpn,虽然麻烦了点)

5、如何把客户端的默认网关指向vpn服务器

push "redirect-gateway def1 bypass-dhcp"

需要的注意的是,如果这样配置会导致所有的流量都经过vpn服务器,这样的vpn服务器的压力会比较大,一般用的不是很多,除非必须要这么做

三、吊销证书


吊销证书是指让客户端的证书无效,那么被吊销证书的用户就不能连上vpn了。有这个样的场景,某个同事之前给他分配了vpn客户端,可以连vpn,现在它离职了,不想在让他在用vpn了,这时可以吊销它的证书。

例如:吊销客户端 ( vpnclient ) 的证书.

# cd /etc/openvpn/easy-rsa
# source ./vars
# ./revoke-full vpnclient   # 通过revoke-full脚本吊销证书, 吊销vpnclient这个客户端的证书

 执行后将看到下面的提示,表示证书已经被吊销

Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf
Revoking Certificate 03.
Data Base Updated
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf
client02.crt: C = US, ST = CA, L = SanFrancisco, O = Fort-Funston, OU = MyOrganizationalUnit, CN = client02, name = EasyRSA, emailAddress = me@myhost.mydomain
error 23 at 0 depth lookup:certificate revoked  # 出现error 23 表示证书已经被吊销了

需要注意的是到这步还没有彻底完成,此时客户端仍然可以连上。

当通过 revoke-full 脚本吊销客户端的证书后它会在keys(我这里是/etc/openvpn/easy-rsa/keys)目录生成一个crl.pem(吊销证书列表 )文件,所以还需要在openvpn服务器的配置文件 /etc/openvpn/server.conf 添加:

crl-verify /etc/openvpn/easy-rsa/keys/crl.pem      # 指定crl.pem文件的路径,必须存在并能够被启动openvpn的用户有权限读取,否则会报cannot read错误

然后重启openvpn服务

# service openvpn restart
Shutting down openvpn:                                     [  OK  ]
Starting openvpn:                                          [  OK  ]

最后测试被吊销证书的客户端能不能连上vpn服务,如果不能连上说明成功.

此外,还可以通过查看/etc/openvpn/easy-ras/keys/index.txt文件,了解vpn客户端的吊销状态.

  • R 开头的表示reovke,说明是吊销状态,V表示是正常的
  • CN=vpnclient,表示客户端vpnclient已经被吊销
# cat /etc/openvpn/easy-rsa/keys/index.txt
V    270929154610Z        01    unknown    /C=US/ST=CA/L=SanFrancisco/O=Fort-Funston/OU=MyOrganizationalUnit/CN=vpnserver/name=EasyRSA/emailAddress=me@myhost.mydomain
V    270929154708Z        02    unknown    /C=US/ST=CA/L=SanFrancisco/O=Fort-Funston/OU=MyOrganizationalUnit/CN=client01/name=EasyRSA/emailAddress=me@myhost.mydomain
R    271005070515Z    171008142938Z    03    unknown    /C=US/ST=CA/L=SanFrancisco/O=Fort-Funston/OU=MyOrganizationalUnit/CN=vpnclient/name=EasyRSA/emailAddress=me@myhost.mydomain

那么问题来了又想恢复这个被吊销的客户端(vpnclient)呢?  同样可以在openvpn服务器的配置文件/etc/openvpn/server.conf注释或取消:

 crl-verify /etc/openvpn/easy-rsa/keys/crl.pem      # 注释或取消掉这行

重启openvpn,客户端测试,如果能连上说明成功了,又可以连了

四、故障与排错


如果不成功,需要从各个方面排查:

  • 检查openvpn服务器端口和进程是否正常
  • 检查tun0接口和路由表是否正常
  • 检查证书的路径是否能够正常访问
  • 查看openvpn服务器日志(重点)
  • 检查防火墙是否做了限制,是否放通了openvpn的ip或端口
  • 使用tcpdump一节一节的抓包,看包到了那个环节

 

五、扩展脚本

客户端连接或断开服务端时可以执行一些外部的脚本,达到一些统计的目的

服务端,可以配置

# 脚本的级别,用2就行
script-security 2 

# server vpn interface is up
up "/script/server_up.sh"

# server vpn interface is going down
down "/script/server_down.sh"

# client connected to VPN server
client-connect "/script/client_connect.sh"

# client disconnected from VPN server
client-disconnect "/script/client_disconnect.sh"

客户端,可以配置(注意脚本是放在客户端的,这种情况用的不是特别多)

# 脚本的安全级别,用2就行
script-security 2

# Client connected to VPN server
up "/script/connected.sh"

# Client disconnected from VPN server
down "/script/disconnected.sh"

 

posted @ 2017-10-08 22:36  opss  阅读(19990)  评论(5编辑  收藏  举报