How to install a OpenVPN System Based On User/Password Authentication with mysql & Day Control (libpam-mysql)

Source Page: http://sysadmin.compxtreme.ro/how-to-install-a-openvpn-system-based-on-userpassword-authentication-with-mysql-day-control-libpam-mysql/

I have added some notes through the article.

here comes the article:

This document describes how to install a OpenVPN server with User/Password authentication with mysql and day control using libpam-mysql. This will be a brief, but a very practical document.

Install mysql server

apt-get install mysql-server

Create a mysql user and a database to be used later

Create user

mysql -u root -p
CREATE DATABASE openvpn;
USE openvpn;

create database

CREATE USER 'openvpn'@'localhost' IDENTIFIED BY 'lNPg5TAIy82zFpEn';
GRANT ALL PRIVILEGES ON `openvpn`.* TO 'openvpn'@'localhost';
FLUSH PRIVILEGES;

Create user table

CREATE TABLE IF NOT EXISTS `user` (
    `user_id` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
    `user_pass` varchar(32) COLLATE utf8_unicode_ci NOT NULL DEFAULT '1234',
    `user_mail` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
    `user_phone` varchar(16) COLLATE utf8_unicode_ci DEFAULT NULL,
    `user_start_date` date NOT NULL,
    `user_end_date` date NOT NULL,
    `user_online` enum('yes','no') NOT NULL DEFAULT 'no',
    `user_enable` enum('yes','no') NOT NULL DEFAULT 'yes',
PRIMARY KEY (`user_id`),
KEY `user_pass` (`user_pass`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Create log table

CREATE TABLE IF NOT EXISTS `log` (
    `log_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `user_id` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
    `log_trusted_ip` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
    `log_trusted_port` varchar(16) COLLATE utf8_unicode_ci DEFAULT NULL,
    `log_remote_ip` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
    `log_remote_port` varchar(16) COLLATE utf8_unicode_ci DEFAULT NULL,
    `log_start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `log_end_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
    `log_received` float NOT NULL DEFAULT '0',
    `log_send` float NOT NULL DEFAULT '0',
PRIMARY KEY (`log_id`),
KEY `user_id` (`user_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Install OpenVPN

apt-get install openvpn

Generate keys

apt-get install openssl

Copy certificate generate file from example

cp -R /usr/share/doc/openvpn/examples/easy-rsa /etc/openvpn/.
cd /etc/openvpn/easy-rsa/2.0/

Replace some options (I have no idea why author want to do this)

sed -i -e 's/--interact //g' build-key

search and replace the following values in /etc/openvpn/easy-keys/2.0/vars

vim vars
export KEY_SIZE=2048

export KEY_COUNTRY="SE"
export KEY_PROVINCE="SE"
export KEY_CITY="STOCKHOLM"
export KEY_ORG="Company Name"
export KEY_EMAIL="email@example.org"
export KEY_CN=vpn.example.org
export KEY_NAME=operations
export KEY_OU=operations
export PKCS11_MODULE_PATH=changeme
export PKCS11_PIN=1234

save and exit

Disable unqiue subject

sed -i -e 's/unique_subject = yes/unique_subject = no/g' /etc/openvpn/easy-rsa/2.0/keys/index.txt.attr

Start to bulid certificates

source ./vars
./clean-all
./build-ca
./build-key-server vpn.example.org
./build-dh
cp -a keys /etc/openvpn/.

Install libpam-mysql and setup pam authentication based on it

apt-get install libpam-mysql

Add a new file inside pam

touch /etc/pam.d/openvpn

Paste the following content into the file we just created

auth sufficient pam_mysql.so user=openvpn passwd=lNPg5TAIy82zFpEn host=localhost db=openvpn [table=user] usercolumn=user.user_id passwdcolumn=user.user_pass [where=user.user_enable=1 AND user.user_start_date!=user.user_end_date AND TO_DAYS(now()) >= TO_DAYS(user.user_start_date) AND (TO_DAYS(now()) <= TO_DAYS(user.user_end_date) OR user.user_end_date='0000-00-00')] sqllog=0 crypt=0
account required pam_mysql.so user=openvpn passwd=lNPg5TAIy82zFpEn host=localhost db=openvpn [table=user] usercolumn=user.user_id passwdcolumn=user.user_pass [where=user.user_enable=1 AND user.user_start_date!=user.user_end_date AND TO_DAYS(now()) >= TO_DAYS(user.user_start_date) AND (TO_DAYS(now()) <= TO_DAYS(user.user_end_date) OR user.user_end_date='0000-00-00')] sqllog=0 crypt=0

Create scripts to log OpenVPN access activity

mkdir /etc/openvpn/scripts/ && cd $_

Create the following file

vim /etc/openvpn/scripts/config.sh
#!/bin/bash
##Dababase Server
HOST='127.0.0.1'
#Default port = 3306
PORT='3306'
#Username
USER='openvpn'
#Password
PASS='lNPg5TAIy82zFpEn'
#database name
DB='openvpn'
vim /etc/openvpn/scripts/connect.sh
#!/bin/bash
. /etc/openvpn/scripts/config.sh
##insert data connection to table log
mysql -h$HOST -P$PORT -u$USER -p$PASS $DB -e "INSERT INTO log (log_id,user_id,log_trusted_ip,log_trusted_port,log_remote_ip,log_remote_port,log_start_time,log_end_time,log_received,log_send) VALUES(NULL,'$common_name','$trusted_ip','$trusted_port','$ifconfig_pool_remote_ip','$remote_port_1',now(),'0000-00-00 00:00:00','$bytes_received','$bytes_sent')"
##set status online to user connected
mysql -h$HOST -P$PORT -u$USER -p$PASS $DB -e "UPDATE user SET user_online='yes' WHERE user_id='$common_name'"
vim /etc/openvpn/scripts/disconnect.sh
#!/bin/bash
. /etc/openvpn/scripts/config.sh
##set status offline to user disconnected
mysql -h$HOST -P$PORT -u$USER -p$PASS $DB -e "UPDATE user SET user_online='no' WHERE user_id='$common_name'"
##insert data disconnected to table log
mysql -h$HOST -P$PORT -u$USER -p$PASS $DB -e "UPDATE log SET log_end_time=now(),log_received='$bytes_received',log_send='$bytes_sent' WHERE log_trusted_ip='$trusted_ip' AND log_trusted_port='$trusted_port' AND user_id='$common_name' AND log_end_time='0000-00-00 00:00:00'"

Change the permission of the files we just created

chmod 755 /etc/openvpn/scripts/*.sh

Create the password file for accessing OpenVPN management interface via telnet

echo "wYYoFlaQa8nGQoO8" > /etc/openvpn/pw-management-file
chmod 600 /etc/openvpn/pw-management-file

Configure OpenVPN

vim /etc/openvpn/vpn.example.org.conf
##general settings
port 1194
proto udp
dev tun

##keys
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/vpn.example.org.crt
key /etc/openvpn/keys/vpn.example.org.key
dh /etc/openvpn/keys/dh2048.pem

##FIXME: ip for the clients
server 10.0.1.0 255.255.255.0
ifconfig-pool-persist ipp.txt
##FIXME: routes pushed to the client
push "route 172.16.1.0 255.255.255.0"
push "route 10.0.0.0 255.0.0.0"
push "route 195.248.229.19 255.255.255.255"

##Auth
comp-lzo
user nobody
#group nogroup
client-to-client
#client-cert-not-required
username-as-common-name

##user/pass auth from mysql
plugin /usr/lib/openvpn/openvpn-auth-pam.so openvpn

##script connect-disconnect
script-security 3 system
client-connect /etc/openvpn/scripts/connect.sh
client-disconnect /etc/openvpn/scripts/disconnect.sh

##management
management localhost 1194 pw-management-file

keepalive 10 120
persist-key
persist-tun
status status.log
verb 3

Start OpenVPN

/etc/init.d/openvpn start

Note: I also created a script to manage OpenVPN users. If you would like to have it, please post a comment.
Note2: feel free to use my user management script! I am pretty sure it has a lot of bugs and things to improve!!! Use it on your own risk!

the 2 notes are written by original author.

OPENVPN使用PAM及MYSQL进行用户认证【转】

1.使用PAM模块
PAM简介:
Pluggable Authentication Module (PAM) 是行业标准验证框架。
PAM 为系统管理员提供了选择系统上可用的任何验证服务来执行验证的灵活性。使用 PAM 框架还可以插入新的验证服务模块,并且无需修改应用程序即可使用,

包含帐户管理,用户验证,口令管理,会话管理四个模块.指定如何处理同一个 service-name 和 module-type 的多个定义的关键字。它为下列值之一
required模块测试必须成功。
optional模块测试可以失败。
sufficient如果测试成功,则不执行进一步的测试。

1>OPENVPN服务器端配置:

plugin /usr/sharelib/openvpn-auth-pam.so login //指定模块的位置,该动态链接库在OPENVPN发生包里需要编译
client-cert-not-required //客户端数字证书无需指定
username-as-common-name //用户名作为common name

2>OPENVPN客户端配置:

auth-user-pass

3>服务器设置:
需要增加相应的用户名及密码,使用useradd password命令
重新启动OPENVPN,则在客户端登录OPENVPN的时候会提示输入用户名及密码

2.使用PAM-MYSQL
1>安装MYSQL,添加用户名vpn 密码设置为vpn,用户表为库openvpn中的user

2>安装pam_mysql ,下载位置http://internap.dl.sourceforge.net/sourceforge/pam-mysql/pam_mysql-0.5.tar.gz

3>配置pam配置文件,在/etc/pam.d中新建openvpn内容如下

auth    required        pam_mysql.so          user=vpn passwd=vpn host=192.168.1.11 db=openvpn table=user usercolumn=username passwdcolumn=password
account required        pam_mysql.so                   user=vpn passwd=vpn host=192.168.1.11 db=openvpn   table=user usercolumn=username   passwdcolumn=password

注意:将pam_mysql.so文件拷入 /lib/security/位置;并且保证系统中有libmysqlclient.so文件,如果连接远程MYSQL数据库无需此文件

4>OPENVPN服务器配置
plugin /usr/sharelib/openvpn-auth-pam.so openvpn 其余配置与上同//加载/etc/pam.d/openvpn配置文件

5>客户端配置与上同

Linux-PAM系统管理指南[转]

来自:http://doc.linuxpk.com/5214.html
联系:linuxmine#gmail.com

Linux-PAM是一组共享库,使用这些模块,系统管理者可以自由选择应用程序使用的验证机制。也就是说,勿需重新编译应用程序就可以切换应用程序 使用的验证机制。甚至,不必触动应用程序就可以完全升级系统使用的验证机制。(2002-07-09 13:08:42)
Read More »