# 虚拟隧道网络 Openvpn
# 一、什么是 VPN
VPN(Virtual Private Network) 翻译过来就是虚拟专⽤⽹络,那虚拟专⽤⽹提供什么功能
- 将两个或多个 “不同地域 “的⽹络通过⼀条虚拟隧道的⽅式连接起来,实现互通;
- 在不安全的线路上提供安全的数据传输;
# 二、VPN 应⽤场景
# 2.1 点对点连接
Peer-to-Peer VPN (点对点连接),将 Internet 两台机器(公⽹地址)使⽤ VPN 连接起来,⽐如上海服务器和北京服务器的之间的数据需要相互调⽤,但是数据⼜⽐较敏感,直接通过 http 公共⽹络传输,容易被窃取。如果拉⼀条专线成本⼜太⾼。所以我们可以通过 VPN 将两台主机逻辑上捆绑在⼀个虚拟⽹络中,这样既保证了数据传输安全,同时⼜节省了成本。
# 2.2 站点对站点
SIte-to-Site VPN (站点对站点连接) ,⽤于连接两个或者多个地域上不同的局域⽹ LAN,每个 LAN 有⼀台 OpenVPN 服务器作为接⼊点,组成虚拟专⽤⽹络,使得不同 LAN ⾥⾯的主机和服务器都能够相互通讯。(⽐如国内公司与海外公司分公司的连接)
# 2.3 远程访问
Remote AccessVPN(远程访问),应⽤于外⽹⽤户访问内部资源。在这个场景中远程访问者⼀般通过公⽹ IP 连接 VPN 服务,然后通过分配后的内⽹地址与其内⽹⽹段进⾏通信。
# 三、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 实现场景
# 四、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、客户端重新登陆
# 八、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 的内⽹地址进⾏路由(原理如下图)
[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 节点上增加防⽕墙规则配置,实现地址替换(原理如下图)
# 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 配置路由器路由条⽬(公有云)
实验环境准备:
1. 华南 3 买三台,公网 IP,安全组放行 1194 端口;
2. 西南购买 1 台,公网 IP;
实现场景 1:
1.Windows 主机通过远程访问 vpn,能够直接链接阿里云内网主机;
方法一:给路由器添加路由条目,指向 VPN 主机;
方法二: 在 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 |