背景:
在现代企业中,跨地区的办公室和数据中心之间的互联互通是非常常见的需求。企业可能拥有多个分支机构、数据中心(IDC),这些地点需要通过可靠的网络连接进行数据传输、资源共享和远程管理。传统上,企业可能会选择租用专线来连接不同地点的网络,但这种方式成本较高且实施复杂。为了在保持安全性和可靠性的同时降低成本,越来越多的企业选择使用 VPN(虚拟专用网络)技术,而 OpenVPN 是其中一种广受欢迎的解决方案。
OpenVPN 是一个开源的 VPN 解决方案,通过创建加密的隧道,确保不同网络之间的通信安全无虞。这种加密隧道不仅能有效保护数据传输,还能让不同地理位置的网络看起来像是在同一个局域网(LAN)内。这对于需要跨地域进行数据共享、资源访问和远程管理的企业来说,是一个非常实用的工具。
常见应用场景
- 分支机构与总部的网络互通:
分支机构的数据需要实时传输到总部进行处理。例如,一个公司在北京设有总部,在上海设有分支机构,北京的服务器需要实时接收和处理来自上海的业务数据。
- 办公室与 IDC 机房的网络互通:
IT 运维或技术人员需要从办公室远程管理位于 IDC 机房的服务器。此外,IDC 内的服务器也可能需要访问办公室内网中的资源。例如,运维团队在北京的办公室,而服务器部署在上海的 IDC 机房中,通过 OpenVPN,可以让他们轻松远程管理这些服务器。
- 不同 IDC 机房之间的网络互通:
两个数据中心之间可能需要同步数据或共享资源。例如,一个企业在北京和上海都拥有数据中心,为了确保数据的高可用性和安全性,他们需要在两个数据中心之间建立一个加密的连接,确保数据能够在两个 IDC 之间安全传输。
我们使用的场景
我们北京和深圳各有分部,但是由于网络原因,导致两边的资源不互通,经常做一些事情效率底下。现在进行网络调整优化,北京可以访问深圳网络,深圳可以访问北京网络,这样网络打通,资源共享方便,有助于提高工作效率和流程办事速度。
为什么选择 OpenVPN
- 安全性: OpenVPN 使用 SSL/TLS 协议进行加密,能够提供高水平的安全性,防止数据在传输过程中被窃取或篡改。
- 成本效益: 与租用专线相比,使用 OpenVPN 可以大幅降低企业的网络连接成本。
- 灵活性: OpenVPN 支持多种网络架构和配置,能够适应企业的多样化需求。不论是通过互联网连接不同地点,还是在复杂的网络环境下建立多点连接,OpenVPN 都能轻松应对。
- 跨平台支持: OpenVPN 兼容多种操作系统,包括 Windows、Linux、macOS 以及各种移动设备,确保企业能够在不同的平台上实现无缝连接
北京和深圳两边网络双向互通流程
环境配置
| 主机 | ip | 用途 | 
| openvpn服务端(深圳) | 172.17.10.20 | openvpn-server | 
| openvpn-server网段机器(深圳办公区域) | 172.17.10.21 | server同一网段机器 | 
| openvpn客户端(北京) | 172.17.20.20 | openvpn-client | 
| openvpn-client网段机器(北京办公区域) | 172.17.20.21 | client同一网段机器 | 
| 虚拟IP | 10.10.10.0/24 | openvpn的虚拟IP | 
部署流程

安装openvpn、easy-rsa、iptables-server
| 1
2
 | yum install epel-* -y
yum -y install openvpn easy-rsa iptables-services
 | 
 
生成证书及相关文件
利用easy-rsa生成相关证书文件
CA根证书
openvpn服务器证书
Diffie-Hellman算法用到的key 复制easy-rsa脚本到/etc/openvpn下面,该脚本是用来生成CA证书和各种key文件
复制easy-rsa脚本到/etc/openvpn下面,该脚本是用来生成CA证书和各种key文件
| 1
 | cp -r /usr/share/easy-rsa/ /etc/openvpn/
 | 
 
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
 | [root@openvpn openvpn]# cd /etc/openvpn/easy-rsa/3.0.8/
