ThankNeko's Blog ThankNeko's Blog
首页
  • 操作系统

    • Linux基础
    • Linux服务
    • WindowsServer笔记
    • Ansible笔记
    • Shell笔记
  • 容器服务

    • Docker笔记
    • Kubernetes笔记
    • Git笔记
  • 数据库服务

    • MySQL笔记
    • ELK笔记
    • Redis笔记
  • 监控服务

    • Zabbix笔记
  • Web服务

    • Nginx笔记
    • Tomcat笔记
  • 数据处理

    • Kettle笔记
  • Python笔记
  • Bootstrap笔记
  • C笔记
  • C++笔记
  • Arduino笔记
  • 分类
  • 标签
  • 归档
  • 随笔
  • 关于
GitHub (opens new window)

Hoshinozora

尽人事,听天命。
首页
  • 操作系统

    • Linux基础
    • Linux服务
    • WindowsServer笔记
    • Ansible笔记
    • Shell笔记
  • 容器服务

    • Docker笔记
    • Kubernetes笔记
    • Git笔记
  • 数据库服务

    • MySQL笔记
    • ELK笔记
    • Redis笔记
  • 监控服务

    • Zabbix笔记
  • Web服务

    • Nginx笔记
    • Tomcat笔记
  • 数据处理

    • Kettle笔记
  • Python笔记
  • Bootstrap笔记
  • C笔记
  • C++笔记
  • Arduino笔记
  • 分类
  • 标签
  • 归档
  • 随笔
  • 关于
GitHub (opens new window)
  • 操作系统

    • Linux基础

    • Linux服务

      • Rsync文件传输
      • Sersync实时同步
      • NFS文件服务
      • SSH远程连接
      • Keepalived高可用
      • Supervospr进程管理
      • APT包管理工具
      • Samba文件共享
      • JumpServer堡垒机
      • Linux搭建DNS服务
      • Tmux终端管理
      • Iptables
      • Firewalld防火墙管理
      • OpenVPN代理
        • 介绍
          • 特点
          • 工作机制
          • 部署
        • 命令参数
          • 通用选项
          • TLS模式选项
          • 对端状态检测与处理选项
        • 配置文件格式
          • 格式
          • 例子
        • 点对点配置
          • 介绍
          • 实验环境
          • 实现方法
        • 静态秘钥模式
          • 介绍
          • 实现方法
        • 站点到站点配置
          • 介绍
          • 实验环境
          • 实现方法
        • TLS秘钥协商模式
        • 客户端到服务端配置
          • 实现方法
          • 访问VPN后面资源方法
          • 服务端充当路由配置
          • 服务端NAT配置
          • 配置客户端密码认证
      • 本地yum仓库搭建
    • Windows Server笔记

    • Shell笔记

    • Ansible笔记

  • 虚拟化服务

  • 数据库服务

  • 监控服务

  • Web服务

  • 数据处理

  • Ops
  • 操作系统
  • Linux服务
Hoshinozora
2024-01-04
目录

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
1
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

# --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 同等于以下配置:

image-20240104135441200

# --client

  • --client - 将OpenVPN配置为客户端模式。
  • 它也是一个辅助指令,同等于pull和tls-client参数。

# --push

  • --push "option" - 用于服务端向客户端推送一个选项,选项的内容要放置在双引号内,同时可以使用方括号引用服务器配置的值。客户端必须指定--pull选项。

  • 例如:push "route 10.200.0.0 255.255.255.0"、push "topology [topology]"。

  • 当前可被推送的选项有:

image-20240104135730021

# --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之后多少秒没有收到回应,则表示对方已断开。

# 配置文件格式

# 格式

  1. 配置文件中的选项没有"--"。
  2. 配置文件可嵌套。
  3. 行首的"#"或";"字符表示注释行。
  4. 包含空格的参数,要用双引号或单引号包裹。
  5. 非单引号的反斜杠""会被当做Shell的转义字符。
  6. 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
1
2
3
4
5
6
7
8
9
10

# 点对点配置

# 介绍

点对点VPN就是在同一时刻,只能有一个客户端可以连接VPN服务器。

