# 虚拟隧道网络 Openvpn

# 一、什么是 VPN

VPN(Virtual Private Network) 翻译过来就是虚拟专⽤⽹络,那虚拟专⽤⽹提供什么功能

  1. 将两个或多个 “不同地域 “的⽹络通过⼀条虚拟隧道的⽅式连接起来,实现互通;
  2. 在不安全的线路上提供安全的数据传输;

# 二、VPN 应⽤场景

# 2.1 点对点连接

Peer-to-Peer VPN (点对点连接),将 Internet 两台机器(公⽹地址)使⽤ VPN 连接起来,⽐如上海服务器和北京服务器的之间的数据需要相互调⽤,但是数据⼜⽐较敏感,直接通过 http 公共⽹络传输,容易被窃取。如果拉⼀条专线成本⼜太⾼。所以我们可以通过 VPN 将两台主机逻辑上捆绑在⼀个虚拟⽹络中,这样既保证了数据传输安全,同时⼜节省了成本。

1.png

# 2.2 站点对站点

SIte-to-Site VPN (站点对站点连接) ,⽤于连接两个或者多个地域上不同的局域⽹ LAN,每个 LAN 有⼀台 OpenVPN 服务器作为接⼊点,组成虚拟专⽤⽹络,使得不同 LAN ⾥⾯的主机和服务器都能够相互通讯。(⽐如国内公司与海外公司分公司的连接)

2.png

# 2.3 远程访问

Remote AccessVPN(远程访问),应⽤于外⽹⽤户访问内部资源。在这个场景中远程访问者⼀般通过公⽹ IP 连接 VPN 服务,然后通过分配后的内⽹地址与其内⽹⽹段进⾏通信。

3.png

# 三、OpenVPN 基本介绍

# 3.1 什么是 OpenVPN

OpenVPN 就像它的名字⼀样,是⼀个开源的软件,且提供

VPN 虚拟专⽤⽹络功能;

  • ⽀持 SSL/TLS 协议,使得数据传输更安全;
  • ⽀持 TCP、UDP 隧道;
  • ⽀持动态分配虚拟 IP 地址;
  • ⽀持数百甚⾄数千⽤户同时使⽤;
  • ⽀持⼤多数主流操作系统平台;

OpenVPN 官⽹:https://openvpn.net

GitHub 地址:https://github.com/OpenVPN/openvpn

# 3.2 OpenVPN 应⽤场景

场景 1:拨⼊ OpenVPN,然后连接内部服务器;

场景 2:实现两个不同地域主机、且两个地域主机 IP 不固定,互连互通;

# 3.3 OpenVPN 实现场景

1.png

# 四、OpenVPN 证书配置

# 4.1 安装 easy-rsa

1. 为了保证 OpenVPN 数据传输安全,所以需要证书,可以通过 easy-rsa ⼯具创建相关证书

[root@openvpn ~]# yum install easy-rsa -y

2. 创建证书前,需要拷⻉配置⽂件,以及 vars ⽂件,定义证书相关的属性

[root@open ~]# mkdir /opt/easy-rsa
[root@open ~]# cd /opt/easy-rsa/
[root@openvpn easy-rsa]# cp -a /usr/share/easy-rsa/3/* ./
[root@openvpn easy-rsa]# cp -a /usr/share/doc/easy-rsa-*/vars.example ./vars

3. 修改 vars ⽂件

[root@openvpn easy-rsa]# cat vars 
if [ -z "$EASYRSA_CALLER" ]; then
	echo "You appear to be sourcing an Easy-RSA 'vars' file." >&2
	echo "This is no longer necessary and is disallowed. See the section called" >&2
	echo "'How to use this file' near the top comments for more details." >&2
	return 1
