相关链接
1. 介绍
OpenVPN 是一个基于 OpenSSL库的应用层 VPN 实现。和传统 VPN 相比,它的优点是简单易用。vpn直译就是虚拟专用通道,是提供企业之间或者公司之间安全数据传输的隧道。 OpenVPN是一个全特性的SSL VPN,它使用2层或3层的安全网络技术,使用的是工业标准的SSL/TLS协议。 SSL(Secure Sockets Layer 安全套接层)及其继任者传输层安全(TransportLayer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议
OpenVPN支持灵活的客户端授权方式,支持证书、智能卡、用户名和密码、文件、LDAP,允许用户可以通过防火墙连接到VPN的虚拟接口 OpenVPN是一个软件服务,不是一个基于web代理的应用,也不是基于浏览器访问。
类似产品 openswan-优势:支持IPsec,可直接实现子网拓展,无需安装客户端
openvpn使用场景
企业员工远程办公,通过远程VPN连接到公司的服务器,访问公司ERP、OA等系统。IT技术人员通过VPN远程连接到机房进行系统维护。
总部与分支机构之间联通,打通分支与总部的连接
多IDC机房之间的互联,实现多机房之间的互联互通,数据共享,文件传送
内网穿透,没有公网IP但需要公网访问相关机器或服务。例如:远程访问家里的机器、内网机器调用支付宝回调需要地址 [ 花生壳、frp、ngrok、路由器的ddns]
注意:OpenVPN适用于功能性实现,对于大流量大带宽应用,建议使用点对点专线实现互联
企业的常见的使用场景 - 多机房互联
2. 安装使用
💡 openvpn的安装使用分为服务端和客户端,使用同一软件,基于不同配置文件进行区分功能。
2.1 服务端安装
2.1.1 安装软件和相关环境
#!/bin/bash
# 安装常用软件
echo "#### 安装常用软件 ntpdate tree net-tools tcpdump wget "
yum install -y ntpdate tree net-tools tcpdump wget
# 同步时间,并添加定时任务
echo '# time sync' >> /var/spool/cron/root
echo '*/5 * * * * ntpdate pool.ntp.org > /dev/null 2>&1' >> /var/spool/cron/root
crontab -l
# 加载内核模块
echo "#### 加载TUN内核模块"
modinfo tun
modprobe tun
lsmod | grep tun
# 安装基础环境
echo "#### 安装 gcc lzo openssl* pam-devel "
yum install -y gcc lzo-devel openssl-devel pam-devel
if [ $? -ne 0 ]; then
echo "install software package failed! "
exit 1
fi
# 安装openvpn
echo "#### openvpn-下载软件包"
cd ~ && wget <https://swupdate.openvpn.org/community/releases/openvpn-2.5.6.tar.gz>
echo "#### openvpn-解压"
tar zxf openvpn-2.5.6.tar.gz
echo "#### openvpn-删除压缩包"
rm -rf openvpn-2.5.6.tar.gz
cd openvpn-2.5.6
echo "#### openvpn-检测"
./configure
if [ $? -ne 0 ]; then
echo "openvpn configure failed! "
exit 1
fi
echo "#### openvpn-编译安装"
make && make install
if [ $? -ne 0 ]; then
echo "openvpn make or install failed! "
exit 1
fi
# 安装证书工具
echo "#### easy-rsa-下载软件包"
cd ~ && wget -O easy-rsa-3.0.8.tar.gz <https://github.91chi.fun/https://github.com//OpenVPN/easy-rsa/archive/refs/tags/v3.0.8.tar.gz>
echo "#### easy-rsa-解压"
tar zxf easy-rsa-3.0.8.tar.gz
echo "#### easy-rsa-删除压缩包"
rm -rf easy-rsa-3.0.8.tar.gz
# 复制相关软件到/etc/openvpn
echo "#### 复制相关软件到/etc/openvpn"
mkdir -p /etc/openvpn && cd /etc/openvpn
cp -a ~/openvpn-2.5.6/sample/sample-config-files/server.conf /etc/openvpn/server.conf.bak
# 整理出一个简洁服务端配置文件,去掉空行和注释行
grep -vE "#|^$" /etc/openvpn/server.conf.bak >> /etc/openvpn/server.conf
cp -a ~/easy-rsa-3.0.8/easyrsa3 /etc/openvpn/key_server/
cp -a ~/easy-rsa-3.0.8/easyrsa3 /etc/openvpn/key_client/
# 开启转发
echo "#### 开启ipv4 IP转发"
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
防火墙处理
################### 测试环境关闭防火墙即可 ###############
## 暂时关闭防火墙
systemctl stop firewalld
## 暂时关闭防火墙
systemctl disable firewalld
################### 线上环境开启相关端口即可 #############
firewall-cmd --add-port 1194/tcp --permanent
firewall-cmd --add-port 1194/tcp --permanent
# 重新加载
firewall-cmd --reload
# 若接口未添加区域则执行添加语句,否则执行改变语句
firewall-cmd --zone=public --add-interface=ens37
firewall-cmd --zone=internal --change-interface=ens37
firewall-cmd --zone=internal --list-all
2.1.2 制作证书
每条命令执行之后都有些信息输出,如出错,会提示相关错误信息
1) ./easyrsa init-pki
初始化,会在当前目录创建PKI目录,用于存储一些中间变量及最终生成的证书
2) ./easyrsa build-ca
创建根证书,首先会提示设置密码,用于ca对之后生成的server和client证书签名时使用,然后会提示设置Country Name,State or Province Name,Locality Name,Organization Name,
Organizational Unit Name,Common Name,Email Address,可以键入回车使用默认的,也可以手动更改
3) ./easyrsa gen-req server nopass
创建server端证书和private key,nopass表示不加密private key,然后会提示设置Country Name,State or Province Name,Locality Name,Organization Name,
Organizational Unit Name,Common Name,Email Address,可以键入回车使用默认的,也可以手动更改
4) ./easyrsa sign server server
给server端证书做签名,首先是对一些信息的确认,可以输入yes,然后输入build-ca时设置的那个密码
5) ./easyrsa gen-dh
创建Diffie-Hellman,时间会有点长,耐心等待
6) 创建client端证书,需要单独把easyrsa3文件夹拷贝出来一份,删除里面的PKI目录,然后进入到此目录
./easyrsa init-pki
初始化,会在当前目录创建PKI目录,用于存储一些中间变量及最终生成的证书
7) ./easyrsa gen-req client nopass
创建client端证书和private key,nopass表示不加密private key,然后会提示设置Country Name,State or Province Name,Locality Name,Organization Name,
Organizational Unit Name,Common Name,Email Address,可以键入回车使用默认的,也可以手动更改
8) 回到制作server证书时的那个easyrsa3目录,导入client端证书,准备签名
./easyrsa import-req client.req所在路径 client
client.req应该在刚才制作client端证书的easyrsa3/pki/reqs/下面
9) ./easyrsa sign client client
给client端证书做签名,首先是对一些信息的确认,可以输入yes,然后输入build-ca时设置的那个密码
注意:ca、server和client的Common Name最好不要设置为一样,我没有验证,不过网上有人说设置一样后,openvpn连接时会有问题
至此,server和client端证书已制作完毕
10) openvpn --genkey secret ta.key
生成tls-auth签名文件. tls-auth 指令向所有 SSL/TLS 握手数据包添加一个额外的 HMAC 签名,以进行完整性验证。可以防止DDos攻击、扫描器、未经授权无法连接
复制证书到/etc/openvpn/keys目录
openvpn server端需要的是
easyrsa3/pki/ca.crt <制作server证书的文件夹>
easyrsa3/pki/private/server.key <制作server证书的文件夹>
easyrsa3/pki/issued/server.crt <制作server证书的文件夹>
easyrsa3/pki/dh.pem
ta.key
openvpn client端需要的是
easy-rsa/easyrsa3/pki/ca.crt <制作server证书的文件夹>
easy-rsa/easyrsa3/pki/issued/client.crt <制作server证书的文件夹>
easy-rsa/easyrsa3/pki/private/client.key <制作client证书的文件夹>
ta.key
2.1.3 编辑配置文件
# 复制配置文件
cp ~/openvpn/openvpn-2.5.6/sample/sample-config-files/server.conf /etc/openvpn/server.conf.bak
# 可使用grep 检索去除注释的行
# grep -vE '#|^$' server.conf.bak >> server.conf
vi server.conf # 修改内容
============================
改为一下内容
# 可以配置监听的IP,多IP时可以配置,默认监听本机所有
;local 172.17.0.14
# 监控本机端口号
port 21194
# 指定采用的传输协议,可以选择tcp或udp
proto tcp
# 指定创建的通信隧道类型,路由tun或桥接tap
dev tun
# Windows需要指定TAP-Win32适配器名称
;dev-node MyTap
# CA证书的文件路径
ca /etc/openvpn/keys/ca.crt
# 服务器端的证书文件路径
cert /etc/openvpn/keys/server.crt
# 服务器端的私钥文件路径 注意这个需要自己添加
**key /etc/openvpn/keys/server.key**
# 迪菲赫尔曼参数的文件路径
dh /etc/openvpn/keys/dh.pem
# 网络拓扑结构
;topology subnet
# 配置服务器模式,并配置VPN子网
# 虚拟局域网占用的IP地址段和子网掩码,此处配置的服务器自身占用.1的ip地址
server 10.8.0.0 255.255.255.0
# 维护客户端<->虚拟IP地址的记录关联
# 服务器自动给客户端分配IP后,客户端下次连接时,仍然采用上次的IP地址(第一次分配的IP保存在ipp.txt中,下一次分配其中保存的IP)。
ifconfig-pool-persist ipp.txt
# 配置以太网桥接的服务器模式。
# 您必须首先使用操作系统的桥接功能以桥接TAP接口与以太网网卡接口。然后必须手动设置网桥接口上的IP/netmask,这里假设10.8.0.4/255.255.255.0。
# 最后,我们必须在这个子网中设置一个IP范围(start=10.8.0.50 end=10.8.0.100)分配联系客户。
# 注释这一行,除非是以太网桥接
;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100
# 配置以太网桥接的服务器模式
# 使用DHCP-proxy,客户端在这里交谈到OpenVPN服务器端DHCP服务器以接收他们的IP地址分配和DNS服务器地址。
# 你必须首先使用您的操作系统的桥接能力来桥接TAP接口与以太网卡接口。
# 注意:此模式仅适用于客户端(例如Windows),其中客户端TAP适配器绑定到DHCP客户端。
;server-bridge
# 将路由推送到客户端,以允许它连接后面的其他私有子网服务器。
# 请记住,这些私有子网也需要知道如何路由到OpenVPN服务器
push "route 172.17.0.0 255.255.255.0"
#自动推送客户端上的网关及DHCP
;push "redirect-gateway def1 bypass-dhcp"
#OpenVPN的DHCP功能为客户端提供指定的 DNS、WINS 等
;push "dhcp-option DNS 114.114.114.114"
# 允许客户端与客户端相连接,默认情况下客户端只能与服务器相连接
client-to-client
# 是否允许同一用户同时开启多个客户端,默认仅允许一个
;duplicate-cn
# 每10秒ping一次,连接超时时间设为120秒
keepalive 10 120
# 加密认证算法 2.4以上版本,支持自动选择,注释掉即可
;cipher AES-256-CBC
# 使用lzo压缩的通讯,服务端和客户端都必须配置,默认值为 adaptive
comp-lzo
# 强化安全,额外证书配置
# 开启TLS-auth,使用ta.key防御攻击。服务器端的第二个参数值为0,客户端的为1。
**tls-auth /etc/openvpn/keys/ta.key 0**
# 最大连接用户
;max-clients 100
# 初始化后降级权限,定义运行的用户和组
;user openvpn
;group openvpn
# 尝试在重新启动时保留某些状态
persist-key
persist-tun
# 输出短日志,每分钟刷新一次,以显示当前的客户端
status openvpn-status.log
# 日志保存路径
log /var/openvpn/openvpn.log
# 指定日志文件的记录详细级别,可选0-9,等级越高日志内容越详细
verb 3
# 相同信息的数量,如果连续出现 20 条相同的信息,将不记录到日志中
;mute 20
# 显示退出通知
;explicit-exit-notify 1
===============================
2.1.4 启动openvpn服务端
# 方式1 命令行启动
/usr/local/sbin/openvpn --daemon --cd /etc/openvpn --config server.conf
# 方式2 配置开机启动文件
echo '# start openvpn' >> /etc/rc.local
echo '/usr/local/sbin/openvpn --daemon --askpass /etc/openvpn/askpass.txt --cd /etc/openvpn --config server.conf ' >> /etc/rc.local
2.1.5 使用账号户密码连接
1)修改server.conf配置文件,添加以下内容
script-security 3
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env
username-as-common-name
verify-client-cert none
2)在配置文件同级目录,放置checkpsw.sh 用户校验脚本、psw-file账号文件
在 checkpsw.sh文件中写入以下内容,完成后需要添加可执行权限 chmod +x checkpsw.sh
#!/bin/sh
###########################################################
# checkpsw.sh (C) 2004 Mathias Sundman
#
# This script will authenticate OpenVPN users against
# a plain text file. The passfile should simply contain
# one row per user with the username first followed by
# one or more space(s) or tab(s) and then the password.
PASSFILE="/etc/openvpn/psw-file"
LOG_FILE="/etc/openvpn/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
在psw-file文件中添加账号密码信息
vm 123456
test test
3)重启服务
pkill openvpn
/usr/local/sbin/openvpn --daemon --cd /etc/openvpn --config server.conf
4) 客户端配置
# 需保留服务端CA证书,
# 若服务端已配置verify-client-cert none 也可以注释掉证书
ca ca.crt
# 注释掉客户端相关证书
#cert client1.crt
#key client1.key
# 使用账户认证
auth-user-pass
# 可指定账号密码文件,文件格式 第一行为用户名,第二行为密码 注意权限-可以改为400
# auth-user-pass /etc/openvpn/psw-file
auth-nocache
##############################################
# 启动客户端 执行命令。输入账号密码
/usr/local/sbin/openvpn --daemon --cd /etc/openvpn --config server.conf
Enter Auth Username:test
Enter Auth Password:
2.2 客户端安装
2.2.1 软件安装
1)window安装
直接安装软件即可
注意:windows使用的配置文件后缀不是.conf 需要改成.ovpn
2)centos系统安装
#!/bin/bash
# 安装常用软件
echo "#### 安装常用软件 ntpdate tree net-tools tcpdump wget "
yum install -y ntpdate tree net-tools tcpdump wget
# 同步时间,并添加定时任务
# 确保服务器 Server 和 客户端 Client 的时间要正确,不然会导致后续证书验证不通过,无法建立连接。
echo '# time sync' >> /var/spool/cron/root
echo '*/5 * * * * ntpdate pool.ntp.org > /dev/null 2>&1' >> /var/spool/cron/root
crontab -l
# 加载内核模块
echo "#### 加载TUN内核模块"
modinfo tun
modprobe tun
lsmod | grep tun
# 安装基础环境
echo "#### 安装 gcc lzo openssl* pam-devel "
yum install -y gcc lzo-devel openssl-devel pam-devel
if [ $? -ne 0 ]; then
echo "install software package failed! "
exit 1
fi
# 安装openvpn
echo "#### openvpn-下载软件包"
cd ~ && wget <https://swupdate.openvpn.org/community/releases/openvpn-2.5.6.tar.gz>
echo "#### openvpn-解压"
tar zxf openvpn-2.5.6.tar.gz
echo "#### openvpn-删除压缩包"
rm -rf openvpn-2.5.6.tar.gz
cd openvpn-2.5.6
echo "#### openvpn-检测"
./configure
if [ $? -ne 0 ]; then
echo "openvpn configure failed! "
exit 1
fi
echo "#### openvpn-编译安装"
make && make install
if [ $? -ne 0 ]; then
echo "openvpn make or install failed! "
exit 1
fi
# 复制相关软件到/etc/openvpn
echo "#### 复制相关软件到/etc/openvpn"
mkdir -p /etc/openvpn && cd /etc/openvpn
cp -a ~/openvpn-2.5.6/sample/sample-config-files/client.conf /etc/openvpn/client.conf.bak
# 整理出一个简洁服务端配置文件,去掉空行和注释行
grep -vE "#|^$" /etc/openvpn/client.conf.bak >> /etc/openvpn/client.conf
# 开启转发
echo "#### 开启ipv4 IP转发"
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
防火墙处理
# 重新加载
firewall-cmd --reload
# 若接口未添加区域则执行添加语句,否则执行改变语句
# 持久化,添加参数 --permanent 最后重新加载即可
firewall-cmd --zone=public --add-interface=ens37
firewall-cmd --zone=internal --change-interface=ens37
firewall-cmd --zone=internal --list-all
启动openvpn客户端
# 方式1 命令行启动
/usr/local/sbin/openvpn --daemon --cd /etc/openvpn --config client.conf
# 方式2 配置开机启动文件
echo '# start openvpn' >> /etc/rc.local
echo '/usr/local/sbin/openvpn --daemon --cd /etc/openvpn --config client.conf ' >> /etc/rc.local
2.2.2 客户端配置
# 配置为客户端模式
client
# 指定创建的通信隧道类型,路由tun或桥接tap
dev tun
# 指定采用的传输协议,可以选择tcp或udp
proto udp
# vpn服务端地址 端口
# 可以配置多个负载均衡
remote 192.168.60.160 1194
# 从远程列表中随机选择一个主机进行负载平衡。否则按照指定的顺序尝试主机
;remote-random
# 无限重试
resolv-retry infinite
# 大多数客户端不需要绑定到特定的本地端口号
nobind
# 初始化后降级权限,定义运行的用户和组
;user nobody
;group nobody
# 尝试在重新启动时保留某些状态
persist-key
persist-tun
# 代理服务器设置
;http-proxy [proxy server] [proxy port #]
# 连接失败时重试
;http-proxy-retry # retry on connection failures
# 关闭重复报文警告
;mute-replay-warnings
# TLS证书相关路径
ca keys/ca.crt
cert keys/lclient.crt
key keys/lclient.key
# 验证服务器证书
remote-cert-tls server
# 如果在服务器上使用tls-auth密钥,那么每个客户端也必须有该密钥
tls-auth keys/ta.key 1
# 加密认证算法 2.4以上版本,支持自动选择,注释掉即可
;cipher AES-256-CBC
# 指定日志文件的记录详细级别,可选0-9,等级越高日志内容越详细
verb 3
# 相同信息的数量,如果连续出现 20 条相同的信息,将不记录到日志中
;mute 20
# 使用lzo压缩的通讯,服务端和客户端都必须配置,默认值为 adaptive **需手动添加**
comp-lzo
3. 常见问题
❓ certificate verify failed
这里主要是客户端和服务端的时间不一致造成的,首页此博文最开始就强调了时间的问题,如果时间不一致,需要调整好时间后重新生成证书才可以。
❓ OpenVPN Bad LZO decompression header byte: 69
客户端连接的时候,提示连接成功,但是会报这个错误然后卡住。这个主要是服务得的配置有 comp-lzo adaptive 这一行,客户端配置里没有, 所以需要在客户端配置文件 client.ovpn 里加上一行 comp-lzo ,此配置的默认值就是 adaptive
❓ explicit-exit-notify can only be used with --proto udp
explicit-exit-notify 1 #此选项开启只能使用udp协议。否则会报错error: --explicit-exit-notify can only be used with --proto udp
❓ 设置与子网络互通
详见案例分析
❓ 设置vpn代理
server.conf添加配置
push "redirect-gateway def1 bypass-dhcp bypass-dns"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
根据需要添加NAT
评论区