[root@openvpn 3.0.8]# ls
easyrsa  openssl-easyrsa.cnf    vars  x509-types
#新建vars文件,编辑变量,初始化
[root@openvpn 3.0.8]# vim vars 
export KEY_COUNTRY="CN"
export KEY_PROVINCE="ShangHai"
export KEY_CITY="ShangHai"
export KEY_ORG="YCZB"
export KEY_EMAIL="heian@heian.com"
[root@openvpn 3.0.8]# source ./vars
 | 
 
生成CA根证书
| 1
2
3
 | #初始化 pki 相关目录
./easyrsa init-pki
 | 
 
生成 CA 根证书, 输入 Common Name,名字随便起。
| 1
2
 | ./easyrsa build-ca nopass 
这个命令是不生成密码
 | 
 
生成openvpn服务器证书和密钥,第一个参数是证书名称
| 1
 | ./easyrsa build-server-full server nopass
 | 
 
生成Diffie-Hellman算法需要的密钥文件
| 1
 | /easyrsa gen-dh   #创建 Diffie-Hellman ,时间比较久一些
 | 
 
生成tls-auth key,为了防止DDOS和TLS攻击,这个属于可选安全配置
| 1
 | openvpn --genkey --secret ta.key
 | 
 
openvpn文件整理
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
 | mkdir /etc/openvpn/server/certs 
cd /etc/openvpn/server/certs/
# SSL 协商时 Diffie-Hellman 算法需要的 key
cp /etc/openvpn/easy-rsa/3/pki/dh.pem ./  
# CA 根证书
cp /etc/openvpn/easy-rsa/3/pki/ca.crt ./  
# open VPN 服务器证书
cp /etc/openvpn/easy-rsa/3/pki/issued/yczbjt.crt ./server.crt 
# open VPN 服务器证书 key
cp /etc/openvpn/easy-rsa/3/pki/private/yczbjt.key ./server.key 
# tls-auth key
cp /etc/openvpn/easy-rsa/3/ta.key ./  
-----------------------------------
 | 
 
创建openvpn日志目录
| 1
2
3
4
5
 | [root@openvpnservice certs]# /etc/openvpn/cdd
#创建日志目录
[root@openvpnservice certs]# mkdir -p /var/log/openvpn/
#给予权限
[root@openvpnservice certs]# chown openvpn:openvpn /var/log/openvpn
 | 
 
配置OpenVPN
深圳服务端配置
|  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
 | port 1194
proto udp
dev tun
ca /etc/openvpn/server/certs/ca.crt
cert /etc/openvpn/server/certs/server.crt
key /etc/openvpn/server/certs/server.key
dh /etc/openvpn/server/certs/dh.pem
tls-auth /etc/openvpn/server/certs/ta.key 0
server 10.10.10.0 255.255.255.0
route 172.17.20.0 255.255.255.0
push "route 172.17.10.0 255.255.255.0"
ifconfig-pool-persist ipp.txt
client-to-client
compress lzo
keepalive 10 120
client-config-dir /etc/openvpn/ccd
cipher AES-256-CBC
comp-lzo
persist-key
persist-tun
log /var/log/openvpn/server.log
log-append /var/log/openvpn/server.log
status /var/log/openvpn/status.log
verb 3
explicit-exit-notify 1
script-security 2
client-connect /etc/openvpn/script/connect.sh
client-disconnect /etc/openvpn/script/disconnect.sh
 | 
 
connect.sh
| 1
2
3
4
5
6
7
8
9
 | #!/bin/bash
