侧边栏壁纸
博主头像
叶落无痕

鸿雁长飞光不度,鱼龙潜跃水成文。

  • 累计撰写 11 篇文章
  • 累计创建 7 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

OpenVPN搭建

yeluo
2024-11-25 / 0 评论 / 0 点赞 / 21 阅读 / 0 字
温馨提示:
本文最后更新于2024-11-25,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

相关链接

官方文档

OpenVPN配置详解

深海游弋的鱼

OpenVPN win10客户端连接几个警告信息解决

使用easyrsa3来制作证书

openvpn2.3.12安装与easy-rsa3的使用

OpenVPN 设置非全局代理

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使用场景

  1. 企业员工远程办公,通过远程VPN连接到公司的服务器,访问公司ERP、OA等系统。IT技术人员通过VPN远程连接到机房进行系统维护。

  2. 总部与分支机构之间联通,打通分支与总部的连接

  3. 多IDC机房之间的互联,实现多机房之间的互联互通,数据共享,文件传送

  4. 内网穿透,没有公网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

4. 案例分析

0

评论区