1. 环境

1.1 硬件和网络拓扑

网络拓扑

  • OpenVPN Server:双网卡机器,同时连接大小网,提供 VPN 拨号服务。

  • OpenVPN Client:位于大网,通过拨号,获得小网地址后,可以和小网 PC 互相访问。

  • 小网 PC:位于小网(如 192.168 网段)

    注意:以下 OpenVPN Server 网络配置相关信息仅供参考,并非真实信息。

    IP1:10.185.80.57 子网掩码1:255.255.254.0
    IP2:192.168.18.6 子网掩码2:255.255.240.0

1.2 软件要求

操作系统:Centos 7
第三方包:所有软件包均通过 yum 在线安装

2.安装配置 OpenVPN 服务端

2.1 配置 yum 源

由于 rpm 包安装需要的依赖关系可能比较繁杂,这里选用 yum 在线安装。

2.1.1 配置 Centos 源

打开 Centos 清华镜像源 ,选择 Centos 7 配置文件,直接使用如下内容覆盖掉/etc/yum.repos.d/CentOS-Base.repo文件:

[base]
name=CentOS-$releasever - Base
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/os/$basearch/
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-7

#released updates
[updates]
name=CentOS-$releasever - Updates
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/updates/$basearch/
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-7

#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/extras/$basearch/
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-7

#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/centosplus/$basearch/
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-7

然后缓存元数据。

yum makecache

2.1.2 配置 EPEL 源

openvpn 在 EPEL 仓库中,所以需要配置 EPEL 源。这里参考清华镜像源epel帮助,在/etc/yum.repos.d目录下增加“epel.repo”文件,内容如下:

