Total Pageviews

Sunday 3 March 2013

在debian/ubuntu vps下,使用pam-MyQL验证OpenVPN的用户

使用 pam + MySQL 验证,这样不但以后给朋友开openvpn账户方便了,而且还可以多台主机使用一个 MySQL 表,实现多台服务器账户信息共享,配置过程简单整理记录如下.
前提条件:先在vps安装好OpenVPN,并且客户端可以使用证书方式正常连接。

安装 pam-mysql

apt-get install libpam-mysql libmysql++-dev libpam0g-dev libmysqlclient-dev sasl2-bin
(如果你的vps是centos/fedora系统,则yum install pam-devel -y)

建 MySQL 库,表,用户

mysql> create database vpndb;
mysql> grant all on vpndb.* to myname@localhost IDENTIFIED BY 'MYPASSWORD';
mysql> FLUSH PRIVILEGES;
mysql> use vpndb;
mysql> CREATE TABLE vpnuser (
-> username char(20) NOT NULL,
-> password char(128) default NULL,
-> active int(10) NOT NULL DEFAULT 1,
-> PRIMARY KEY (username)
-> );
mysql> insert into vpnuser (username,password) values('somebody',password('secret'));
建议使用明文密码否则下面的testsaslauthd命令会通不过的:
mysql> insert into vpnuser (username,password) values('somebody',
'hispassword');
 #创建DB用户myname,对vpndb这个database有全部的操作权限,密码为MYPASSWORD

#active不为1,无权使用VPN

#增加用户 用户名:somebody 密码:secret  参见:http://www.chinaunix.net/jh/50/513004.html,http://blog.chinaunix.net/u/2389/showart_15825.html

配置 pam-mysql

# cd /etc/pam.d/
#nano openvpn (新建openvpn文件)
输入内容:
auth optional pam_mysql.so user=myname passwd=MYPASSWORD host=localhost db=vpndb table=vpnuser usercolumn=username passwdcolumn=password where=active=1 crypt=0

account required pam_mysql.so user=myname passwd=MYPASSWORD host=localhost db=vpndb table=vpnuser usercolumn=username passwdcolumn=password where=active=1 crypt=0
注意这里 crypt=2,是指密码需要用 mysql 的 password()函数。如果 crypt=3 的话密码则需要 MD5()。建议把crypt=的值设为0,否则下面的testsaslauthd命令会通不过的。
用 sasl2 验证一下
# saslauthd -a pam  (如果cyrus-sasl是编译的,则运行# saslauthd -m /var/state/saslauthd -a pam)
# testsaslauthd -u somebody -p secret -s openvpn (这个openvpn即为上面新建的openvpn文件)
如果出现
0: OK "Success." 就表示pam-mysql验证没有问题了.

如果出现 
0: NO "authentication failed"
则上面的mysql> insert into vpnuser (username,password) values('somebody',password('secret'));应该改为: mysql> insert into vpnuser (username,password) values('somebody','hispassword'); 即:使用明文密码。另外还要把/et/pam.d/openvpn文件中的crypt=的值改为0才行
(LDAP的验证.
需要pam-ldap.so模块
编辑/etc/pam_ldap.conf 文件
#host IPaddress  #远端服务器地址
#base ou=XXX,dc=XXX,dc=XXX #ldap路径
#ldap_version 3 #ldap版本
#rootbinddn cn=XXX,dc=XXX,dc=XXX #ldap admin
#pam_password crypt #加密方式
LDAP admin的密码放在/etc/ldap.secret文件中。
配置pam_ldap模块
创建/etc/pam.d/openvpn文件,文件内容如下:
auth sufficient pam_ldap.so config=/etc/pam_ldap.conf
account sufficient pam_ldap.so config=/etc/pam_ldap.conf
测试和MySQL一样。
原本建OpenVPN是使用的是MySQL验证方式,为了配合公司的SSO(Single sign-on)单点登录,后改成LDAP的验证方式,但是搜索了很多中文文档都没有说到,在google上到看到国外网站有针对OpenVPN的第三方 插件,也有提到点滴pam_ldap验证,于是尝试也一下,没想到成功了,呵呵)

修改 OpenVPN的配置