Time=`date +%F`
if [ -f /etc/openvpn/log/openvpn_$Time.log ];then
  touch /etc/openvpn/log/openvpn_$Time.log
  echo "`date '+%F %H:%M:%S'` User $common_name trust_ip $trusted_ip is login,Remote_ip is $ifconfig_pool_remote_ip, Mask is $route_netmask_1" >> /etc/openvpn/log/openvpn_$Time.log
else
  touch /etc/openvpn/log/openvpn_$Time.log
  echo "`date '+%F %H:%M:%S'` User $common_name trust_ip $trusted_ip is login,Remote_ip is $ifconfig_pool_remote_ip, Mask is $route_netmask_1" >> /etc/openvpn/log/openvpn_$Time.log
fi
 | 
 
disconnect.sh
| 1
2
3
4
5
6
7
8
9
 | #!/bin/bash
Time=`date +%F`
if [ -f /etc/openvpn/log/openvpn_$Time.log ];then
  touch /etc/openvpn/log/openvpn_$Time.log
  echo "`date '+%F %H:%M:%S'` User $common_name trust_ip $trusted_ip is logout,Remote_ip is $ifconfig_pool_remote_ip, Mask is $route_netmask_1" >> /etc/openvpn/log/openvpn_$Time.log
  else
  touch /etc/openvpn/log/openvpn_$Time.log
  echo "`date '+%F %H:%M:%S'` User $common_name trust_ip $trusted_ip is logout,Remote_ip is $ifconfig_pool_remote_ip, Mask is $route_netmask_1" >> /etc/openvpn/log/openvpn_$Time.log
fi
 | 
 
开启路由转发
| 1
2
 |  echo net.ipv4.ip_forward = 1 >>/etc/sysctl.conf
 sysctl -p
 | 
 
添加IPtables
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
 | [root@bt script]# cat /etc/sysconfig/iptables
# Generated by iptables-save v1.4.21 on Sun Jun 26 10:24:16 2022
*filter
:INPUT ACCEPT [1248:200636]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [2012:242515]
-A FORWARD -j ACCEPT
COMMIT
# Completed on Sun Jun 26 10:24:16 2022
# Generated by iptables-save v1.4.21 on Sun Jun 26 10:24:16 2022
*nat
:PREROUTING ACCEPT [2:162]
:INPUT ACCEPT [1:78]
:OUTPUT ACCEPT [271:36649]
:POSTROUTING ACCEPT [72:5056]
-A POSTROUTING -s 172.17.10.0/24 -j MASQUERADE
-A POSTROUTING -s 10.10.10.0/24 -o ens33 -j SNAT --to-source 172.17.10.20
COMMIT
# Completed on Sun Jun 26 10:24:16 2022
 | 
 
这是一些iptables规则,用于网络地址转换(NAT)和IP数据包过滤。这些规则可能在Linux操作系统上的iptables防火墙中使用。
第一个规则的意思是将来自172.17.10.0/24子网中的数据包的源地址改为防火墙的IP地址,以便将数据包传递到互联网,并确保响应数据包可以正确返回。使用MASQUERADE选项的目的是自动根据防火墙的出口IP地址进行地址转换。
第二个规则的意思是将来自10.10.10.0/24子网的数据包的源IP地址改为172.17.10.20,并在防火墙的网络接口(ens33)上发送。这个规则可能会用于特殊情况,例如需要使用特定的IP地址来绕过某些防火墙或网络限制。
加载防火墙
| 1
 | iptables-restore > /etc/sysconfig/iptables
 | 
 

ccd
| 1
2
3
 | [root@bt openvpn]# cat ccd/fujinfu 
iroute 172.17.20.0 255.255.255.0
配置客户端推送的路由
 | 
 
添加客户端用户配置文件
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
 | [root@openvpnservice ~]# cd /etc/openvpn/client/
