企业级openvpn搭建

2023-05-19 17:36:41 浏览数 (1)

# 企业级openvpn搭建

OpenVPN是一个用于创建虚拟专用网络加密通道的软件包,最早由James Yonan编写。OpenVPN允许创建的VPN使用公开密钥、电子证书、或者用户名/密码来进行身份验证。 它大量使用了OpenSSL加密库中的SSLv3/TLSv1协议函数库。 目前OpenVPN能在Solaris、Linux、OpenBSD、FreeBSD、NetBSD、Mac OS X与Microsoft Windows以及Android、iOS、MacOS(2020年官方推出Mac客户端)上运行,并包含了许多安全性的功能。它并不是一个基于Web的VPN软件,也不与IPsec及其他VPN软 OpenVPN2.0后引入了用户名/口令组合的身份验证方式,它可以省略客户端证书,但是仍有一份服务器证书需要被用作加密。 OpenVPN所有的通信都基于一个单一的IP端口, 默认且推荐使用UDP协议通讯,同时TCP也被支持。OpenVPN连接能通过大多数的代理服务器,并且能够在NAT的环境中很好地工作。服务端具有向客 户端“推送”某些网络配置信息的功能,这些信息包括:IP地址、路由设置等。 OpenVPN提供了两种虚拟网络接口:通用Tun/Tap驱动,通过它们, 可以建立三层IP隧道,或者虚拟二层以太网,后者可以传送任何类型的二层以太网络数据。传送的数据可通过LZO算法压缩。在选择协议时候,需要注意2个加密隧道之间的网络状况,如有高延迟或者丢包较多的情况下,请选择TCP协议作为底层协议,UDP协议由于存在无连接和重传机制,导致要隧道上层的协议进行重传,效率非常低下。 VPN的主要作用是在局域网外部时也可以访问局域网的资源,比如公司内网有许多资源只能公司内网访问,而我们外派出差员工还想访问公司内网资源[如:GitLab/测试库/其他测试环境接口]就需要通过连接公司公网出口暴露VPN来实现。 由于众所周知的原因,几种简单的VPN协议比如L2TP/IPsec和PPTP协议在大陆地区已经被干扰的基本无法正常使用了。因此也就SSL VPN还可以使用。SSL VPN有非常多种,但很多都是商业软件,不开源也不适合个人搭建。而OpenVPN是一款开源的SSL VPN,可以很容易找到搭建的方法,非常符合我们的要求。

# 基于账号密码的搭建

# 安装依赖
代码语言:javascript复制
yum install -y openssl openssl-devel lzo lzo-devel pam pam-devel automake pkgconfig gcc gcc-c  
# 安装目录
代码语言:javascript复制
mkdir /opt/apps
# 安装easy-rsa并生成相关证书

easy-rsa 下载地址:https://codeload.github.com/OpenVPN/easy-rsa-old/zip/master

代码语言:javascript复制
unzip easy-rsa-old-master.zip
[root@host-172-16-30-22 easy-rsa-old-master]# ls
configure.ac  COPYING  COPYRIGHT.GPL  distro  doc  easy-rsa  Makefile.am
# 生成相关证书
代码语言:javascript复制
[root@host-172-16-30-22 2.0]# cd /opt/apps/easy-rsa-old-master/easy-rsa/2.0
# 准备openssl相关文件
代码语言:javascript复制
ln -s openssl-1.0.0.cnf openssl.cnf
# 编辑证书基本信息
代码语言:javascript复制
[root@host-172-16-30-22 2.0]# pwd
/opt/apps/easy-rsa-old-master/easy-rsa/2.0
vim vars
export KEY_COUNTRY="CN"
export KEY_PROVINCE="sz"
export KEY_CITY="shenzhen"
export KEY_ORG="1quant"
export KEY_EMAIL="xxx@1quant.com"
. vars #生效环境变量
# 生成服务器端秘钥
代码语言:javascript复制
./build-key-server server
# 生成客户端证书
代码语言:javascript复制
./build-key client
# 创建迪菲·赫尔曼密钥
代码语言:javascript复制
./build-dh
# 查看生成的所有证书
代码语言:javascript复制
[root@host-172-16-30-22 keys]# ls
01.pem  ca.crt  client.crt  client.key  index.txt       index.txt.attr.old  serial      server.crt  server.key
02.pem  ca.key  client.csr  dh2048.pem  index.txt.attr  index.txt.old       serial.old  server.csr  ta.key
# 安装openvpn

下载地址:https://openvpn.net/community-downloads/