#cp /usr/lib/openvpn/openvpn-auth-pam.so /etc/openvpn/ 
(如果openvpn是从源码编译安装的,则:
# cd /root/openvpn-版本号/plugin/auth-pam/
# make
在当前目录/root/openvpn-版本号/plugin/auth-pam/下就会生成openvpn-auth-pam.so文件。然后
# cp openvpn-auth-pam.so /etc/openvpn/ )
(如果在用openvpn客户端连接的时候提示输入用户名/密码,输入后,验证不成功又跳出输入用户名/密码的对话框,并且在putty.exe中显示
AUTH-PAM: BACKGROUND: user 'tom' failed to authenticate: Module is unknown.   问题终于解决了,是由于openvpn-auth-pam.so的问题,openvpn的版本为2.1-rc11,但相应的openvpn-auth-pam.so不能用,在openvpn
源码包的解压出来的/root/openvpn-版本号/plugin/auth-pam/目录下,运行# make,在该目录下就会生成openvpn-auth-pam.so文件,替换原来的,就能正常连接了。)
# cd /etc/openvpn/easy-rsa/2.0 # openvpn --genkey --secret keys/ta.key

# cp /etc/openvpn/easy-rsa/2.0/keys/ta.key /etc/openvpn/
# nano /etc/openvpn/openvpn.conf
在最后加入:
plugin /etc/openvpn/openvpn-auth-pam.so /etc/pam.d/openvpn
client-cert-not-required
username-as-common-name
tls-auth ta.key 0

下载ca.crt和ta.key到c:\program files\openvpn\config\,
修改客户端的conf文件:client.ovpn文件,将原来的
cert client.crt
key client.key
这2行注释掉,并加入:
auth-user-pass
tls-auth ta.key 1
保存即可。(以上蓝色字体部分为我所加)
到此为止所有准备工作就完成了。(在mac下,用 Tunnelblick 启动这个新的客户端配置文件的话,会有对话框提示用户名和密码,输入并保存到 keychain 以后就一劳永逸了。)
另外,网上很多用户遇到了使用 sasl 验证没问题,但是 OpenVPN 验证不过去的现象:
BACKGROUND:  *** failed to authenticate: Permission denied
所以,很多朋友会在这里纠结,网上找了很久,发现这个原来是pam_mysql的一个bug ,我也在这个问题上卡了好久.
Google 后,发现网上已经有可用的 patch,步骤如下:
wget http://prdownloads.sourceforge.net/pam-mysql/pam_mysql-0.7RC1.tar.gz
tar zxvf pam_mysql-0.7RC1.tar.gz
cd pam_mysql-0.7RC1
nano patch.in
内容如下
--- Makefile.in.chold   2008-07-14 10:25:53.000000000 +0200
+++ Makefile.in 2008-07-14 10:26:06.000000000 +0200
@@ -110,7 +110,7 @@
 CPPFLAGS = @CPPFLAGS@
 LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
-pam_mysql_la_LIBADD =
+pam_mysql_la_LIBADD = -lpam
 pam_mysql_la_OBJECTS =  pam_mysql.lo
 CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
(注意:如上的patch.in其实是有问题的。它的目的其实就是修改解压出来的目录pam_mysql-0.7RC1里面的Makefile.in文件,我们把Makefile.in文件的第113行由
“pam_mysql_la_LIBADD = ”改为"pam_mysql_la_LIBADD = -lpam",保存更改。无需新建patch.in文件)
然后开始编译pam_mysql,
# ./configure
# make
# make install (这样,
编译pam_mysql就顺利完成了。编译pam_mysql的做法适合在centos/fedora vps下进行。当然debian/ubuntu下,也可这样编译
# nano /etc/ld.so.conf (在/etc/ld.so.conf文件的最下面添加/usr/lib/)
# cp /lib/security/pam_mysql.so to /usr/lib/
上面打了下划线的部分也可改为:
#nano /etc/ld.so.conf
在文件的末尾加入以下一行:
/lib/security/
#ldconfig


然后重启openvpn:

/etc/init.d/openvpn restart
(如果openvpn是编译的,则
# killall openvpn
# /usr/local/sbin/openvpn --config /etc/openvpn/openvpn.conf &)
重新测试,连接 OpenVPN,工作正常!
PS:如果你的系统是 Debian 的话,squeeze 的 testing 源里面已经有了加入这个 patch 的新版 libpam-mysql,版本号为 0.7~RC1-4

参考:
这下不应该有任何问题了,把ca.crt,ta.key 放到你的网站让用户下载吧,以后只需要在 MySQL 表格中添加记录就可以开openvpn用户帐号了具体操作过程为:
# mysql -u myname -p (myname为db username)
会出现Enter password:(输入数据库用户myname的密码)

之后会出现mysql的提示符:mysql>,
在mysql>处,输入use vpndb;
在mysql>处,输入insert into vpnuser (username,password) values('somebody','hispassword');
回车,出现Query Ok,openvpn server的帐号就添加完成了。(蓝色字体系我所加)
参考:
from http://b.gkp.cc/2010/08/08/setup-openvpn-with-mysql-auth/

(此文不错,我设置成功.这种需要认证才能连接的openvpn,最好不要设置前置代理,如果设置了的话,反而连不上openvpn server.只需在openvpn服务器端打混淆补丁就够了)


--------------------------------------------------------------------------------------------------------------
OpenVPN with pam_mysql using username/password authentication

Here's how I setup OpenVPN with pam_mysql using only username/password authentication (insecure, but really easy on the admin side :P).  Target platform is Ubuntu Jaunty.  For starters, you'll need the following installed:
  • openvpn
  • mysql - server installed and running
Get the latest version of pam_mysql from http://pam-mysql.sourceforge.net/.  Untar it into a working directory.  The latest version as of writing this article is 0.7RC1.  The pam_mysql package in Jaunty is broken.  You'll need to patch the Makefile.in with the following patch (thanks to http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=418500#50):
--- Makefile.in.chold   2008-07-14 10:25:53.000000000 +0200
+++ Makefile.in 2008-07-14 10:26:06.000000000 +0200
@@ -110,7 +110,7 @@
 CPPFLAGS = @CPPFLAGS@
 LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
-pam_mysql_la_LIBADD =
+pam_mysql_la_LIBADD = -lpam
 pam_mysql_la_OBJECTS =  pam_mysql.lo
 CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
Save the above as patch.in in the same folder where you untar pam_mysql.  Then run the following command:
# patch -p0 <patch.in
That command will perform the patch process by using the patch.in file.  Next, we'll need to grab some deb packages to compile the module:
# apt-get install libmysql++-dev libpam0g-dev libgsasl7 libgsasl7-dev
Once that's done, proceed with the usual make commands (please note the extra configure options to enable SHA1 and MD5 options in the module):
# ./configure --with-cyrus-sasl2 --with-openssl
# make
# make install

The module should now be installed in /lib/security/pam_mysql.so.  Now to configure OpenVPN.  Here's my server configuration file:
port 1194
proto udp
dev tun

ca /etc/openvpn/easy-rsa/ca.crt
cert /etc/openvpn/
easy-rsa/server.crt
key /etc/openvpn/
easy-rsa/server.key
dh /etc/openvpn/
easy-rsa/dh1024.pem

server 10.128.127.0 255.255.255.0
ifconfig-pool-persist ipp.txt

push "redirect-gateway def1"
push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 2.2.2.2"

keepalive 10 120

comp-lzo

max-clients 50

persist-key
persist-tun

status openvpn-status.log
log-append /var/log/openvpn.log
verb 3
mute 20

client-cert-not-required
username-as-common-name

plugin /usr/lib/openvpn/openvpn-auth-pam.so openvpn
The most important lines are the last three lines which have been bold.  Follow the commands below to setup OpenVPN server:
cd /etc/openvpn
cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0/ easy-rsa
cd easy-rsa
vim vars # Edit KEY_* vars appropriately
source ./vars
./clean-all
./build-dh
./pkitool --initca
./pkitool --server server
To allow traffic to be routed from clients to the server, perform the following tasks:
echo 1 > /proc/sys/net/ipv4/ip_forward
edit /etc/sysctl.conf
Uncomment/add the line: net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 10.128.127.0/24 -o eth0 -j MASQUERADE
iptables-save
Now to configure PAM.  Create a file called openvpn in /etc/pam.d.  Below are its contents:
auth optional /lib/security/pam_mysql.so user=root passwd=pass host=localhost db=vpn_db table=tbl_user usercolumn=userid passwdcolumn=password where=active=1 sqllog=no crypt=4 verbose=0

account required /lib/security/pam_mysql.so user=root passwd=pass host=localhost db=vpn_db table=tbl_user usercolumn=userid passwdcolumn=password
where=active=1 sqllog=no crypt=4 verbose=0
crypt=4 instructs pam_mysql to use SHA1.  There are other options which you can view in the pam_mysql README file.  OpenVPN client configuration file is shown below:
client
dev tun
proto udp
remote my.vpn.server.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
auth-user-pass
cipher BF-CBC
comp-lzo
verb 4
mute 20
Very lean and clean client config file.

2 comments:

David said...
Whats the SQL dump file or how do I create the database / tables in mysql?
voiptrader said...
try this :

mysql -u root -p
CREATE DATABASE vpn_db;

USE vpn_db;
CREATE TABLE `tbl_user` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`userid` VARCHAR( 30 ) NOT NULL ,
`password` VARCHAR( 50 ) NOT NULL,
`active` TINYINT ( 1 ) NOT NULL,
UNIQUE (`userid`)
) ENGINE = MYISAM ;

from http://techtots.blogspot.com/2010/01/openvpn-with-pammysql-usernamepassword.html