[root@openvpnservice client]# touch sample.ovpn
[root@openvpnservice client]# vim sample.ovpn
client
proto udp
dev tun
remote 49.234.26.34 1194  #openvpn公网映射的ip地址和端口
ca ca.crt
cert admin.crt
key admin.key
tls-auth ta.key 1
remote-cert-tls server
persist-tun
persist-key
comp-lzo
verb 3
mute-replay-warnings
 | 
 
创建用户脚本
|  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
 | yum install -y zip,unzip
[root@bt client]# cat bash_openuser.sh 
# ! /bin/bash
set -e
OVPN_USER_KEYS_DIR=/etc/openvpn/client/keys
EASY_RSA_VERSION=3
EASY_RSA_DIR=/etc/openvpn/easy-rsa/
PKI_DIR=$EASY_RSA_DIR/$EASY_RSA_VERSION/pki
for user in "$@"
do
  if [ -d "$OVPN_USER_KEYS_DIR/$user" ]; then
    rm -rf $OVPN_USER_KEYS_DIR/$user
    rm -rf  $PKI_DIR/reqs/$user.req
    sed -i '/'"$user"'/d' $PKI_DIR/index.txt
  fi
  cd $EASY_RSA_DIR/$EASY_RSA_VERSION
  # 生成客户端 ssl 证书文件
  ./easyrsa build-client-full $user nopass
  # 整理下生成的文件
  mkdir -p  $OVPN_USER_KEYS_DIR/$user
  cp $PKI_DIR/ca.crt $OVPN_USER_KEYS_DIR/$user/   # CA 根证书
  cp $PKI_DIR/issued/$user.crt $OVPN_USER_KEYS_DIR/$user/   # 客户端证书
  cp $PKI_DIR/private/$user.key $OVPN_USER_KEYS_DIR/$user/  # 客户端证书密钥
  cp /etc/openvpn/client/sample.ovpn $OVPN_USER_KEYS_DIR/$user/$user.ovpn # 客户端配置文件
  sed -i 's/admin/'"$user"'/g' $OVPN_USER_KEYS_DIR/$user/$user.ovpn
  cp /etc/openvpn/server/certs/ta.key $OVPN_USER_KEYS_DIR/$user/ta.key  # auth-tls 文件
  cd $OVPN_USER_KEYS_DIR
  zip -r $user.zip $user
done
exit 0
 | 
 
北京客户端配置

iptables设置
开启转发路由
| 1
2
3
4
5
6
7
 | systemctl stop firewalld
systemctl mask firewalld
setenforce 0				# 临时关闭
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
echo net.ipv4.ip_forward = 1 >>/etc/sysctl.conf
sysctl -p
 | 
 
根据下图设置IPtables的规则
| 1
2
3
4
5
6
7
8
 | vim  /etc/sysconfig/iptables
-A POSTROUTING -s 172.17.20.0/24 -j MASQUERADE
-A POSTROUTING -s 10.10.10.0/24 -o ens33 -j SNAT --to-source 172.17.20.20
加载防火墙
iptables-restore > /etc/sysconfig/iptables
 | 
 

交换机配置
深圳访问北京的机器
| 1
 | route add -net 172.17.20.0/24 gw 172.17.10.20
 | 
 
如果使用的是华为交换机(Huawei),命令则如下:
| 1
 | ip route-static 172.17.20.0 255.255.255.0 172.17.10.20
 | 
 
请根据具体使用的交换机型号和品牌,选择相应的命令格式。
北京机器访问深圳段的机器
| 1
 | route add -net 172.17.10.0/24 gw 172.17.20.20
 | 
 
如果使用的是华为交换机(Huawei),命令则如下:
| 1
 | ip route-static 172.17.10.0 255.255.255.0 172.17.20.20
 | 
 
上面是临时加到机器上,我们应该加到交换机上,这样整个网段都可以访问
在实际的环境中可以在内网的路由器上做,这样就不需要在主机上配,比较省事.
参考文档:
https://ownit.top/p/202407290930/
https://www.cnblogs.com/huangweimin/articles/7700892.html