Centos 6.4 openvpn各种认证方式
因为除了ldap认证方式以外,openvpn还有一些其他的认证方式么,就放到这里一并记录一下。
https://blog.51niux.com/?id=33 已经记录了openvpn的搭建以及证书认证,所以这里接着这篇博文讲述一些其他的认证方式。当然除了证书认证以外,其他的都是口令认证方式。
一、openvpn口令密码认证方式。
第一步:下载密码脚本
# cd /etc/openvpn/
# wget http://openvpn.se/files/other/checkpsw.sh #当然现在这个脚本是需要翻墙的
# chmod +x /etc/openvpn/checkpsw.sh(不授权的话,你会发现你的配置都没错误,但是就是认证不成功,看日志: /etc/openvpn/checkpsw.sh: Permission denied错误)
# cat checkpsw.sh #查看一下这个脚本,直接粘贴过去便可
#!/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/psw-file"
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
博文来自:www.51niux.com
第二步:创建密码文件
由上面的脚本可以看出密码文件所在的位置为:/etc/openvpn/psw-file
# ls -l /etc/openvpn/psw-file #给此密码文本400权限
-r--------. 1 root root 26 Dec 2 16:48 /etc/openvpn/psw-file
# cat /etc/openvpn/psw-file #我这里创建了两个用户,test1密码为123456,test2密码为654321,用户名和密码之间用空格隔开,一个用户一行,此为规定格式
test1 123456
test2 654321
第三步:服务器端配置文件修改并重新启动openvpn服务
# cat /etc/openvpn/server.conf
port 52116
proto tcp
dev tun
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/openvpn.51niux.com.crt
key /etc/openvpn/keys/openvpn.51niux.com.key
dh /etc/openvpn/keys/dh1024.pem
server 10.16.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
keepalive 10 120
comp-lzo
persist-key
persist-tun
status openvpn-status.log
verb 3
push "route 10.1.15.0 255.255.255.0"
client-to-client
log-append /var/log/openvpn.log
log /var/log/openvpn.log
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env #新加此行,开启密码验证脚本
client-cert-not-required #新加此行,如果加上client-cert-not-required则代表只使用用户名密码方式验证登录,如果不加,则代表需要证书和用户名密码双重验证登录!
username-as-common-name #新加此行,使用客户提供的UserName作为Common Name
还有额外的两行语句:
#duplicate-cn #是否允许一个User同时登录多次,去掉本行注释后可以使用同一个用户名登录多次
#plugin /etc/openvpn/openvpn-auth-pam.so openvpn #说明使用的插件,openvpn为插件的参数,使用pam的servicesname,而openvpn-auth-pam.so默认是没有的,需要进入openvpn的源码目录:plugin/auth-pam下面执行一下make命令,才会产生此文件.
第四步:客户端的配置文件的修改
;cert csp.crt #注释掉此句
;key csp.key #注释掉此句
auth-user-pass #新加此句,打开用户名密码验证
auth-nocache #新加此句,auth-nocache可以在断线后防止内存中保存用户名和密码来提高安全性,闲麻烦可不加,不然每次断开重新连接都会要求需要输入用户名和密码。
第五步:客户端登录验证
# tail -f /var/log/openvpn-password.log #查看密码验证日志
2016-12-02 17:07:58: Successful authentication: username="test1".
2016-12-02 17:10:47: Successful authentication: username="test1".
2016-12-02 17:15:46: Successful authentication: username="test2".
2016-12-02 17:16:39: Successful authentication: username="test2".
2016-12-02 17:24:51: Successful authentication: username="test2".
2016-12-02 17:26:45: Successful authentication: username="test1".
2016-12-02 17:27:26: Successful authentication: username="test1".
2016-12-02 17:28:21: Successful authentication: username="test1".
2016-12-02 17:28:56: Successful authentication: username="test1".https://blog.51niux.com/zb_system/admin/edit.php?act=ArticleEdt&id=73
2016-12-02 18:00:44: Successful authentication: username="test1".
2016-12-02 18:04:52: Incorrect password: username="test2", password="32131". #错误也是会有提示的
#经过测试,我们创建的test1和test2用户都已经可以登录openvpn。
博文来自:www.51niux.com
二、mysql认证方式
https://blog.51niux.com/?id=71这里已经有一篇文章讲了vsftpd如何使用mysql认证,所以这里的大概步骤是跟这篇文章的mysql认证是一致的。
如果openvpn采用了口令认证的形式,文本密码的方式可能会稍微的low一点,所以我们尝试用mysql来管理一下,而且用了mysql还可以引入后续的流量统计,网上一搜还是很多的。
这里openvpn用mysql认证,还是通过pam认证的形式。
第一步:安装必要的软件(假设我们已经安装了mysql)
# yum install pam_krb5 pam_mysql pam pam-devel #(这里第三方yum源)
第二步:数据库配置
# mysql #登录mysql数据库
mysql> create database openvpn; #创建openvpn数据库
mysql> use openvpn;
mysql> grant all on openvpn.* to vpnadmin@'localhost' identified by 'vpn123456';
mysql> flush privileges;
mysql> create table vpnuser ( name char (100) not null, password char (255) default null, active int (10) not null default 1, primary key (name) );
mysql> desc vpnuser;
+----------+-----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-----------+------+-----+---------+-------+
| name | char(100) | NO | PRI | NULL | |
| password | char(255) | YES | | NULL | |
| active | int(10) | NO | | 1 | |
+----------+-----------+------+-----+---------+-------+
3 rows in set (0.03 sec)
#第一列为登录vpn的用户名,第二列为登录的密码,第三列是是否被禁用,active为启用,改为0表示不能登录。
mysql> create table loginlog ( msg char (254), user char (100), pid char (100), host char (100), rhost char (100), time char (100) );
mysql> desc loginlog;
+-------+-----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+---------+-------+
| msg | char(254) | YES | | NULL | |
| user | char(100) | YES | | NULL | |
| pid | char(100) | YES | | NULL | |
| host | char(100) | YES | | NULL | |
| rhost | char(100) | YES | | NULL | |
| time | char(100) | YES | | NULL | |
+-------+-----------+------+-----+---------+-------+
6 rows in set (0.00 sec)
mysql> insert into vpnuser (name,password) values ('test1',password('123456'));
mysql> insert into vpnuser (name,password) values ('test2',password('654321'));
#插入了两个用户
mysql> select * from vpnuser;
+-------+-------------------------------------------+--------+
| name | password | active |
+-------+-------------------------------------------+--------+
| test1 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | 1 |
| test2 | *2A032F7C5BA932872F0F045E0CF6B53CF702F2C5 | 1 |
+-------+-------------------------------------------+--------+
测试一下我们的用户名密码是否能登录:
# mysql -uvpnadmin -pvpn123456 -e "show databases;"
+--------------------+
| Database |
+--------------------+
| information_schema |
| openvpn |
+--------------------+
第三步:配置pam_mysql
# vi /etc/pam.d/openvpn_mysql #为什么要要加个后缀呢,因为pam支持好多种认证方式,这样好识别
auth sufficient pam_mysql.so user=vpnadmin passwd=vpn123456 host=localhost db=openvpn table=vpnuser usercolumn=name passwdcolumn=password [where=vpnuser.active=1] sqllog=0 crypt=2 sqllog=true logtable=loginlog logmsgcolumn=msg logusercolumn=user logpidcolumn=pid loghostcolumn=host logrhostcolumn=rhost logtimecolumn=time
account required pam_mysql.so user=vpnadmin passwd=vpn123456 host=localhost db=openvpn table=vpnuser usercolumn=name passwdcolumn=password [where=vpnuser.active=1] sqllog=0 crypt=2 sqllog=true logtable=loginlog logmsgcolumn=msg logusercolumn=user logpidcolumn=pid loghostcolumn=host logrhostcolumn=rhost logtimecolumn=time
第四步:编译安装openvpn-auth-pam.so
openvpn-auth-pam.so默认是没有的,需要进入openvpn的源码目录:plugin/auth-pam下面执行一下make命令,才会产生此文件.
注:2.1以上的OpenVPN的openvpn-auth-pam.so都会出现验证错误的问题,这里需要重新编译一个低版本的
# cd /tools/openvpn-2.0.9/plugin/auth-pam/
# ll
total 40
-rwxr-xr-x. 1 root root 702 Nov 1 2005 Makefile
-rw-r--r--. 1 root root 2590 Nov 1 2005 README
-rw-r--r--. 1 root root 17682 Nov 1 2005 auth-pam.c
-rw-r--r--. 1 root root 5235 Nov 1 2005 pamdl.c
-rw-r--r--. 1 root root 162 Nov 1 2005 pamdl.h
# make
# ll
total 88
-rwxr-xr-x. 1 root root 702 Nov 1 2005 Makefile
-rw-r--r--. 1 root root 2590 Nov 1 2005 README
-rw-r--r--. 1 root root 17682 Nov 1 2005 auth-pam.c
-rw-r--r--. 1 root root 12528 Dec 2 17:03 auth-pam.o
-rwxr-xr-x. 1 root root 20254 Dec 2 17:03 openvpn-auth-pam.so
-rw-r--r--. 1 root root 5235 Nov 1 2005 pamdl.c
-rw-r--r--. 1 root root 162 Nov 1 2005 pamdl.h
-rw-r--r--. 1 root root 9152 Dec 2 17:03 pamdl.o
# cp openvpn-auth-pam.so /etc/openvpn/
第五步:配置openvpn服务端文件
# cat /etc/openvpn/server.conf
port 52116
proto tcp
dev tun
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/openvpn.51niux.com.crt
key /etc/openvpn/keys/openvpn.51niux.com.key
dh /etc/openvpn/keys/dh1024.pem
plugin /etc/openvpn/openvpn-auth-pam.so openvpn_mysql #新增了此行,使用openvpn-auth-pam.so插件openvpn.mysql为参数,也就是我们创建的pam验证文件的名称
server 10.16.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
keepalive 10 120
comp-lzo
persist-key
persist-tun
status openvpn-status.log
verb 3
push "route 10.1.15.0 255.255.255.0"
client-to-client
log-append /var/log/openvpn.log
log /var/log/openvpn.log
client-cert-not-required
username-as-common-name
第六步:测试
首先可以先在本机使用testsaslauthd验证登录:
# saslauthd -a pam 或者 # /etc/init.d/saslauthd start
# testsaslauthd -u test1 -p 123456 -s openvpn_mysql
0: OK "Success." #测试结果是OK的
然后再windows客户端进行验证(客户端的配置文件不变):
下面是client.ovpn的配置:
client
dev tun
proto tcp
remote 192.168.1.212 52116
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
verb 3
auth-user-pass
auth-nocache
comp-lzo
然后进行登录验证,结果是OK的,这里就不贴截图了。
查看下mysql的登录信息表:
然后我们禁用一下test1用户和再新创建一个test3用户,测试一下。
mysql> insert into vpnuser (name,password) values ('test3',password('test123'));
mysql> update vpnuser set active = '0' where name = 'test1';
查看服务端的日志:
# tail -f /var/log/openvpn.log
AUTH-PAM: BACKGROUND: user 'test1' failed to authenticate: Permission denied #出现此信息
博文来自:www.51niux.com
三、openvpn+ldap验证方式
验证方式有两种实现形式:一种用 openvpn-auth-ldap 即直接通过 LDAP 验证,另一种与 mysql 认证相似,使用 pam-ldap ,通过 PAM ,然后再找 LDAP 验证。
先说第一种方式通过:openvpn-auth-ldap进行认证。
第一步:安装相关软件
# yum install openvpn-auth-ldap
生成的库文件为:/usr/lib64/openvpn/plugin/lib/openvpn-auth-ldap.so
配置文件为:/usr/share/doc/openvpn-auth-ldap-2.0.3/auth-ldap.conf
第二步:修改openvpn服务端的配置文件
# cat /etc/openvpn/auth-ldap.conf #我们直接手工创建auth-ldap.conf认证文件了
<LDAP>
URL ldap://192.168.1.111
BindDN "CN=Manager,DC=51niux,DC=com"
Password 123456
Timeout 15
TLSEnable no
FollowReferrals no
</LDAP>
<Authorization>
BaseDN "ou=People,dc=51niux,dc=com"
SearchFilter "(uid=%u)"
RequireGroup false
</Authorization>
# cat /etc/openvpn/server.conf
port 52116
proto tcp
dev tun
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/openvpn.51niux.com.crt
key /etc/openvpn/keys/openvpn.51niux.com.key
dh /etc/openvpn/keys/dh1024.pem
#plugin /etc/openvpn/openvpn-auth-pam.so openvpn_mysql
plugin /usr/lib64/openvpn/plugin/lib/openvpn-auth-ldap.so "/etc/openvpn/auth-ldap.conf cn=%u" #主要是增加了这一句话,这里是双引号
server 10.16.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
keepalive 10 120
comp-lzo
persist-key
persist-tun
status openvpn-status.log
verb 3
push "route 10.1.15.0 255.255.255.0"
client-to-client
log-append /var/log/openvpn.log
log /var/log/openvpn.log
client-cert-not-required
username-as-common-name
第三步:登录测试
我们再ldap服务器新创建一个csp的用户,密码为123456
现在openvpn服务端也就是ldap的客户端进行一下测试,看是否能查询到用户:
# ldapsearch -LLL -W -x -H ldap://192.168.1.111 -D "cn=Manager,dc=51niux,dc=com" -b "dc=51niux,dc=com " "uid=csp"
Enter LDAP Password:
dn: uid=csp,ou=People,dc=51niux,dc=com
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
homeDirectory: /home/csp
loginShell: /bin/bash
uid: csp
cn: csp
uidNumber: 10001
gidNumber: 10001
sn: csp
userPassword:: e1NTSEF9cVM5T2pSbndjUUVVVnU0WCtDQTJ1aDJNcTZsVGg1dVc=
#通过测试是可以查到的,那么下来我们用windows的客户端连接vpn。
查看服务器日志信息:
Fri Dec 2 20:29:44 2016 csp/192.168.1.145:51925 MULTI: primary virtual IP for csp/192.16818.145:51925: 10.16.0.6
Fri Dec 2 20:29:46 2016 csp/192.168.1.145:51925 PUSH: Received control message: 'PUSH_REQUEST'
Fri Dec 2 20:29:46 2016 csp/192.168.1.145:51925 SENT CONTROL [csp]: 'PUSH_REPLY,route 10.1.15.0 255.255.255.0,route 10.16.0.0 255.255.255.0,ping 10,ping-restart 120,ifconfig 10.16.0.6 10.16.0.5' (status=1)
#通过日志可以看到已经认证通过并分配了IP,桌面右下角的图标也是绿色的。
现在来说第二种,以使用pam,然后通过pam_ldap调用ldap进行验证,跟使用mysql有点类似,但是还是用到了openvpn-auth-ldap.so模块啊!
第一步:ldap客户端的相关配置,也就是openvpn服务端的相关配置
https://blog.51niux.com/?id=69跟这个的做法已经非常相似了。就按这个来就行。
要说有区别的地方也就是/etc/nslcd.conf 这个文件不用改。
/etc/pam.d/system-auth文件中:session optional pam__mkhomedir.so skel=/etc/skel umask=077不用加
第二步:修改配置openvpn配置文件
plugin /etc/openvpn/openvpn-auth-pam.so system-auth #将认证文件改为此配置文件
第三步:windows客户端进行测试
好我们就用这个两个用户试一下。
查看日志:
# tail -f /var/log/openvpn.log
Sat Dec 3 01:26:26 2016 192.168.1.103:58797 TLS: Username/Password authentication succeeded for username 'ldaptest1' [CN SET]
Sat Dec 3 01:26:26 2016 192.168.1.103:58797 Data Channel Encrypt: Cipher 'BF-CBC' initialized with 128 bit key
Sat Dec 3 01:26:26 2016 192.168.1.103:58797 Data Channel Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Sat Dec 3 01:26:26 2016 192.168.1.103:58797 Data Channel Decrypt: Cipher 'BF-CBC' initialized with 128 bit key
Sat Dec 3 01:26:26 2016 192.168.1.103:58797 Data Channel Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Sat Dec 3 01:26:26 2016 192.168.1.103:58797 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA
Sat Dec 3 01:26:26 2016 192.168.1.103:58797 [ldaptest1] Peer Connection Initiated with 192.168.1.103:58797
Sat Dec 3 01:26:26 2016 ldaptest1/192.168.1.103:58797 MULTI: Learn: 10.16.0.10 -> ldaptest1/192.168.1.103:58797
Sat Dec 3 01:26:26 2016 ldaptest1/192.168.1.103:58797 MULTI: primary virtual IP for ldaptest1/192.168.1.103:58797: 10.16.0.10
Sat Dec 3 01:26:28 2016 ldaptest1/192.168.1.103:58797 PUSH: Received control message: 'PUSH_REQUEST'
Sat Dec 3 01:26:28 2016 ldaptest1/192.168.1.103:58797 SENT CONTROL [ldaptest1]: 'PUSH_REPLY,route 10.1.15.0 255.255.255.0,route 10.16.0.0 255.255.255.0,ping 10,ping-restart 120,ifconfig 10.16.0.10 10.16.0.9' (status=1)
经过测试,也是可以的。