[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/$basearch
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7

[epel-debuginfo]
name=Extra Packages for Enterprise Linux 7 - $basearch - Debug
baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/$basearch/debug
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-7&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=1

[epel-source]
name=Extra Packages for Enterprise Linux 7 - $basearch - Source
baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/SRPMS
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-7&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=1

然后执行下面的命令,缓存元数据。

yum makecache

2.2 安装相关软件包

执行如下命令,一次性完成安装

yum -y install lzo openssl easy-rsa openvpn

安装后,easy-rsa 的相关文件存放于/usr/share/easy-rsa/3.0.3/usr/share/doc/easy-rsa-3.0.3两个路径下,需要把 easy-rsa 的相关文件放到一个目录,以便后面的操作, 这里我放到/root/EasyRSA-3.0.3/目录。操作如下

mkdir /root/EasyRSA-3.0.3
cp -a /usr/share/easy-rsa/3.0.3/* /root/EasyRSA-3.0.3
cp -a /usr/share/doc/easy-rsa-3.0.3/* /root/EasyRSA-3.0.3

操作完成后,目录中的内容如下

easy-rsa的相关文件

2.3 制作 server 端证书

制作证书需要一个目录,(我这里以/etc/openvpn/目录为 server 端根目录),执行

cp /root/EasyRSA-3.0.3 /etc/openvpn/	# 复制一份给server端,用于生成客户端证书
cd /etc/openvpn/EasyRSA-3.0.3
cp vars.example vars # 复制一份样例,准备修改
vim vars # 修改样例

修改下 EasyRSA-3.0.3 目录下的 vars 这个文件,配置下环境变量,这里配置了主要是方便在后面制作证书的过程中不用输入很多信息,比较方便,我这里的配置如下图,业务可根据需求自行配置。

vars编辑内容

vars 这个文件修改完毕之后,需要 source 一下,再把证书系统初始化,操作如下

source vars                     # 把var里面的值写入到环境变量中去
./easyrsa init-pki # 初始化证书生成环境

初始化证书系统

下一步就是制作 CA 证书了,如下:

./easyrsa build-ca				# 制作ca证书

CA证书制作

这里会要求出入一个 CA 证书的密码,可以不用输入,我这里输入的 CA 密码为 123456,同时设置 CA 的 Common Name 为 puma。

注意:这里CA的这个密码 123456 要记住,因为后续进行 server 证书和 client 证书认证的时候都需要输入这个密码的。如果忘记,需用重新制作根证书。

下一步就是生成server端的证书了,执行:

./easyrsa gen-req server nopass	# 生成server端证书,需要输入server端的CommonName,可以自行设置

生成server端证书

我这里配置的服务器的名字为 server,服务器证书的 Common Name 为 puma_server

接下来需要对服务器端的证书进行签名认证

./easyrsa sign server server	# 认证server端证书,需要前面设置的 CA 密码

注意:认证证书时需要输入CA的密码,我这里输入 123456,可以看到,认证成功了。

签名认证server端证书

最后一步就是生成 Diffie-Hellman 文件了,如下:

./easyrsa gen-dh				# 生成 dh 证书

生成dh证书

dh证书生成成功

完成后如上图。到这里,server 端的证书和根证书就都生成了,我们把它们拷贝到一个目录下,方便后续 openvpn 的配置文件进行配置。这里把需要用到的证书都拷贝到 /etc/openvpn/server 目录下,操作如下:

cd /etc/openvpn/EasyRSA-3.0.3
cp pki/ca.crt ../server/
cp pki/issued/server.crt ../server/
cp pki/private/server.key ../server/
cp pki/dh.pem ../server/
mv /etc/openvpn/server/dh.pem ../server/dh2048.pem # 根据vars文件中的设置,改名为dh2048.pem

执行完成后,/etc/openvpn/server目录下应该有4个文件

server目录下的文件

2.4 配置 server 端配置文件

执行如下命令写配置文件

cd /etc/openvpn/server/
vim server.conf # 创建 server 端配置文件并编辑,文件内容如下
# 强烈建议配置文件中用绝对路径
port 1194 # 监听1194端口
proto udp # 使用udp协议
dev tun # 通信隧道类型为路由IP隧道
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key
dh /etc/openvpn/server/dh2048.pem # 2048位密钥
server 10.9.0.0 255.255.255.0 # 分配的ip地址区间
ifconfig-pool-persist /etc/openvpn/server/ipp.txt
push "route 192.168.16.0 255.255.240.0" # 给客户端推送路由信息
client-to-client # 客户端之间可以互相发现
duplicate-cn # 开启证书复用
keepalive 10 120
comp-lzo # 启用lzo压缩算法
persist-key
persist-tun
status /etc/openvpn/server/openvpn-status.log
verb 3 # 设置日志文件的冗余级别
explicit-exit-notify 1 # 设置服务器重启时通知客户端,自动重新连接
auth-user-pass-verify /etc/openvpn/server/checkpsw.sh via-env # 服务端认证
;client-cert-not-required # 不要求客户端证书
verify-client-cert # 要求客户端证书
username-as-common-name
script-security 3 # 安全等级 3

上面的配置中我们把用户名密码校验交给了checkpsw.sh,现在写一个校验脚本

cd /etc/openvpn/server/
vim checkpsw.sh # 创建校验脚本,文件内容如下
#!/bin/sh
###########################################################
PASSFILE="/etc/openvpn/server/psw-file"
LOG_FILE="/etc/openvpn/server/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 文件,其中保存着已授权的用户名和密码。

chmod +x checkpsw.sh
vim psw-file # 编写psw-file文件,内容如下
用户名1 密码1
用户名2 密码2

执行如下命令配置 iptables 的 NAT 转发

iptables -t nat -A POSTROUTING -j MASQUERADE

在 openvpn-server 机器上,编辑/etc/sysctl.conf文件,加入net.ipv4.ip_forward=1到该文件中并保存,开启操作系统的网关转发功能,操作如下:

vim /etc/sysctl.conf

启用系统的网关转发功能

修改完成并保存后就运行如下命令:

sysctl -p       # 使 /etc/sysctl.conf 配置文件里面的配置生效

2.5 启动 server 端

执行如下命令启动 openvpn 服务端,如图,表示启动成功。

openvpn --config /etc/openvpn/server/server.conf

server端启动成功

注意:OpenVPN 启动后会占用终端,按Ctrl+C停止运行。如果想启动后不占用终端,可加上--daemon参数,如此,启动命令则为:openvpn --daemon --config /etc/openvpn/server/server.conf

2.6 设置 OpenVPN 开机自启(可选)

服务端的安装配置到上一节就完了,为了避免服务器重启后需要手动开启 OpenVPN,这里将其设置为开机自启动,请根据需要选择。

进入到 /etc/rc.d/目录下,编辑 rc.local 文件,操作命令如下:

cd /etc/rc.d/
vim rc.local

在 rc.local 文件中新增下列内容

# OpenVPN start
openvpn --daemon --config /etc/openvpn/server/server.conf > /dev/null
if [ $? -ne 0 ]
then
echo "`date "+%Y-%m-%d %H:%M:%S"` start vpn failed in /etc/rc.d/rc.local" >> /etc/openvpn/server/openvpn-status.log
fi

保存后,修改系统时区和时间,使打印到日志中的时间和本地计算机的时间同步,执行操作:

timedatectl set-timezone Asia/Shanghai	# 设置时区为上海
date -s 10:23:30 # 设置为自己本机时间

3. 安装配置 OpenVPN 的客户端

3.1 制作 client 端证书

client 端证书的制作过程和 server 端的相似,要注意 client 端制作证书的目录和 server 端并非同一个目录。我用来给client 端制作证书的目录:/root/EasyRSA-3.0.3,给server 端则是:/etc/openvpn/EasyRSA-3.0.3

cd /root/EasyRSA-3.0.3/					# 进入客户端证书制作目录
./easyrsa init-pki # 初始化客户端证书制作目录

client端证书制作目录初始化

创建客户端证书,下面是创建成功的截图,client 的名字为 client_xushan,CommonName 为 puma_client_xushan

./easyrsa gen-req client_xushan nopass	# 生成client端证书,需要输入client端的CommonName,可自行设置,可设置密码

生成client端证书

创建成功后,会在pki/reqs/目录下生成一个名为 client_xushan.req 的文件。

下一步就是在 server 端所在的目录里把上一步生成的 client_xushan.req 这个证书进行签约。

cd /etc/openvpn/EasyRSA-3.0.3
./easyrsa import-req /root/EasyRSA-3.0.3/pki/reqs/client_xushan.req client_xushan #导入客户端证书

导入client端证书

客户端证书签约完成后,还需要进行最后一步的认证,认证之后就可以使用了,过程如下:

./easyrsa sign client client_xushan		# 认证客户端证书

认证client端证书

到这里,客户端的证书就生成完成了,我们需要把他们拷贝到一个文件夹下,方便后续的使用,如下:

# 把客户端需要的文件统一放到 /etc/openvpn/client 下
cp pki/ca.crt ../client
cp pki/issued/client_xushan.crt ../client
cp /root/EasyRSA-3.0.3/pki/private/client_xushan.key ../client

至此,client 目录下有3个文件ca.crtclient_xushan.crtclient_xushan.key,将 client 目录下载到本地(windows)。

3.2 client 端安装

客户端一般是 windows,组件全选安装。安装后桌面会有OpenVPN GUI的快捷方式。icon

3.3 制作 client 端配置文件

在本地(windows)创建 .ovpn的配置文件,名字随便起,这里我的是10.185.80.57.ovpn,配置信息:

client                    # 表示当前是客户端
dev tun # tun 模式(路由模式)
proto udp # 使用 udp 协议
remote 10.185.80.57 1194 # 服务器端的ip和端口
resolv-retry infinite # 断后尝试重连
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
auth-user-pass # 密码认证
remote-cert-tls server
comp-lzo # 启用lzo压缩算法,与server端保持一致
verb 3

根据配置文件,修改client_xushan.crt文件名为client.crt、修改client_xushan.key文件名为client.key保存后,放到刚下载的 client 文件夹下,把 client 文件夹改名成10.185.80.57。将整个文件夹放在 OpenVPN的安装目录下的 config 文件夹下,启动客户端,选择当前配置,输入用户名和密码后会连接上(必须在 server 端中已授权),如图,连接成功

客户端连接

客户端分配的ip

【可选配置】

如不想经常输入用户名和密码,可打开客户端ovpn配置文件,将auth-user-pass改成auth-user-pass pass.txt。同时在相同路径下新增一个名为pass.txt的文本文件。
内容为两行,第一行为 VPN 用户名,第二行为密码。
重新运行 OpenVPN 客户端,即可不输入密码登录 VPN 了!


参考:

  1. 完整CentOS搭建OpenVPN服务环境图文教程.老左博客