fi
set_var EASYRSA_CA_EXPIRE 3650            #证书有效期
set_var EASYRSA_CERT_EXPIRE 3650          #服务端证书有效期,默为 825 天
set_var EASYRSA_DN "cn_only"
set_var EASYRSA_REQ_COUNTRY "CN"          #所在的国家
set_var EASYRSA_REQ_PROVINCE "Guangdong"    #所在的省份
set_var EASYRSA_REQ_CITY "Shenzhen"        #所在的城市
set_var EASYRSA_REQ_ORG "nfzl"           #所在的组织
set_var EASYRSA_REQ_EMAIL "xuy@nf-leasing.com" #邮箱的地址
set_var EASYRSA_NS_SUPPORT "yes"
# 4.2 创建证书⽂件
# 4.2.1 初始化 PKI
# 初始化,在当前⽬录创建 PKI ⽬录,⽤于存储证书
[root@openvpn easy-rsa]# ./easyrsa init-pki
Note: using Easy-RSA configuration from: /opt/easy-rsa/vars
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /opt/easy-rsa/pki
# 4.2.2 创建 CA 机构
# 创建 ca 证书,主要对后续创建的 server、client 证书进⾏签名;会提示设置密码,其他可默认
[root@openvpn easy-rsa]# ./easyrsa build-ca
Note: using Easy-RSA configuration from: /opt/easy-rsa/vars
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
Enter New CA Key Passphrase:        #设置密码
Re-Enter New CA Key Passphrase:     #确认密码
Generating RSA private key, 2048 bit long modulus
.................................+++
..............+++
e is 65537 (0x10001)
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.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:nfzl     #输入 nfzl
CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/opt/easy-rsa/pki/ca.crt
# 4.2.3 签发服务端证书

1. 创建 server 端证书,nopass 表示不加密私钥⽂件,其他可默认

[root@openvpn easy-rsa]# ./easyrsa gen-req server nopass
Note: using Easy-RSA configuration from: /opt/easy-rsa/vars
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
Generating a 2048 bit RSA private key
..............................+++
......................................................................+++
writing new private key to '/opt/easy-rsa/pki/easy-rsa-1983.z07ECs/tmp.PBZXuy'
-----
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.
-----
Common Name (eg: your user, host, or server name) [server]:     #回车即可
Keypair and certificate request completed. Your files are:
req: /opt/easy-rsa/pki/reqs/server.req            #请求⽂件
key: /opt/easy-rsa/pki/private/server.key         #私钥

2. 给 server 端证书签名,⾸先是对信息的确认,可以输⼊ yes,然后输⼊创建 ca 根证书时设置的密码

# 第⼀个 server 是类型
# 第⼆个 server 是 req 请求⽂件名称
[root@openvpn easy-rsa]# ./easyrsa sign server server
Note: using Easy-RSA configuration from: /opt/easy-rsa/vars
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.
Request subject, to be signed as a server certificate for 3650 days:
subject=
    commonName                = server
Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes             #输入 yes
Using configuration from /opt/easy-rsa/pki/easy-rsa-2098.GEv4iZ/tmp.oyIjPH
Enter pass phrase for /opt/easy-rsa/pki/private/ca.key:    #输入密码
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'server'
Certificate is to be certified until Jun  8 13:22:49 2033 GMT (3650 days)
Write out database with 1 new entries
Data Base Updated
Certificate created at: /opt/easy-rsa/pki/issued/server.crt   # 公钥
# 4.2.4 创建 DH 密钥

Diffie-Hellman 是⼀种安全协议;让双⽅在完全没有对⽅任何信息情况下通过不安全信道建⽴⼀个密钥; 这个密钥⼀般作为 “对称加密” 的密钥⽽被双⽅在后续数据传输中使⽤;

[root@openvpn easy-rsa]# ./easyrsa gen-dh DH parameters of size 2048 created at /opt/easy-rsa/pki/dh.pem
# 4.2.5 签发客户端证书

1. 创建 client 端私钥⽂件,nopass 表示不加密私钥⽂件,其他可默认

[root@openvpn easy-rsa]# ./easyrsa gen-req client nopass
Note: using Easy-RSA configuration from: /opt/easy-rsa/vars
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
Generating a 2048 bit RSA private key
............................................................+++
.................+++
writing new private key to '/opt/easy-rsa/pki/easy-rsa-2191.qCdaPl/tmp.mqfX2L'
-----
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.
-----
Common Name (eg: your user, host, or server name) [client]:    #回车即可
Keypair and certificate request completed. Your files are:
req: /opt/easy-rsa/pki/reqs/client.req        #请求⽂件
key: /opt/easy-rsa/pki/private/client.key     #私钥⽂件

