OpenVPN使用账号密码认证方式登陆

使用账号密码人认证方式方便给多人分配不同的账号和密码,多人使用更加方便

鉴于上一篇文章已经在CentOS7系统上成功的搭建好 OpenVPN 了,以Windows客户端为例是直接使用证书进行连接OpenVPN服务端的,如果多人使用的话,建议改为账号+密码认证方式,这里介绍比较简单的一种方式。

服务端配置

修改服务端配置

修改OpenVPN服务端配置文件server.conf,执行以下命令:

1
$ vim /etc/openvpn/server.conf  # 打开server.conf配置文件编辑

在配置文件server.conf的末尾追加下面的配置信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# use username and password login
# 新加此行,开启密码验证脚本
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env
# 加上client-cert-not-required代表只使用用户密码方式验证登录,不加则代表需要证书和用户名密码双重验证登录
client-cert-not-required
# 新加此行,使用客户提供的UserName作为Common Name
username-as-common-name
# 该指令提供对OpenVPN使用外部程序和脚本的策略级别的控制。较低的 水平 值更具限制性,较高的值更宽松。级别设置
# 0- 完全不调用外部程序。
# 1- (默认)仅调用内置可执行文件,例如ifconfig,ip,route或netsh。
# 2- 允许调用内置的可执行文件和用户定义的脚本。
# 3- 允许通过环境变量将密码传递给脚本(可能不安全)。
# 特别注意如果没有这个配置项会导致服务端校验密码时无法获取到密码,导致校验失败
script-security 3

增加密码验证脚本

下面开始编写OpenVPN服务端验证密码的脚本checkpsw.sh,执行以下命令:

1
$ vim /etc/openvpn/checkpsw.sh

checkpsw.sh 文件内容如下所示:

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
#!/bin/sh
###########################################################
# checkpsw.sh (C) 2004 Mathias Sundman <mathias@openvpn.se>
#
# 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/user_passwd.txt"
LOG_FILE="/var/log/openvpn/openvpn-login.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

为密码验证脚本checkpsw.sh添加可执行性权限,执行以下命令:

1
# chmod +x /etc/openvpn/checkpsw.sh

配置账号密码文件

配置账号/密码文件user_passwd.txt的内容,新增账号/密码到这个文件,一行一个账号,账号密码用空格隔开:

注:密码需要使用字母加数字,特殊字符等,且不能以数字开头

1
2
3
4
5
6
7
$ vim /etc/openvpn/user_passwd.txt # 编辑账号密码文件,添加以下内容
eddieeo c123456@

# 修改账号密码文件的访问权限,第一是为了安全起见,第二是启动OpenVPN服务端的用户(默认是openvpn用户)必须对账号密码文件具有可读权限
$ cd /etc/openvpn/
$ chmod 400 user_passwd.txt
$ chown openvpn.openvpn user_passwd.txt

重启openvpn服务

1
$ systemctl restart openvpn@server

客户端配置

修改客户端配置

这里以 Windows 客户端为例,编辑客户端软件 OpenVPN GUI 安装路径下的config目录里名为 *.ovpn 结尾的配置文件,修改文件内容如下:

1
2
3
4
5
6
# 注释掉客户端密钥认证方式
;cert laptop.crt
;key laptop.key

# 新增账号/密码验证方式
auth-user-pass

测试连接

编辑完保存好配置文件,使用管理员身份打开客户端程序OpenVPN GUI ,尝试重新连接OpenVPN服务端,可以看到弹出登陆框,输入账号和密码进行验证,如下图所示:

显示OpenVPN GUI连接状态,如下图所示,表示完成账号密码验证,此时已经连接上OpenVPN服务端了。

最后使用 ping 服务端的私网地址的方式,测试连通性。

其他

注意服务端配置文件 server.conf 的最后一行

1
script-security 3

默认的级别是 2,需要修改为级别 3 , 可以用 ps 看进程号时能看到 。
如果没有这个的话,会有个很神奇的现象,就是账号可以传过来,但是密码获取不到,可以在服务端的登录日志/var/log/openvpn/openvpn-login.log 里查看日志!!!

客户端添加账号密码文件省去手动输入账号密码

如果客户端需要记住账号/密码,以Windows客户端 OpenVPN GUI 为例,可以在客户端安装路径下的config目录里修改 *.ovpn 配置文件的配置,添加指定账号密码文件login.conf (Mac客户端Tunnelblick试过不好使)

1
auth-user-pass login.conf

然后在客户端安装路径下的config目录里新增login.conf 文件,账号密码使用换行符分隔,内容如下:

1
2
eddieeo
c123456@