OpenVPN代理
# 介绍
VPN(Virtual Private Network)直译就是虚拟专用通道。可用于提供给企业之间或者个人与公司之间安全数据传输的隧道。而OpenVPN就是用于建立虚拟专用通道的服务之一。 OpenVPN程序之间谁是客户端谁是服务端,取决于各自扮演的角色,客户端与服务端建立连接后,两端之间实际是平等的,A可以访问B,B也可以访问A,类似于一个组网。
# 特点
加密
- 使用OpenSSL库来提供数据和控制通道的加密。
- 提供可选的HMAC功能以提高连接的安全性。
- OpenSSL支持硬件加速。
身份验证
- 允许使用预设的私钥、第三方证书、或者用户名/密码来进行身份验证。
网络
- 支持以TCP或UDP协议进行通信,默认是使用UDP协议。
- IANA指定给OpenVPN的官方端口为1194。
- 服务端支持将一些网络配置信息"推送"到客户端,如IP地址、路由设置等。
- 支持IPv6。
- 提供了两种虚拟网络接口Tun/Tap驱动。可用于建立三层IP隧道,或者虚拟二层以太网,后者可以传送任何类型的二层以太网络数据。
- 传输的数据可通过LZO算法压缩。
安全
- 它在用户空间中运行,无须对内核及网络协议栈作修改,可以以非root用户来运行。
- 使用mlockall以防止敏感数据交换到磁盘。
可扩展性
- 使用脚本或第三方插件来进行功能的扩展。
# 工作机制
OpenVpn的技术核心是虚拟网卡,其次是SSL协议实现,SSL VPN工作在TCP协议的应用层。
点对点模式工作流程
- 服务端启动openvpn服务,服务程序创建一个虚拟网卡,同时监听1194端口。
- 客户端启动openvpn服务,同时指定服务端的远程地址进行连接。
- 客户端与服务端在连接的时候,会通过1194控制端口进行配置的协商,协商好后会连接成功。
- 连接成功后,两者就可以通过虚拟网卡配置的隧道IP地址,来进行互相通讯。
- 两者之间的数据交互,都是在数据通道上来做的,也就是虚拟网卡之间。
- 例如:一端连接另一端的SSH端口,这就是在数据通道上来做的。
# 部署
客户端和服务端都要安装OpenVPN。
Linux
# 安装EPEL源
yum install -y epel-release.noarch
# 安装OpenVPN、easy-rsa
# easy-rsa用于管理rsa秘钥,比直接用openssl操作秘钥更方便一些
yum install -y openvpn easy-rsa
2
3
4
5
6
Windows
从官网中下载Windows安装包进行安装(需要翻墙):https://openvpn.net/community-downloads/
安装后编写配置文件,然后启动可执行文件即可。如果需要使用命令行,则需要将安装目录中的bin目录添加到环境变量。
# 命令参数
# 通用选项
# --config
--config file
- 用于载入指定的配置文件。如果
--config
参数是执行openvpn命令所使用的唯一参数,则--config
也可以省略,例如:openvpn server.conf
。
注意:
如果配置文件中存在两个相同的参数,则以最接近文件底部的参数为准。
如果配置文件和命令行中存在同一参数,则优先以命令行的参数为准。
# --proto
--proto [ udp | tcp-server | tcp-client ]
- 用于指定监听端口的协议,默认udp。- 如果服务端指定为tcp-server,则客户端的--remote参数就需要指定为tcp-client。
# --local
--local host
- 设置用于绑定OpenVPN服务的网卡,可以指定为地址或者名称。- 如果指定了,那么OpenVPN服务仅会绑定到指定的网卡上监听。如果没有指定,那么OpenVPN服务会绑定到所有的网卡上监听。
# --remote
--remote host [port] [proto]
- 用于连接远程主机建立隧道。- 远程地址可以是外网地址,同一局域网内也可以是内网地址,只要能够访问到对端即可。
host: 远程主机名称或者是IP地址
port: 远程主机使用的端口号,默认为1194
proto: 远程主机使用的协议,默认为UDP
# --port
--port port
- 指定本地和远程机器绑定的TCP/UDP端口,默认1194。
# --lport
--lport port
- 仅设定本地主机绑定的TCP/UDP端口。- 本地和远程机器绑定的端口不同时,可以使用。
# --rport
--rport port
- 仅设定远程主机绑定的TCP/UDP端口。- 本地和远程机器绑定的端口不同时,可以使用。
# --dev
--dev tunX | tapX
- 用于设置TUN/TAP虚拟网络设备。- X代表数字,如果省略了X,则表示使用动态设备编号从0开始。两端虚拟网络设备类型需要一致,不能混用。
# --ifconfig
--ifconfig l rn
- 用于设置TUN/TAP适配器接口的参数。- l:l(local)表示本地VPN端点的IP地址。
- rn:rn分两种情况使用,需要根据情况使用r(remote)或者n(netmask)。
- 如果是点对点模式下的TUN设备,则使用r(remote)表示远程VPN端点的IP地址。如:
--ifconfig 10.200.0.1 10.200.0.2
- 如果是TAP设备或者是**--topology subnet的TUN设备**,则使用n(netmask)表示的是虚拟网段的子网掩码,如:
--ifconfig 10.200.0.1 255.255.255.0
- 如果是点对点模式下的TUN设备,则使用r(remote)表示远程VPN端点的IP地址。如:
# --user
--user user
- 在OpenVPN初始化完成后,改变所使用的系统用户的ID,通过将进程降级以提高安全性。
# --group
--group group
- 与--user类似,将OpenVPN进程改变到由该选项指定的组运行。
# --genkey
--genkey
- 用于生成一个共享加密的密钥文件,可以和--secret一起使用来指定秘钥文件名。
# --secret
--secret file [direction]
- 在运行OpenVPN时指定,可启用静态秘钥加密模式(Static Key)。- file:需要指定一个由--genkey生成的密钥文件。
- 静态密钥加密模式:
- 抽出两个对称密钥 (默认)。
- 在OpenVPN建立连接时,它会从密钥文件中取出两个对称密钥,一个用来加密,一个用来签署数据包的HMAC密钥。
- HMAC是哈希运算消息验证码的缩写,在OpenVPN通信时会用到。发送方会用HMAC密钥和消息进行输入生成一个哈希值,然后再连同消息一起发送给接收方。接收方收到消息后,会对其进行签名摘要验证,用接收方本地的HMAC密钥带上收到的消息生成一个哈希值,然后判断该哈希值和传递过来的哈希值是否一致,如果发现不一致则会直接丢掉。
- 通过direction抽出二对非对称密钥。
- 客户端的加密密钥、客户端的HMAC密钥、服务端的加密密钥、服务端的HMAC密钥。
- 抽出两个对称密钥 (默认)。
# --verb
--verb n
- 设置输出消息详细程度。- n:范围是 0-11 默认是1。
# --persist-[ tun | key ]
--persist-[ tun | key ]
- persist-xxx表示重启OpenVPN时,保持原有的xxx。- persist-tun:如果指定了该参数,那么在通过SIGUSR1或者--ping-restart来重启OpenVPN时,不会重新打开新的TUN/TAP设备,直接使用原来的。
- persist-key:如果指定了该参数,那么在通过SIGUSR1或者--ping-restart来重启OpenVPN时,不会重新读取key文件,直接使用缓存中的。
# --daemon
--daemon [progname]
- 如果指定了该参数,那么OepnVPN在所有初始化完成之后,会变成一个后台运行的守护进程。- progname: 指定记录在日志文件中的来源条目的值,默认为openvpn。
# --log
--log file
- 覆盖写日志,将指定文件原有的内容清空,然后再将输出日志信息写入到指定文件中。- 使用该参数之后,屏幕将不会打印日志,而是写入到文件。
# --log-append
--log-append file
- 追加写日志,将输出的日志信息追加到指定的文件尾部。- 使用该参数之后,屏幕将不会打印日志,而是写入到文件。
# --route
--route network/IP [netmask] [gateway] [metric]
- 会在建立连接之后添加指定路由项,它可以指定多个路由项。同时在TUN/TAP设备关闭之前,将会以逆序的方式自动删除这些添加的路由项。- netmask:子网掩码,默认是255.255.255.255。
- gateway:网关地址,默认是ifconfig的第二个参数。
- metric:路由度量值,默认是0。
network和getway还支持以下关键字:
vpn_gateway:代表远程VPN节点地址。
net_gateway:代表预先存在的默认网关地址。
remote_host:如果OpenVPN是运行在客户端模式下,并且没有定义Server模式,则它表示remote地址。
# --route-delay
--route-delay [n] [w]
- 指定在建立完成连接之后、或者添加路由之前的延迟时间。- n:如果是0,则表示在完成连接之后立即添加路由。默认是在启用TUN/TAP设备和--up脚本被执行之后,且在降级权限之前添加路由。
- w:在Windows上,在添加路由之前等待w秒。默认是为30秒。
# --mode
--mode m
- 用于设置OpenVPN的模式。- p2p:点对点模式,OpenVPN的默认模式。
- server:客户端/服务端模式,可执行多个客户端、便于扩展,但必须使用SLL/TLS。
# --server
--server network netmask ['nopool']
- 用于为VPN隧道指定分配的IP地址段和掩码,服务器会使用网段的第1个地址。- 他是一个简化OpenVPN的Server模式配置的辅助指令,类似于宏。
- 例如:--server 10.200.0.0 255.255.255.0 同等于以下配置:
# --client
--client
- 将OpenVPN配置为客户端模式。- 它也是一个辅助指令,同等于pull和tls-client参数。
# --push
--push "option"
- 用于服务端向客户端推送一个选项,选项的内容要放置在双引号内,同时可以使用方括号引用服务器配置的值。客户端必须指定--pull选项。例如:
push "route 10.200.0.0 255.255.255.0"
、push "topology [topology]"
。当前可被推送的选项有:
# --topology
--topology mode
- 用于在tun模式下,配置虚拟地址的拓扑结构。- 在tap模式下,该选项无意义,因为在tap模式下使用subnet拓扑。
- 可选的mode值:
- net30 - 默认的拓扑结构,但是比较老,会浪费IP地址,不推荐使用。
- p2p - 它只会为每个客户端分配一个地址,解决了net30的IP地址浪费的问题。但是不支持Windows客户端,不推荐使用。
- subnet (推荐) - 子网拓扑、地址分配由IP和网络掩码完成。subnet是推荐的拓扑结构,但不是默认值。
- Server和Client均使用且只使用一个IP地址,节省了大量的IP,且降低了配置的难度。
# --ifconfig-pool
--ifconfig-pool start-IP end-IP [netmask]
- 该选项设置一个子网地址池,用于为连接的客户端动态分配地址,类似于DHCP服务器。- 如果是net30或p2p拓扑下的TUN模式,则会为每个客户端分配一个/30的子网,主要是与Windows客户端协同工作。
- 如果是TAP模式或subnet拓扑下的TUN模式,则会为每个客户端分配单个地址,可选项netmask参数也将会被推送到客户端。
# --route-gateway
--route-gateway gw | 'dhcp'
- 用于指定默认的网关。- 如果指定了DHCP参数,则从OpenVPN服务器所在的网络中的DHCP中获取网关地址。
# TLS模式选项
# --ca
--ca file
- 指定信任的CA的证书文件 (根证书或其子证书)。由该CA机构颁布的证书才会信任。- 需要是pem格式的证书文件,可以包含多个CA的证书。
# --cert
--cert file
- 指定本机的证书文件。该文件是由CA签名颁发的证书,该文件包含本机的公共秘钥、颁发机构的信息、证书的有效期、用途等信息。
# --key
--key file
- 指定本机的私有秘钥文件。
# --dh
--dh file
- 指定dh参数文件,VPN服务端节点需要指定。- dh秘钥交换协议,就是现有的公共秘钥加密使用的协议。该参数文件就是dh协议所用到的参数文件,它可以让双方在缺乏对端私有信息的前提下,通过公共的不安全的网络,双方协商生成一个共享的密钥,该密钥用于后续的通信中,使用对称性加密来加密通信的数据。
- 该参数文件并非安全敏感的,被第三方拿到也没有关系,只要保证每个通信的机器上有该dh参数文件即可。
# --tls-[ server|client ]
--tls-server
- 启用TLS模式,并且在TLS会话过程中将当前主机充当Server或Client角色。默认为tls-server。
# 对端状态检测与处理选项
# --ping
--ping n
- 如果在n秒内没有数据包发送,那么就在控制通道上ping远程主机。
# --ping-exit
--ping-exit n
- 和ping一起使用。如果在n秒之后,没有从远程主机收到ping或者其他数据包,那么关闭OpenVPN服务器。
# --ping-restart
--ping-restart n
- 和ping一起使用。如果在n秒之后,没有从远程主机收到ping或者其他数据包,那么OpenVPN服务器将会通过SIGUSR1信号来重启OpenVPN服务器。
# --ping-timer-rem
--ping-timer-rem
- 如果有远程地址,那么就运行ping-exit/ping-restart定时器。
# --keepalive
--keepalive n m
- 类似于ping的功能,会在连接上时发送类似ping的信息,以便发现某一段断开。- n:表示间隔,每隔多少秒ping一次。
- m:表示如果ping之后多少秒没有收到回应,则表示对方已断开。
# 配置文件格式
# 格式
- 配置文件中的选项没有"--"。
- 配置文件可嵌套。
- 行首的"#"或";"字符表示注释行。
- 包含空格的参数,要用双引号或单引号包裹。
- 非单引号的反斜杠""会被当做Shell的转义字符。
- Windows系统中,使用双斜线来表示路径名。
# 例子
# 命令行写法
openvpn --ifconfig 10.200.0.1 10.200.0.2 --dev tun --secret secret.key
# 转化为配置文件写法
ifconfig 10.200.0.1 10.200.0.2
dev tun
secret secret.key
# 用配置文件启动OpenVPN
openvpn server.conf
2
3
4
5
6
7
8
9
10
# 点对点配置
# 介绍
点对点VPN就是在同一时刻,只能有一个客户端可以连接VPN服务器。
它的优点是配置简单容易,不需要证书、公钥基础设施等。缺点是无前向保密,始终使用一个密钥,且密钥是以明文的形式存储在每个VPN节点上的。
# 实验环境
OpenVPN服务端:
192.168.10.4/24
OpenVPN客户端:
192.168.10.11/24
隧道两端的IP地址规划为:
- Server:
10.200.0.1
- Client:
10.200.0.2
- Server:
# 实现方法
服务端
openvpn --ifconfig [自己的隧道地址] [对端的隧道地址] --dev [虚拟接口模式]
- 执行后OpenVPN会创建一个虚拟网卡,用于建立安全隧道。
- 同时会监听本机的1194端口,使对端能够通过物理地址连接本机。
- 例如:
openvpn --ifconfig 10.200.0.1 10.200.0.2 --dev tun
客户端
openvpn --ifconfig [自己的隧道地址] [对端的隧道地址] --dev [虚拟接口模式] --remote [对端网络的物理地址]
- 指定remote可以远程连接到服务端,建立两端之间的隧道连接。
- 例如:
openvpn --ifconfig 10.200.0.2 10.200.0.1 --dev tun --remote 192.168.10.4
# 静态秘钥模式
# 介绍
如果OpenVPN不使用任何加密方式,数据通道的数据传输都将使用明文,有受到中间人攻击的风险。
常见的解决方案有:
- 静态秘钥(Static key)
- 优点:不需要证书和CA,配置简单。
- 缺点:密钥的分发与管理成本高。没有前向保密功能,只要有一台主机的秘钥泄露,那么之前或之后的传输的内容,都可能会泄露。
- TLS秘钥协商(TLS-negotiated key)
# 实现方法
生成静态秘钥文件。
openvpn --genkey --secret [密钥文件保存路径]
- 例如:
openvpn --genkey --secret secret.key
将该秘钥文件分发到各端,建议使用SCP或STFP等方式,传输方式尽量做到安全。
客户端和服务端启动时通过**--secret**参数指定秘钥即可。
服务端:
openvpn --ifconfig 10.200.0.1 10.200.0.2 --dev tun --secret secret.key
客户端:
openvpn --ifconfig 10.200.0.2 10.200.0.1 --dev tun --remote 192.168.10.4 --secret secret.key
# 站点到站点配置
# 介绍
如果两个局域网之间需要通信,我们可以在各局域网中都安装一台VPN服务器。然后将两台VPN通过点对点的方式连接起来。
# 实验环境
# 实现方法
# 1. Linux配置IP转发(路由)功能
# 临时启用
echo 1 > /proc/sys/net/ipv4/ip_forward
# 永久启用
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p
# 检查是否启用,1表示打开,0表示关闭
cat /proc/sys/net/ipv4/ip_forward
2
3
4
5
6
7
8
9
# 2. 配置路由
我们需要告诉各主机这两个局域网是如何路由,然后不同局域网之间的各主机才能正常的通信。
如果VPN1没有配置路由,则发送数据包时由于找不到VPN2(172.16.12.0/24)相关的路由,于是就会走默认路由导致发送失败。
如果VPN1配置了路由,但VPN2没有配置路由,则VPN1局域网内的主机发送ping请求包到VPN2局域网的主机时,由于VPN2的路由表中没有VPN1的路由,VPN2就会把响应发给默认网关,因而导致响应包丢失,无法正常通信。
默认网关可以通过
route -n
命令查看路由表得知,路由表中Destination为0.0.0.0的就是默认路由。在路由表中如果没有明确的目标方,则都会转发到默认网关。
# 手动配置静态路由
- 添加静态路由:
route add -net [目标网段] gw [本机网关地址]
- 例如:
route add -net 172.16.11.0/24 gw 10.200.0.1
,告诉主机让目标IP属于172.16.11.0/24的数据包,都走10.200.0.1网关发出。
- 例如:
- 删除静态路由:
route del -net [目标网段]
# OpenVPN配置路由 (推荐)
- OpenVPN的配置文件中添加route参数,让OpenVPN自动添加路由。
- VPN1:
route 172.16.12.0 255.255.255.0
- VPN2:
route 172.16.11.0 255.255.255.0
# 3. 编写VPN服务端配置文件
- VPN1服务器配置文件
cat>/etc/openvpn/server/server.conf<<EOF
dev tun
proto udp
local 192.168.1.231
lport 1194
remote 192.168.1.232
rport 1194
route 172.16.12.0 255.255.255.0
secret /etc/openvpn/secret.key
ifconfig 10.200.0.1 10.200.0.2
user nobody
group nobody
persist-tun
persist-key
keepalive 10 60
ping-timer-rem
verb 3
EOF
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- VPN2服务器配置文件
cat>/etc/openvpn/server/server.conf<<EOF
dev tun
proto udp
local 192.168.1.232
lport 1194
remote 192.168.1.231
rport 1194
route 172.16.11.0 255.255.255.0
secret /etc/openvpn/secret.key
ifconfig 10.200.0.2 10.200.0.1
user nobody
group nobody
persist-tun
persist-key
keepalive 10 60
ping-timer-rem
verb 3
EOF
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 4. 两台VPN服务器都启动OpenVPN
openvpn --config /etc/openvpn/server/server.conf
# TLS秘钥协商模式
# TLS模式介绍
TLS(Transport Layer Security) 传输层安全协议,它是OpenVPN的两种加密模式之一。OpenVPN在控制通道初始化TLS会话,交换动态密钥和HMAC密钥,并通过这些密钥对数据通道进行加密。
OpenVPN需要使用证书来实现TLS,每个OpenVPN节点需要有自己和CA的证书。握手协商时,节点会将自己证书发送给对端,然后通过CA证书检查对端发送过来的证书。
在通讯双方相互检查成功之后,TLS自动协商就完成了,两个OpenVPN节点就会生成一个临时会话Key用于加密数据,且在之后的通讯中,也会定期更换临时会话Key加密数据。
# PKI介绍
PKI(Public Key Infrastructure)即公钥基础设施,它一般指证书颁发机构CA、数字证书、证书吊销列表CRL、使用PKI的程序与服务、证书和CA的管理工具、其他辅助组件。
PKI用于提高通信、应用程序和商业交易安全性的基于安全的工具、技术、流程和规范,它能够提供保密性、完整性、真实性、不可否认性。
# 证书颁发机构(CA)
Root CA的主要功能是给自己签发自签名证书、验证证书请求者的身份、向用户或计算机等颁发证书、管理证书吊销列表,建议CA服务器、与其他服务器分开,提高安全性。
常用的CA软件:OpenSSL、EasyRSA(封装了OpenSSL的命令,使管理更简单)。
# 通过easy-rsa构建PKI
# 安装easy-rsa命令
yum install -y easy-rsa
ln -s /usr/share/easy-rsa/3/easyrsa /usr/bin/easyrsa
# 创建并切换到CA目录
mkdir -p /etc/openvpn/ca && cd /etc/openvpn/ca
# 初始化PKI目录
easyrsa init-pki
# 构建CA,按照提示输入信息即可
# Enter New CA Key Passphras:输入CA的密码
# Common Name:指定CA机构名称,默认是Easy-RSA CA
easyrsa build-ca
# 查看CA证书信息
openssl x509 -text -in pki/ca.crt
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# CA PKI目录结构
# VPN服务端/客户端申请证书
# 申请流程
- 在VPN服务器生成一个密钥对 (私有秘钥、公共密钥)。
- VPN服务器将它的公共密钥发送给CA服务器。
- CA服务器将VPN1发送过来的公共密钥,加上一些用CA服务器私有密钥加密的额外的信息(签名操作),最终生成VPN1的证书。
- 然后CA服务器将CA证书和VPN的证书发送给VPN。
# 申请操作
- VPN服务器
# 安装easy-rsa命令
yum install -y easy-rsa
ln -s /usr/share/easy-rsa/3/easyrsa /usr/bin/easyrsa
# 创建并切换到Cert目录
mkdir -p /etc/openvpn/cert && cd /etc/openvpn/cert
# 初始化PKI目录
easyrsa init-pki
# 生成密钥对:easyrsa gen-req [证书名称],然后按照提示输入信息
# Enter PEM pass phrase:输入PEM的密码
# Common Name:指定证书名称
easyrsa gen-req vpn
# 生成之后密钥对位置
# 私钥./pki/private/[证书名称].key
# 公钥./pki/reqs/[证书名称].req
# 发送公钥到CA服务器,各种方式都行,只要能发送给CA服务器
# 如果是VPN服务器和CA服务器是一台主机,则不发送即可
scp pki/reqs/vpn.req root@192.168.10.11:/tmp/vpn.req
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- Req PKI目录结构
- CA服务器
# 切换到ca目录
cd /etc/openvpn/ca
# 将申请者的公钥文件导入到PKI的reqs目录中,easyrsa import-req [文件路径] [基本名称]
# 会将公钥文件以基本名称为文件名称名,导入到PKI目录中的reqs目录中,该基本名称会用于后续证书的辨识名称、公共名称,可以填上申请者名称
# 如果申请者主机和CA服务器是一台主机,则可以跳过这步
easyrsa import-req /tmp/vpn.req vpn
# 对公钥进行签名生成证书文件,easyrsa sign-req [证书用途] [基本名称],如果公钥设置了密码,会要求输入一次密码
# 证书用途包括client、server、serverClient、ca
# 基本名称指在reqs目录下的公钥文件的文件名
easyrsa sign-req server vpn
# 生成的证书文件位置
# ./pki/issued/[基本名称].crt
# 发送CA证书和签发的证书到申请者主机,各种方式都行,只要能发回去就行
# 如果是VPN服务器和CA服务器是一台主机
scp /etc/openvpn/ca/pki/issued/vpn.crt /etc/openvpn/ca/pki/ca.crt root@192.168.10.21:/tmp/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# VPN服务端生成dh参数文件
# 切换到证书目录
cd /etc/openvpn/ca
# 生成dh参数文件
easyrsa gen-dh
# 生成的dh文件位置
# ./pki/dh.pem
2
3
4
5
6
7
8
# 客户端到服务端配置
# 实现方法
各端上面要有密钥、证书等文件。
创建配置文件。
- server服务端配置文件
cat>/etc/openvpn/server/server.conf<<EOF dev tun proto udp port 1194 server 10.200.0.0 255.255.255.0 topology subnet user nobody group nobody persist-key persist-tun keepalive 10 60 ca /etc/openvpn/cert/ca.crt cert /etc/openvpn/cert/vpn01.crt key /etc/openvpn/cert/pki/private/vpn01.key dh /etc/openvpn/cert/pki/dh.pem EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21- client客户端配置文件
cat>/etc/openvpn/client/client.conf<<EOF client dev tun proto udp remote 192.168.10.11 port 1194 ca /etc/openvpn/cert/ca.crt cert /etc/openvpn/cert/vpn02.crt key /etc/openvpn/cert/pki/private/vpn02.key EOF
1
2
3
4
5
6
7
8
9
10
11
12最后运行OpenVPN服务端,然后再运行客户端即可。
# 访问VPN后面资源方法
# 服务端充当路由配置
# 介绍
- 客户端访问服务端后面的资源,要通过服务端,也就是访问资源内网段要配置路由到服务端。
- 服务器端和客户端都需要知道各个网络如何走,我们可以直接通过OpenVPN的push参数告诉客户端如何走。
# 实验环境
# 实现方法
- 服务器配置IP转发(路由)功能。
# 临时启用
echo 1 > /proc/sys/net/ipv4/ip_forward
# 永久启用
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p
# 检查是否启用,1表示打开,0表示关闭
cat /proc/sys/net/ipv4/ip_forward
2
3
4
5
6
7
8
9
配置文件配置路由。
- server服务端配置文件
dev tun proto udp port 1194 server 10.200.0.0 255.255.255.0 topology subnet # 告诉服务端主机请求172.16.50.0网段走route1 route 172.16.50.0 255.255.255.0 192.168.1.235 # 告诉客户端主机请求172.16.50.0网段走VPN1 push "route 172.16.50.0 255.255.255.0" user nobody group nobody persist-key persist-tun keepalive 10 60 ca /etc/openvpn/cert/ca.crt cert /etc/openvpn/cert/vpn01.crt key /etc/openvpn/cert/pki/private/vpn01.key dh /etc/openvpn/cert/pki/dh.pem
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25- client客户端配置文件
dev tun proto udp remote 192.168.10.11 port 1194 persist-key persist-tun keepalive 10 60 ca /etc/openvpn/cert/ca.crt cert /etc/openvpn/cert/vpn02.crt key /etc/openvpn/cert/pki/private/vpn02.key
1
2
3
4
5
6
7
8
9
10
11
12
# 服务端NAT配置
# 介绍
NAT转发可以将客户端请求到后端业务主机的数据包,其源IP伪装成服务端网卡所使用的IP。OpenVPN服务端使用NAT功能,需要使用对iptables进行配置,开启NAT转发。
# 实验环境
# 实现方法
- 服务端操作
# 服务器配置IP转发(路由)功能
## 临时启用
echo 1 > /proc/sys/net/ipv4/ip_forward
## 永久启用
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p
## 检查是否启用,1表示打开,0表示关闭
cat /proc/sys/net/ipv4/ip_forward
# 添加目标网段的路由,让服务器知道目标网段该怎么走,可在OpenVPN配置中添加
# route add -net [目标网段] gw [本机网关地址]
# 使用iptables配置NAT转发
iptables -t nat -A POSTROUTING -s 10.200.0.0/24 -o ens32 -j MASQUERADE
# 服务端OpenVPN配置
cat>/etc/openvpn/server/server.conf<<EOF
dev tap
proto udp
port 1194
server 10.200.0.0 255.255.255.0
topology subnet
push "route 127.16.50.0 255.255.255.0"
user nobody
group nobody
persist-key
persist-tun
keepalive 10 60
ca /etc/openvpn/cert/ca.crt
cert /etc/openvpn/cert/vpn01.crt
key /etc/openvpn/cert/pki/private/vpn01.key
dh /etc/openvpn/cert/pki/dh.pem
EOF
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
- 客户端配置
dev tun
proto udp
remote 192.168.10.11
port 1194
persist-key
persist-tun
keepalive 10 60
ca /etc/openvpn/cert/ca.crt
cert /etc/openvpn/cert/vpn02.crt
key /etc/openvpn/cert/pki/private/vpn02.key
2
3
4
5
6
7
8
9
10
11
12
# 验证方法
- 客户端ping业务主机
- 后端业务主机通过抓包进行验证
tcpdump -i [网卡名] icmp -n
,如果业务主机抓到的包的源地址是VPN在网段中的地址,则表示NAT转发是正常的。
# 配置客户端密码认证
# 服务端
- 创建密码认证文件存放目录。
mkdir -p /etc/openvpn/auth
- 创建密码认证脚本。
cat>/etc/openvpn/auth/checkpsw.sh<<EOF
#!/bin/bash
# 密码文件位置
PASSFILE="/etc/openvpn/auth/password"
# 日志文件位置
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
EOF
####################################################################
##### 也可以用MD5加密判断密码,然后密码文件中保存MD5加密后的值,这样更安全 #####
####################################################################
cat>/etc/openvpn/auth/checkpsw.sh<<EOF
#!/bin/bash
# 密码文件位置
PASSFILE="/etc/openvpn/auth/password"
# 日志文件位置
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}\"." >> ${LOG_FILE}
exit 1
fi
INPUT_PASSWORD_MD5=`echo -n "mchuan_ovpn@${password}" | openssl md5 | awk '{print $2}'`
if [ "${INPUT_PASSWORD_MD5}" = "${CORRECT_PASSWORD}" ]; then
echo "${TIME_STAMP}: Successful authentication: username=\"${username}\"." >> ${LOG_FILE}
exit 0
fi
echo "${TIME_STAMP}: Incorrect password: username=\"${username}\"." >> ${LOG_FILE}
exit 1
EOF
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
- 创建密码文件。
vim /etc/openvpn/auth/password
格式:一行对应一个用户
用户名01 密码
用户名02 密码
... ...
例如:
zhangsan qwe123123
lisi qwe123456
2
3
4
5
6
7
8
9
- 认证脚本与密码文件权限配置。
# 认证脚本添加执行权限
chmod +x /etc/openvpn/auth/checkpsw.sh
# 密码文件修改权限以保证安全
chown nobody.nobody /etc/openvpn/auth/password
chmod 400 /etc/openvpn/auth/password
2
3
4
5
6
- OpenVPN配置文件添加密码认证配置。
dev tap
proto udp
port 1194
server 10.200.0.0 255.255.255.0
topology subnet
push "route 192.168.10.0 255.255.255.0"
push "route 172.17.0.1 255.255.0.0"
# 配置客户端不需要证书认证
client-cert-not-required
# 配置用户密码认证脚本
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env
# 配置使用用户名密码登录认证
username-as-common-name
# 配置脚本安全级别
script-security 3
user nobody
group nobody
persist-key
persist-tun
keepalive 10 60
# 仍然配上证书
ca /etc/openvpn/cert/ca.crt
cert /etc/openvpn/cert/vpnsvc.crt
key /etc/openvpn/cert/pki/private/vpnsvc.key
dh /etc/openvpn/cert/pki/dh.pem
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 客户端
OpenVPN配置文件中添加auth-user-pass参数即可。
dev tun
proto udp
remote 192.168.10.11
port 1194
auth-user-pass
persist-key
persist-tun
keepalive 10 60
# 只需要配CA证书,无需配客户端证书
ca /etc/openvpn/cert/ca.crt
2
3
4
5
6
7
8
9
10
11
12
13