它的优点是配置简单容易,不需要证书、公钥基础设施等。缺点是无前向保密,始终使用一个密钥,且密钥是以明文的形式存储在每个VPN节点上的。

# 实验环境

image-20240103212453286

  • OpenVPN服务端:192.168.10.4/24

  • OpenVPN客户端:192.168.10.11/24

  • 隧道两端的IP地址规划为:

    • Server: 10.200.0.1
    • Client: 10.200.0.2

# 实现方法

服务端

  • 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)

# 实现方法

  1. 生成静态秘钥文件。

    • openvpn --genkey --secret [密钥文件保存路径]
    • 例如:openvpn --genkey --secret secret.key
  2. 将该秘钥文件分发到各端,建议使用SCP或STFP等方式,传输方式尽量做到安全。

  3. 客户端和服务端启动时通过**--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通过点对点的方式连接起来。

# 实验环境

image-20240104165721120

# 实现方法

# 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
1
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
1
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
1
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# CA PKI目录结构

image-20240104185538834

# VPN服务端/客户端申请证书

# 申请流程
  1. 在VPN服务器生成一个密钥对 (私有秘钥、公共密钥)。
  2. VPN服务器将它的公共密钥发送给CA服务器。
  3. CA服务器将VPN1发送过来的公共密钥,加上一些用CA服务器私有密钥加密的额外的信息(签名操作),最终生成VPN1的证书。
  4. 然后CA服务器将CA证书和VPN的证书发送给VPN。
# 申请操作
  1. 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  • Req PKI目录结构 image-20240104192056203
  1. 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/
1
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
1
2
3
4
5
6
7
8

# 客户端到服务端配置

# 实现方法

  1. 各端上面要有密钥、证书等文件。

  2. 创建配置文件。

    • 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
  3. 最后运行OpenVPN服务端,然后再运行客户端即可。

# 访问VPN后面资源方法

image-20240104192940505

# 服务端充当路由配置

# 介绍

  • 客户端访问服务端后面的资源,要通过服务端,也就是访问资源内网段要配置路由到服务端。
  • 服务器端和客户端都需要知道各个网络如何走,我们可以直接通过OpenVPN的push参数告诉客户端如何走。

# 实验环境

image-20240104193452701

# 实现方法

  1. 服务器配置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
1
2
3
4
5
6
7
8
9
  1. 配置文件配置路由。

    • 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转发。

# 实验环境

image-20240104193825827

# 实现方法

  1. 服务端操作
# 服务器配置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
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
26
27
28
29
30
31
32
33
34
35
36
37
38
  1. 客户端配置
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

# 验证方法

  1. 客户端ping业务主机
  2. 后端业务主机通过抓包进行验证tcpdump -i [网卡名] icmp -n,如果业务主机抓到的包的源地址是VPN在网段中的地址,则表示NAT转发是正常的。

# 配置客户端密码认证

# 服务端

  1. 创建密码认证文件存放目录。
mkdir -p /etc/openvpn/auth
1
  1. 创建密码认证脚本。
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
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
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
  1. 创建密码文件。
vim /etc/openvpn/auth/password
格式:一行对应一个用户
用户名01 密码
用户名02 密码
... ...

例如:
zhangsan qwe123123
lisi qwe123456
1
2
3
4
5
6
7
8
9
  1. 认证脚本与密码文件权限配置。
# 认证脚本添加执行权限
chmod +x /etc/openvpn/auth/checkpsw.sh

# 密码文件修改权限以保证安全
chown nobody.nobody /etc/openvpn/auth/password
chmod 400 /etc/openvpn/auth/password
1
2
3
4
5
6
  1. 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
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
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
1
2
3
4
5
6
7
8
9
10
11
12
13
#Linux#代理服务#OpenVPN
Firewalld防火墙管理
本地yum仓库搭建

← Firewalld防火墙管理 本地yum仓库搭建→

最近更新
01
二〇二五年四月十七日随笔
04-17
02
二〇二五年四月十六日随笔
04-16
03
二〇二五年四月九日随笔
04-09
更多文章>
Theme by Vdoing | Copyright © 2022-2025 Hoshinozora | MIT License
湘ICP备2022022820号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式