2. 给 client 端证书签名,⾸先是对信息的确认,可以输⼊ yes,然后创建 ca 根证书时设置的密码

# 第⼀个 client 是类型
# 第⼆个 client 是 req 请求⽂件名称
[root@openvpn easy-rsa]# ./easyrsa sign client client
Note: using Easy-RSA configuration from: /opt/easy-rsa/vars
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.
Request subject, to be signed as a client certificate for 3650 days:
subject=
    commonName                = yes
Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes                      #输入 yes
Using configuration from /opt/easy-rsa/pki/easy-rsa-2218.aCZcDB/tmp.Z2nHgS
Enter pass phrase for /opt/easy-rsa/pki/private/ca.key:            #输入密码
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'yes'
Certificate is to be certified until Jun  8 13:29:01 2033 GMT (3650 days)
Write out database with 1 new entries
Data Base Updated
Certificate created at: /opt/easy-rsa/pki/issued/client.crt     # 客户端公钥

# 五、OpenVPN 服务安装

# 5.1 安装 Openvpn 服务
[root@openvpn ~]# ntpdate time2.aliyun.com         #⼀定要同步时间
[root@openvpn ~]# crontab -l
*/5 * * * * /usr/sbin/ntpdate time2.aliyun.com &> /dev/null
[root@openvpn ~]# yum install openvpn -y
# 5.2 配置 openvpn 服务
[root@openvpn easy-rsa]# cat /etc/openvpn/server.conf 
port 1194                              #端口
proto tcp                              #协议
dev tun                                #采用路由隧道模式 tun
ca ca.crt                              #ca 证书文件位置
cert server.crt                        #服务端公钥名称
key server.key                         #服务端私钥名称
dh dh.pem                              #交换证书
server 10.8.0.0 255.255.255.0          #给客户端分配地址池,注意:不能和 VPN 服务器内网网段有相同
push "route 172.16.1.0 255.255.255.0"  #允许客户端访问内网 172.16.1.0 网段,根据实际情况修改
# push "redirect-gateway def1"
# push "dhcp-option DNS 8.8.8.8"
ifconfig-pool-persist ipp.txt       #地址池记录文件位置
keepalive 10 120                    #存活时间,10 秒 ping ⼀次,120 如未收到响应则视为断线
max-clients 100                     #最多允许 100 个客户端连接
status openvpn-status.log           #日志记录位置
verb 3                              #openvpn 版本
client-to-client                    #客户端与客户端之间通信
log /var/log/openvpn.log            #openvpn 日志记录位置
persist-key                         #通过 keepalive 检测超时后,重新启动 VPN,不重新读取 keys,保留第一次使的 keys
persist-tun                         #检测超时后,重新启动 VPN,一直保持 tun 是 linkup 的。否则网络会先 linkdown 然后再 linkup
duplicate-cn
# 5.3 拷⻉服务端证书⽂件
# 将服务端证书拷⻉⾄ /etc/openvpn ⽬录下
cp /opt/easy-rsa/pki/ca.crt /etc/openvpn/
cp /opt/easy-rsa/pki/dh.pem /etc/openvpn/
cp /opt/easy-rsa/pki/issued/server.crt /etc/openvpn/
cp /opt/easy-rsa/pki/private/server.key /etc/openvpn/
# 5.4 开启内核转发参数
# 必须开启内核转发功能
[root@openvpn ~]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
[root@openvpn ~]# sysctl -p
# 5.5 启动 openvpn 服务
[root@openvpn ~]# systemctl enable openvpn@server && systemctl start openvpn@server
[root@openvpn ~]# netstat -lntp|grep 1194
tcp        0      0 0.0.0.0:1194            0.0.0.0:*               LISTEN      2522/openvpn
#检测 1194 端口是否通,阿里云服务器需安全组规则放行 1194
[root@jumpserver ~]# telnet 192.168.40.70 1194
Trying 192.168.40.70...
Connected to 192.168.40.70.
Escape character is '^]'.
[root@openvpn easy-rsa]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.40.70  netmask 255.255.255.0  broadcast 192.168.40.255
        inet6 fe80::1856:7b0:9d1e:7208  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:75:9b:a9  txqueuelen 1000  (Ethernet)
        RX packets 2542  bytes 836133 (816.5 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3150  bytes 327134 (319.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.1.70  netmask 255.255.255.0  broadcast 172.16.1.255
        inet6 fe80::1607:3fa8:6c0d:8f7f  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:75:9b:b3  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 18  bytes 1382 (1.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 10.8.0.1  netmask 255.255.255.255  destination 10.8.0.2
        inet6 fe80::d334:578d:2988:1996  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 100  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3  bytes 144 (144.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

# 六、OpenVPN 客户端

# 6.1 客户端连接 Linux

1. 端安装 openvpn

[root@openvpn-client ~]# yum install openvpn -y

2. 下载客户端公钥与私钥以及 Ca 证书⾄客户端

[root@openvpn-client ~]# cd /etc/openvpn/
[root@openvpn-client openvpn]# scp root@192.168.40.70:/opt/easy-rsa/pki/ca.crt ./
[root@openvpn-client openvpn]# scp root@192.168.40.70:/opt/easy-rsa/pki/issued/client.crt ./
[root@openvpn-client openvpn]# scp root@192.168.40.70:/opt/easy-rsa/pki/private/client.key ./

3. 客户端有了公钥和私钥后,还需要准备对应的客户端配置⽂件

[root@db01 openvpn]# cat client.ovpn
client                        #指定当前 VPN 是客户端
dev tun                       #使用 tun 隧道传输协议
proto tcp                     #使用 udp 协议传输数据
remote 192.168.40.70 1194     #openvpn 服务器 IP 地址端口号
resolv-retry infinite         #断线后动重新连接,在网络不稳定的情况下非常有用
nobind                        #不绑定本地特定的端口号
ca ca.crt                     #指定 CA 证书的文件路径
cert client.crt               #指定当前客户端的证书文件路径
key client.key                #指定当前客户端的私钥文件路径
verb 3                        #指定日志文件的记录详细级别,可选 0-9,等级越高日志内容越详细
persist-key                   #通过 keepalive 检测超时后,重新启动 VPN,不重新读取 keys,保留第几次使用的 keys
persist-tun                   #检测超时后,重新启动 VPN,一直保持 tun 是 linkup 的。否则网络会先 linkdown 然后再 linkup

4. 启动 openvpn 客户端

[root@db01 openvpn]# openvpn --daemon --cd /etc/openvpn --config client.ovpn --log-append /var/log/openvpn.log
# --daemon:openvpn 以 daemon ⽅式启动。
# --cd dir:配置⽂件的⽬录,openvpn 初始化前,先切换到此⽬录。
# --config file:客户端配置⽂件的路径。
# --log-append file:⽇志⽂件路径,如果⽂件不存在会⾃动创建。
[root@db01 openvpn]# ps aux|grep openvpn
root       2675  0.0  0.1  75164  3448 ?        Ss   16:20   0:00 openvpn --daemon --cd /etc/openvpn --config client.ovpn --log-append /var/log/openvpn.log
root       2705  0.0  0.0 112812   980 pts/0    S+   16:21   0:00 grep --color=auto openvpn
      
[root@db01 openvpn]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.40.51  netmask 255.255.255.0  broadcast 192.168.40.255
        inet6 fe80::63d4:467f:9b76:e34f  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::1856:7b0:9d1e:7208  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:e0:f8:86  txqueuelen 1000  (Ethernet)
        RX packets 2911  bytes 880086 (859.4 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1943  bytes 249205 (243.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.1.51  netmask 255.255.255.0  broadcast 172.16.1.255
        inet6 fe80::1607:3fa8:6c0d:8f7f  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::b64e:4e5e:1653:e542  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:e0:f8:90  txqueuelen 1000  (Ethernet)
        RX packets 6  bytes 516 (516.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 66  bytes 5642 (5.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 97  bytes 15400 (15.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 97  bytes 15400 (15.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 10.8.0.6  netmask 255.255.255.255  destination 10.8.0.5
        inet6 fe80::7cc6:553f:e98d:9633  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 100  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3  bytes 144 (144.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
# 6.2 客户端连接 Windows

openvpn for windows 客户端下载地址、openvpn-2.4.11-Win7.exe、openvpn-2.4.11-Win10.exe

1. 下载服务端准备的客户端密钥⽂件和 ca ⽂件⾄ C:\Program Files\OpenVPN\config ⽬录中

[root@openvpn ~]# sz /opt/easy-rsa/pki/ca.crt
[root@openvpn ~]# sz /opt/easy-rsa/pki/issued/client.crt
[root@openvpn ~]# sz /opt/easy-rsa/pki/private/client.key

2. 在 C:\Program Files\OpenVPN\config 创建⼀个客户端配置⽂件,名称叫 client.ovpn

client                       #指定当前 VPN 是客户端
dev tun                      #使用 tun 隧道传输协议
proto tcp                    #使用 udp 协议传输数据
remote 192.168.40.70 1194   #openvpn 服务器 IP 地址端口号
resolv-retry infinite        #断线自动重新连接,在网络不稳定的情况下非常有用
nobind                       #不绑定本地特定的端口号
ca ca.crt                    #指定 CA 证书的文件路径
cert client.crt              #指定当前客户端的证书文件路径
key client.key               #指定当前客户端的私钥文件路径
verb 3                       #指定日志文件的记录详细级别,可选 0-9,等级越越高志内容越详细
persist-key                  #通过 keepalive 检测超时后,重新启动 VPN,不重新读取 keys,保留第一次使用的 keys
persist-tun                  #检测超时后,重新启动 VPN,一直保持 tun 是 linkup 的。否则网络会先 linkdown 然后再 linkup

3. 最终 windows 的⽬录中配置⽂件如下

C:\Program Files\OpenVPN\config
ca.crt
client.crt
client.key
client.ovpn
README.txt

4. 登陆成功后,通过 windows 查看 openvpn 服务推送过来的路由信息;

# 查看连接状态 10.8.0.6 连接 172.16.1.60
[root@openvpn ~]# netstat -nt
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0     36 172.16.1.70:22          10.8.0.6:52391          ESTABLISHED
tcp        0      0 192.168.40.70:1194      192.168.40.1:52319      ESTABLISHED
tcp        0      0 192.168.40.70:22        192.168.40.1:51544      ESTABLISHED
# windows 查看推送过来的路由信息
[C:\~]$ route print -4
===========================================================================
接口列表
 14...94 c6 91 22 3a e8 ......Realtek PCIe GBE Family Controller
 13...00 ff 9c 82 0c c4 ......TAP-Windows Adapter V9
  5...52 2b 73 e8 4f b4 ......Microsoft Wi-Fi Direct Virtual Adapter
 18...50 2b 73 e8 4f b4 ......Microsoft Wi-Fi Direct Virtual Adapter #2
 20...00 50 56 c0 00 01 ......VMware Virtual Ethernet Adapter for VMnet1
 11...00 50 56 c0 00 08 ......VMware Virtual Ethernet Adapter for VMnet8
 10...00 50 56 c0 00 0f ......VMware Virtual Ethernet Adapter for VMnet15
 17...50 2b 73 e8 4f b4 ......Realtek 8188GU Wireless LAN 802.11n USB NIC
  1...........................Software Loopback Interface 1
===========================================================================
IPv4 路由表
===========================================================================
活动路由:
网络目标        网络掩码          网关       接口   跃点数
          0.0.0.0          0.0.0.0      192.168.1.1    192.168.1.102     50
         10.8.0.0    255.255.255.0         10.8.0.5         10.8.0.6    281
         10.8.0.4  255.255.255.252            在链路上          10.8.0.6    281
         10.8.0.6  255.255.255.255            在链路上          10.8.0.6    281
         10.8.0.7  255.255.255.255            在链路上          10.8.0.6    281
        127.0.0.0        255.0.0.0            在链路上         127.0.0.1    331
        127.0.0.1  255.255.255.255            在链路上         127.0.0.1    331
  127.255.255.255  255.255.255.255            在链路上         127.0.0.1    331
       172.16.1.0    255.255.255.0         10.8.0.5         10.8.0.6    281         #路由条目
      192.168.1.0    255.255.255.0            在链路上     192.168.1.102    306
    192.168.1.102  255.255.255.255            在链路上     192.168.1.102    306
    192.168.1.255  255.255.255.255            在链路上     192.168.1.102    306
     192.168.40.0    255.255.255.0            在链路上      192.168.40.1    291
     192.168.40.1  255.255.255.255            在链路上      192.168.40.1    291
   192.168.40.255  255.255.255.255            在链路上      192.168.40.1    291
    192.168.137.0    255.255.255.0            在链路上     192.168.137.1    291
    192.168.137.1  255.255.255.255            在链路上     192.168.137.1    291
  192.168.137.255  255.255.255.255            在链路上     192.168.137.1    291
    192.168.195.0    255.255.255.0            在链路上     192.168.195.1    291
    192.168.195.1  255.255.255.255            在链路上     192.168.195.1    291
  192.168.195.255  255.255.255.255            在链路上     192.168.195.1    291
        224.0.0.0        240.0.0.0            在链路上         127.0.0.1    331
        224.0.0.0        240.0.0.0            在链路上     192.168.195.1    291
        224.0.0.0        240.0.0.0            在链路上      192.168.40.1    291
        224.0.0.0        240.0.0.0            在链路上     192.168.137.1    291
        224.0.0.0        240.0.0.0            在链路上          10.8.0.6    281
        224.0.0.0        240.0.0.0            在链路上     192.168.1.102    306
  255.255.255.255  255.255.255.255            在链路上         127.0.0.1    331
  255.255.255.255  255.255.255.255            在链路上     192.168.195.1    291
  255.255.255.255  255.255.255.255            在链路上      192.168.40.1    291
  255.255.255.255  255.255.255.255            在链路上     192.168.137.1    291
  255.255.255.255  255.255.255.255            在链路上          10.8.0.6    281
  255.255.255.255  255.255.255.255            在链路上     192.168.1.102    306
===========================================================================
永久路由:

# 七、OpenVPN ⽤户密码认证

我们⽬前使⽤密钥进⾏加密传输,可以说已经很安全了,为什么还要需要⽤户名秘密呢。

1、首先管理这些秘钥和证书⽐较麻烦,如果⽤户⽐较多,单独为每个⽤户都创建⼀套秘钥⽐较麻烦;
2、其次多⼈使⽤同⼀秘钥⼜不具有唯⼀性,⽐如说有⽤户不在需要 VPN 的时候,我们就需要吊销证书,如果多⼈使⽤⼀个秘钥的情况下,吊销证书会造成其他⽤户也⽆法正常登录。

所以就需要秘钥加⽤户名密码,这样就可以实现多个⽤户使⽤同⼀个证书,使⽤不同的⽤户名和密码; 当有新⽤户加⼊时,只需要添加⼀个⽤户名和密码即可,如果不需要使⽤,则删除⽤户名和密码即可;

# 7.1 OpenVPN 服务端配置

1、修改服务端配置

# 添加如下三⾏代码,使其服务端⽀持密码认证⽅式
[root@openvpn ~]# vim /etc/openvpn/server.conf
script-security 3                                         #允许使用自定义脚本
auth-user-pass-verify /etc/openvpn/check.sh via-env       #自定义脚本路径
username-as-common-name                                   #用户密码登陆方式验证
# 表示只使用用户名密码方式验证,不加该参数,则代表需要证书、用户名、密码多重验证登录
# client-cert-not-required

2、创建⾃定义脚本

[root@openvpn ~]# vim /etc/openvpn/check.sh
#!/bin/sh
###########################################################
PASSFILE="/etc/openvpn/openvpnfile"
LOG_FILE="/var/log/openvpn-password.log"
TIME_STAMP=`date "+%Y-%m-%d %T"`
if [ ! -r "${PASSFILE}" ]; then
  echo "${TIME_STAMP}: Could not open password file \"${PASSFILE}\" for reading." >> ${LOG_FILE}
  exit 1
fi
CORRECT_PASSWORD=`awk '!/^;/&&!/^#/&&$1=="'${username}'"{print $2;exit}' ${PASSFILE}`
if [ "${CORRECT_PASSWORD}" = "" ]; then 
  echo "${TIME_STAMP}: User does not exist: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
  exit 1
fi
if [ "${password}" = "${CORRECT_PASSWORD}" ]; then 
  echo "${TIME_STAMP}: Successful authentication: username=\"${username}\"." >> ${LOG_FILE}
  exit 0
fi
echo "${TIME_STAMP}: Incorrect password: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
exit 1
# 为脚本增加执⾏权限
[root@openvpn ~]# chmod +x /etc/openvpn/check.sh

3、创建⽤户密码⽂件

# 创建 `check.sh` 脚本中定义 `openvpn` 使⽤的⽤户和密码认证⽂件
cat > /etc/openvpn/openvpnfile <<EOF
xuyong 123456
EOF

4、重启 OpenVPN 服务

[root@openvpn ~]# systemctl restart openvpn@server
# 7.2 OpenVPN 客户端配置

1、修改客户端配置 C:\Program Files\OpenVPN\config

# 修改客户端配置文件,增加如下代码,使其支持用户名 / 密码与服务器进行身份验证;
auth-user-pass                #用户密码认证

2、客户端重新登陆

Snipaste_2025-06-07_23-10-45.jpg

# 八、OpenVPN 访问内部⽹段

# 8.1 内部节点无法正常访问

抓包分析数据包能抵达 openvpn 的内⽹地址,但⽆法与 OpenVPN 服务同内⽹⽹段主机进⾏通信;

因为后端主机没有去往 10.8.0.0 ⽹段的路由,所以数据包⽆法原路返回,最终造成⽆法 ping 通

[root@windows ~]# ping 172.16.1.51 -t
正在 Ping 172.16.1.51 具有 32 字节的数据:
请求超时。
#在后端的主机上抓包分析,发现能接收到数据包,但没有回去的路由所以⽆法通信
[root@openvpn-client ~] tcpdump  -i eth1 -nn -p icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
16:44:54.957022 IP 10.8.0.10 > 172.16.1.51: ICMP echo request, id 1, seq 137, length 40
16:44:59.956197 IP 10.8.0.10 > 172.16.1.51: ICMP echo request, id 1, seq 138, length 40

解决此问题有如下⼏种⽅式:

⽅式 1:在每台节点添加⼀条路由,下⼀跳为 Openvpn 节点;

⽅式 2:在所有内⽹主机的默认路由器上添加⼀条路由,下⼀跳为 Openvpn 节点;

⽅式 3:配置 iptables、firewalld 的 NAT 规则

# 8.2 在节点上添加主机路由

1、在后端主机添加抵达去往 10.8.0.0/24 ⽹段的⾛ openvpn 的内⽹地址进⾏路由(原理如下图)

1.jpg

[root@openvpn-client ~] route add -net 10.8.0.0/24 gw 172.16.1.70
[root@db01 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.40.2    0.0.0.0         UG    100    0        0 eth0
10.8.0.0        172.16.1.70     255.255.255.0   UG    0      0        0 eth1
172.16.1.0      0.0.0.0         255.255.255.0   U     101    0        0 eth1
192.168.40.0    0.0.0.0         255.255.255.0   U     100    0        0 eth0

2、添加完路由后,继续 ping 该节点,在抓包查看

[root@openvpn-client ~] tcpdump  -i eth1 -nn -p icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
16:48:14.054654 IP 10.8.0.10 > 172.16.1.51: ICMP echo request, id 1, seq 240, length 40
16:48:14.054673 IP 172.16.1.51 > 10.8.0.10: ICMP echo reply, id 1, seq 240, length 40
16:48:15.055662 IP 10.8.0.10 > 172.16.1.51: ICMP echo request, id 1, seq 241, length 40
16:48:15.055683 IP 172.16.1.51 > 10.8.0.10: ICMP echo reply, id 1, seq 241, length 40
16:48:16.056026 IP 10.8.0.10 > 172.16.1.51: ICMP echo request, id 1, seq 242, length 40
16:48:16.056046 IP 172.16.1.51 > 10.8.0.10: ICMP echo reply, id 1, seq 242, length 40

3、通过 vpn 连接内⽹服务器,检查内⽹服务器与哪个 IP 建⽴连接(会发现是真实的 VPN 客户端节点);

[root@openvpn-client ~] netstat -nt
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0     36 172.16.1.51:22          10.8.0.10:53947         ESTABLISHED
tcp        0      0 192.168.40.51:22        192.168.40.1:53130      ESTABLISHED
# 8.3 配置 NAT 地址替换

如上的配置需要在所有后端主机添加,如果机器量过多,那么添加起来⾮常的麻烦,可以在 VPN 节点上增加防⽕墙规则配置,实现地址替换(原理如下图)

2.jpg

# Iptables
[root@openvpn ~]# iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth1 -j MASQUERADE    # ⾃动
[root@openvpn ~]# iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth1 -j SNAT --to 172.16.1.70
# Firewalld
[root@openvpn ~]# systemctl start firewalld
[root@openvpn ~]# firewall-cmd --addservice=openvpn --permanent
[root@openvpn ~]# firewall-cmd --add-masquerade --permanent
[root@openvpn ~]# firewall-cmd --reload

2. 通过 vpn 连接内⽹服务器,检查内⽹服务器与哪个 IP 建⽴连接(会发现是 SNAT 后的内⽹ IP);

[root@windows ~]# ssh root@172.16.1.51
[root@db01 ~]# netstat -nt|grep 22
tcp        0      0 192.168.40.51:22        192.168.40.1:60083      ESTABLISHED
tcp        0     36 172.16.1.51:22          172.16.1.70:60439       ESTABLISHED
# 8.4 配置路由器路由条⽬(公有云)

实验环境准备

2.jpg

1. 华南 3 买三台,公网 IP,安全组放行 1194 端口;

2. 西南购买 1 台,公网 IP;

1.jpg

实现场景 1:
1.Windows 主机通过远程访问 vpn,能够直接链接阿里云内网主机;

方法一:给路由器添加路由条目,指向 VPN 主机;

5.jpg

方法二: 在 VPN 主机上使用 iptables 或 firewalld 规则;

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j SNAT --to 172.16.1.70

实现场景 2:
1. 西南 Linux 主机拨入 vpn 后,可以直接访问华南地域的内网;

实现场景 3:
1.windows 和西南地区的 Linux 主机都拨入了 VPN,它们之间通过虚拟地址是可以互通;

# 九、OpenVP 结合 Jumpserver

实现拨通 OpenVPN 后,仅能够访问 Jumpserver172.16.1.61.

[root@openvpn easy-rsa]# cat /etc/openvpn/server.conf 
port 1194                              #端口
proto tcp                              #协议
dev tun                                #采用路由隧道模式 tun
ca ca.crt                              #ca 证书文件位置
cert server.crt                        #服务端公钥名称
key server.key                         #服务端私钥名称
dh dh.pem                              #交换证书
server 10.8.0.0 255.255.255.0          #给客户端分配地址池,注意:不能和 VPN 服务器内网网段有相同
push "route 172.16.1.61 255.255.255.255"  #允许客户端访问内网 172.16.1.61 主机,根据实际情况修改
# push "redirect-gateway def1"
# push "dhcp-option DNS 8.8.8.8"
ifconfig-pool-persist ipp.txt       #地址池记录文件位置
keepalive 10 120                    #存活时间,10 秒 ping ⼀次,120 如未收到响应则视为断线
max-clients 100                     #最多允许 100 个客户端连接
status openvpn-status.log           #日志记录位置
verb 3                              #openvpn 版本
client-to-client                    #客户端与客户端之间通信
log /var/log/openvpn.log            #openvpn 日志记录位置
persist-key                         #通过 keepalive 检测超时后,重新启动 VPN,不重新读取 keys,保留第一次使的 keys
persist-tun                         #检测超时后,重新启动 VPN,一直保持 tun 是 linkup 的。否则网络会先 linkdown 然后再 linkup
duplicate-cn
此文章已被阅读次数:正在加载...更新于

请我喝[茶]~( ̄▽ ̄)~*

Xu Yong 微信支付

微信支付

Xu Yong 支付宝

支付宝