代码语言:javascript复制
 tar -xf openvpn-2.5.8.tar.gz
 cd /opt/apps/openvpn-2.5.8
 ./configure --prefix=/opt/apps/openvpn && make && make install
 [root@host-172-16-30-22 apps]# ll
total 1904
drwxr-xr-x  5 root  root     4096 Jan 23  2018 easy-rsa-old-master
-rw-------  1 root  root    59661 Dec 27 12:30 easy-rsa-old-master-1.zip
drwxr-xr-x  7 root  root     4096 Dec 27 14:37 openvpn
drwxrwxr-x 12 admin admin    4096 Dec 27 14:02 openvpn-2.5.8
-rw-------  1 root  root  1875551 Dec 27 11:37 openvpn-2.5.8.tar.gz
# 配置openvpn
代码语言:javascript复制
配置 OpenVPN 服务端
创建配置文件目录和证书目录:
mkdir -p /etc/openvpn        # openvpn 配置文件路径
mkdir -p /etc/openvpn/pki    # openvpn 证书存放位置
# 生成ta.key文件(防DDos攻击、udp淹没等恶意攻击)
代码语言:javascript复制
cd /opt/apps/easy-rsa-old-master/easy-rsa/2.0/keys
/opt/apps/openvpn/sbin/openvpn --genkey --secret ta.key
# 将签名生成的CA证书秘钥和服务端证书秘钥拷贝到证书目录中
代码语言:javascript复制
cp {ca.crt,ca.key,dh2048.pem,server.crt,server.key,ta.key} /etc/openvpn/pki/
[root@host-172-16-30-22 pki]# ll
total 32
-rw-r--r-- 1 root root 2419 Dec 27 14:15 ca.crt
-rw------- 1 root root 3268 Dec 27 14:15 ca.key
-rw-r--r-- 1 root root  424 Dec 27 14:15 dh2048.pem
-rw-r--r-- 1 root root 8203 Dec 27 14:15 server.crt
-rw------- 1 root root 3272 Dec 27 14:15 server.key
-rw------- 1 root root  636 Dec 27 14:15 ta.key
# 拷贝配置文件模板
代码语言:javascript复制
cp openvpn-2.5.8/sample/sample-config-files/server.conf /etc/openvpn/
# 拷贝配置文件模板
代码语言:javascript复制
cp openvpn-2.5.8/sample/sample-config-files/server.conf /etc/openvpn
# 编辑openvpn配置文件
代码语言:javascript复制
local 0.0.0.0
port 8888
proto tcp
dev tun
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/server.crt
key /etc/openvpn/pki/server.key  # This file should be kept secret
dh /etc/openvpn/pki/dh2048.pem
server 10.8.0.0 255.255.255.0
push "dhcp-option DNS 114.114.114.114"
push "dhcp-option DNS 8.8.8.8"
push "route 172.16.30.0 255.255.255.0"
push "route 172.16.60.253 255.255.255.0"
ifconfig-pool-persist ipp.txt
client-to-client
keepalive 10 120
tls-auth /etc/openvpn/pki/ta.key 0 # This file is secret
cipher AES-256-CBC
comp-lzo
user nobody
group nobody
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env
script-security 3
verify-client-cert none
username-as-common-name
persist-key
persist-tun
status /var/log/openvpn-status.log
log         /var/log/openvpn.log
log-append  /var/log/openvpn.log
verb 3
# centos7添加防火墙方式访问内部网络
代码语言:javascript复制
#在服务端开启防火墙,放行openvpn服务,并且开启masquerade。
#优点:只需在OpenVPN服务端配置防火墙规则,内部网络主机无需配置
systemctl start firewalld
firewall-cmd --add-masquerade --permanent
firewall-cmd --add-service=openvpn --permanent
firewall-cmd --reload
# iptables配置防火墙方式访问内部网络
代码语言:javascript复制
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE
也可以这样做:添加 iptables 转发规则,对所有源地址(openvpn为客户端分配的地址)为 10.10.10.0/24 的数据包转发后进行源地址转换,伪装成 openvpn 服务器内网地址 x.x.x.x, 这样 VPN 客户端就可以访问服务器内网的其他机器了。

iptables -A POSTROUTING -s 10.10.10.0/24 -j SNAT --to-source 192.168.1.160
iptables -I INPUT -p tcp -m tcp --dport 8888 -j ACCEPT
# 上传密码验证脚本
代码语言:javascript复制
[root@host-172-16-30-22 openvpn]# ll
total 28
-rwxr-xr-x 1 root root   901 Dec 27 14:36 checkpsw.sh
-rw------- 1 root root     0 Dec 27 14:40 ipp.txt
drwxr-xr-x 2 root root  4096 Dec 27 14:15 pki
-rw-r--r-- 1 root root    22 Dec 27 14:37 psw-file
-rw-r--r-- 1 root root   807 Dec 28 11:42 server.conf
cat checkpsw.sh
#!/bin/sh
###########################################################
PASSFILE="/etc/openvpn/psw-file"
LOG_FILE="/opt/apps/openvpn/logs/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
# 配置systemd启动脚本
代码语言:javascript复制
[root@host-172-16-30-22 openvpn]# cat /usr/lib/systemd/system/openvpn.service
[Unit]
Description=openvpn
After=network.target
[Service]
EnvironmentFile=-/etc/openvpn/openvpn
ExecStart=/opt/apps/openvpn/sbin/openvpn --config /etc/openvpn/server.conf
Restart=on-failure
Type=simple
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
代码语言:javascript复制
[root@host-172-16-30-22 openvpn]# systemctl status openvpn
● openvpn.service - openvpn
   Loaded: loaded (/usr/lib/systemd/system/openvpn.service; disabled; vendor preset: disabled)
   Active: active (running) since Wed 2022-12-28 11:43:13 CST; 6min ago
 Main PID: 10319 (openvpn)
    Tasks: 1
   Memory: 1004.0K
   CGroup: /system.slice/openvpn.service
           └─10319 /opt/apps/openvpn/sbin/openvpn --config /etc/openvpn/server.conf

Dec 28 11:43:13 host-172-16-30-22 systemd[1]: Stopped openvpn.
Dec 28 11:43:13 host-172-16-30-22 systemd[1]: Started openvpn.
Dec 28 11:43:13 host-172-16-30-22 openvpn[10319]: 2022-12-28 11:43:13 WARNING: Compression for receiving enabled. Compression has been used in the past to break encryption. Sent packets are not compressed unless "allow-comp...yes" is also set.
Hint: Some lines were ellipsized, use -l to show in full.
[root@host-172-16-30-22 openvpn]# netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      911/sshd            
tcp        0      0 0.0.0.0:8888            0.0.0.0:*               LISTEN      10319/openvpn       
tcp6       0      0 :::22                   :::*                    LISTEN      911/sshd            
udp        0      0 0.0.0.0:68              0.0.0.0:*                           593/dhclient
# 开启内核路由转发功能
代码语言:javascript复制
vim /etc/sysctl.conf
添加如下内容
net.ipv4.ip_forward = 1
sysctl -p
# 安装openvpn客户端

windows和linux下载地址:https://openvpn.net/community-downloads/

  1. 安装成功后,打开应用,选择导入配置、导入client.ovpn文件
  2. 导入成功后,选择连接即可

macos安装包:Tunnelblick_3.7.8_build_5180.dmg

  1. 下载安装MacOS客户端 https://tunnelblick.net/downloads.html 选择Stable稳定版 Tunnelblick 3.7.8
  2. 安装成功后 双击client.ovpn(附件)
  3. 选择连接client 弹窗显示connected 则连接成功

Android系统 安装包:openvpn-connect-3-0-5.apk

  1. 下载安装客户端 https://openvpn-connect.en.uptodown.com/android 选择最新版本
  2. 安装成功后、点击client.ovpn, 选择使用openVPN connect 打开
  3. 进入app, 点击连接即可

ios客户端

1.国内app store屏蔽了openvpn client,暂时不支持

2.国外app store下载后导入openvpn client即可

# 客户端配置

windows客户端配置

代码语言:javascript复制
client
dev tun
proto tcp
remote 220.231.216.147 8888
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
tls-auth ta.key 1
cipher AES-256-CBC
comp-lzo
verb 3
auth-user-pass

app端配置

注意:APP端配置在windwos主机配置要注意文件格式,不然会报错line is too long

代码语言:javascript复制
client
dev tun
proto tcp
remote 220.231.216.147 8888 tcp-client
resolv-retry infinite
nobind
persist-key
persist-tun
cipher AES-256-CBC
comp-lzo
verb 3
<ca>
-----BEGIN CERTIFICATE-----
xxx
-----END CERTIFICATE-----

</ca>

key-direction 1

<tls-auth>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
xxxx
-----END OpenVPN Static key V1-----

</tls-auth>
auth-user-pass

0 人点赞