基于用户名密码认证和流量控制的OpenVPN系统的实现.docx
- 文档编号:27892217
- 上传时间:2023-07-06
- 格式:DOCX
- 页数:13
- 大小:19.49KB
基于用户名密码认证和流量控制的OpenVPN系统的实现.docx
《基于用户名密码认证和流量控制的OpenVPN系统的实现.docx》由会员分享,可在线阅读,更多相关《基于用户名密码认证和流量控制的OpenVPN系统的实现.docx(13页珍藏版)》请在冰豆网上搜索。
基于用户名密码认证和流量控制的OpenVPN系统的实现
基于用户名密码认证和流量控制的OpenVPN系统的实现
前一阵子,弄到了一个非常便宜的VPS服务器,位置在美国亚利桑那州的凤凰城,线路可以,速度不错,于是乎在上面架起了OpenVPN服务器,以便在“特殊条件”下“更加安全地访问网络”。
由于每个月1TB的流量无论如何是用不完的,打算把它分享给朋友们一起用。
为了防止被滥用,需要实现OpenVPN系统的用户认证和流量控制。
考虑到方便性,需要UDP、TCP协议同时支持。
经过一番研究,将其实现方法记录如下。
一、OpenVPN的基本安装与配置
以Debian5.0系统为例。
主要包括OpenVPN服务器程序的安装和证书的生成。
1、下载安装OpenVPN
apt-getinstallopenvpn
2、生成证书
复制生成证书的脚本:
cp-R/usr/share/doc/openvpn/examples/easy-rsa//etc/openvpn/
修改证书的变量:
cd/etc/openvpn/easy-rsa/2.0/
nanovars
编辑该文件,将最后几行的变量改成自己的,例如
exportKEY_COUNTRY="CN"
exportKEY_PROVINCE="BJ"
exportKEY_CITY="Beijing"
exportKEY_ORG="XX"
exportKEY_EMAIL="xxx@"
保存退出后,运行脚本设置变量,并清理:
source./vars
./clean-all
之后就可以生成公钥和私钥证书了,一路回车默认值或yes即可:
./build-ca
./build-key-serverserver
./build-keyclient1
./build-dh
实际上,对于用户名/密码认证机制来说,client1可以省略掉。
二、基于MySQL的用户名/密码认证实现
1、安装MySQLServer
apt-getinstallmysql-server
已安装的可以略过。
2、建立数据库
以管理员身份登录MySQL:
mysql-uroot-p
运行以下SQL命令:
--创建数据库
CREATEDATABASEopenvpn;
--切换数据库
USEopenvpn;
--创建用户,用户名openvpn,密码openvpn(可自行设定)
GRANTALLONopenvpn.*TO'openvpn'@'localhost'IDENTIFIEDBY'openvpn';
--创建用户数据表
CREATETABLEIFNOTEXISTS`user`(
`username`char(32)COLLATEutf8_unicode_ciNOTNULL,
`password`char(128)COLLATEutf8_unicode_ciDEFAULTNULL,
`active`int(10)NOTNULLDEFAULT'1',
`creation`timestampNOTNULLDEFAULTCURRENT_TIMESTAMP,
`name`varchar(32)COLLATEutf8_unicode_ciNOTNULL,
`email`char(128)COLLATEutf8_unicode_ciDEFAULTNULL,
`note`textCOLLATEutf8_unicode_ci,
`quota_cycle`int(10)NOTNULLDEFAULT'30',
`quota_bytes`bigint(20)NOTNULLDEFAULT'10737418240',
`enabled`int(10)NOTNULLDEFAULT'1',
PRIMARYKEY(`username`),
KEY`idx_active`(`active`),
KEY`idx_enabled`(`enabled`)
)DEFAULTCHARSET=utf8COLLATE=utf8_unicode_ci;
--创建日志数据表
CREATETABLEIFNOTEXISTS`log`(
`username`varchar(32)COLLATEutf8_unicode_ciNOTNULL,
`start_time`timestampNOTNULLDEFAULTCURRENT_TIMESTAMP,
`end_time`timestampNOTNULLDEFAULT'0000-00-0000:
00:
00',
`trusted_ip`varchar(64)COLLATEutf8_unicode_ciDEFAULTNULL,
`trusted_port`int(10)DEFAULTNULL,
`protocol`varchar(16)COLLATEutf8_unicode_ciDEFAULTNULL,
`remote_ip`varchar(64)COLLATEutf8_unicode_ciDEFAULTNULL,
`remote_netmask`varchar(64)COLLATEutf8_unicode_ciDEFAULTNULL,
`bytes_received`bigint(20)DEFAULT'0',
`bytes_sent`bigint(20)DEFAULT'0',
`status`int(10)NOTNULLDEFAULT'1',
KEY`idx_username`(`username`),
KEY`idx_start_time`(`start_time`),
KEY`idx_end_time`(`end_time`)
)DEFAULTCHARSET=utf8COLLATE=utf8_unicode_ci;
3、安装pam_mysql模块
apt-getinstalllibpam-mysql
4、配置OpenVPN的PAM
nano/etc/pam.d/openvpn
输入以下内容:
authsufficientpam_mysql.souser=openvpnpasswd=openvpnhost=localhostdb=openvpntable=userusercolumn=usernamepasswdcolumn=passwordwhere=active=1sqllog=0crypt=1
accountrequiredpam_mysql.souser=openvpnpasswd=openvpnhost=localhostdb=openvpntable=userusercolumn=usernamepasswdcolumn=passwordwhere=active=1sqllog=0crypt=1
其中数据库、用户名、密码按照自己的实际情况设置。
crypt表示密码在数据库中加密存储的方式,含义如下:
0(or“plain”):
不加密,明文存储。
不推荐使用。
1(or“Y”):
使用crypt(3)函数,相当于MySQL中的ENCRYPT()函数。
2(or“mysql”):
使用MySQL的PASSWORD()函数。
PAM可能与MySQL的函数不同,不推荐使用。
3(or“md5″):
使用MD5。
4(or“sha1″):
使用SHA1。
MD5我试用过有些问题。
最后我使用的是1。
之后重启saslauthd:
/etc/init.d/saslauthdrestart
如果出现以下提示:
Toenablesaslauthd,edit/etc/default/saslauthdandsetSTART=yes(warning).
说明saslauthd未配置成自动启动,则需修改/etc/default/saslauthd文件,将START=no改为START=yes,再重启服务即可。
5、测试saslauthd是否配置成功
登入MySQL数据库:
mysql-uopenvpn-p
执行以下命令:
USEopenvpn;
INSERTINTOuser(username,password)VALUES('test',ENCRYPT('123456'));
退出后,运行以下命令:
testsaslauthd-utest-p123456-sopenvpn
如果显示
0:
OK"Success."
则说明配置成功。
否则,请根据/var/log/auth.log日志查找原因。
6、复制OpenVPNPAM认证模块
cp/usr/lib/openvpn/openvpn-auth-pam.so/etc/openvpn/
7、编写OpenVPN配置文件。
OpenVPN服务启动时,会扫描/etc/openvpn目录中的.conf文件,对于每个文件,启动一个daemon。
本系统要实现UDP、TCP登录的同时支持,我的做法是写两份配置文件,即启动两个daemon,分别负责UDP和TCP协议。
nano/etc/openvpn/
输入以下内容
devtun
protoudp
port1194
ca/etc/openvpn/easy-rsa/2.0/keys/ca.crt
cert/etc/openvpn/easy-rsa/2.0/keys/server.crt
key/etc/openvpn/easy-rsa/2.0/keys/server.key
dh/etc/openvpn/easy-rsa/2.0/keys/dh1024.pem
usernobody
groupnogroup
server10.8.0.0255.255.255.0
keepalive20120
persist-key
persist-tun
#user/passauthfrommysql
plugin./openvpn-auth-pam.soopenvpn
client-cert-not-required
username-as-common-name
client-to-client
push"redirect-gatewaydef1"
push"dhcp-optionDNS8.8.8.8"
push"dhcp-optionDNS8.8.4.4"
comp-lzo
max-clients15
statusstatus/udp.log
log-append/var/log/openvpn/udp.log
verb3
mute5
其中,#user/passauthfrommysql下面的几行是该认证设置的关键所在。
同理,如果想支持TCP,建立一个openvpn-tcp.conf文件,内容跟上面相同,仅仅把
protoudp
server10.8.0.0255.255.255.0
statusstatus/udp.log
log-append/var/log/openvpn/udp.log
改为
prototcp
server10.10.0.0255.255.255.0
statusstatus/tcp.log
log-append/var/log/openvpn/tcp.log
即可。
同时,为日志和状态文件建立目录:
mkdir/etc/openvpn/status
mkdir/var/log/openvpn
重启OpenVPN服务:
/etc/init.d/openvpnrestart
8、设置iptables
nano/etc/rc.local
在exit0之前添加以下几行:
#iptablesforOpenVPN
iptables-tnat-APOSTROUTING-s10.8.0.0/24-ovenet0-jSNAT--toxxx.xxx.xxx.xxx
iptables-tnat-APOSTROUTING-s10.10.0.0/24-ovenet0-jSNAT--toxxx.xxx.xxx.xxx
其中xxx.xxx.xxx.xxx是你的服务器的IP地址。
然后让其生效:
/etc/rc.local
至此,一个用户名/密码认证的OpenVPN系统就配置完成了。
客户端下载使用/etc/openvpn/easy-rsa/2.0/keys/ca.crt作为证书文件,用用户名、密码认证,即可连接。
一个典型的客户端配置文件如下:
client
devtun
protoudp
remote1194
resolv-retryinfinite
nobind
persist-key
persist-tun
caca.crt
auth-user-pass
comp-lzo
verb3
其中替换为服务器的域名或IP地址。
用刚才建立的test/123456用户连接一下试试吧!
9、“PAMunabletodlopen(/lib/security/pam_mysql.so):
/lib/security/pam_mysql.so:
undefinedsymbol:
pam_get_item”错误的解决办法
我在Debian5中,遇到了如上的错误(/var/log/auth.log),导致OpenVPN提示认证失败。
解决方法如下:
echo"/lib/libpam.so.0">>/etc/ld.so.preload
/etc/init.d/saslauthdrestart
/etc/init.d/openvpnrestart
三、流量控制的实现
总体思路:
利用OpenVPN程序在连接、断开时的脚本钩子,将用户的使用信息记录到数据库。
根据数据库中的日志,判断用户是否超过流量配额,如果超过,则将用户锁定。
1、连接、断开时的脚本
建立文件/etc/openvpn/connect.sh,内容如下:
#!
/bin/bash
DB='openvpn'
DBADMIN='openvpn'
DBPASSWD='openvpn'
mysql-u$DBADMIN-p$DBPASSWD-e"INSERTINTOlog(username,start_time,trusted_ip,trusted_port,protocol,remote_ip,remote_netmask,status)VALUES('$common_name',now(),'$trusted_ip',$trusted_port,'$proto_1','$ifconfig_pool_remote_ip','$route_netmask_1',1)"$DB
建立文件/etc/openvpn/disconnect.sh,内容如下:
#!
/bin/bash
DB='openvpn'
DBADMIN='openvpn'
DBPASSWD='openvpn'
mysql-u$DBADMIN-p$DBPASSWD-e"UPDATElogSETend_time=now(),bytes_received=$bytes_received,bytes_sent=$bytes_sent,status=0WHEREtrusted_ip='$trusted_ip'ANDtrusted_port=$trusted_portANDremote_ip='$ifconfig_pool_remote_ip'ANDusername='$common_name'ANDstatus=1"$DB
mysql-u$DBADMIN-p$DBPASSWD-e"UPDATEuserSETactive=0WHEREuser.usernameIN(SELECTusernameFROM(SELECTlog.usernameASusername,quota_bytesFROMuser,logWHERElog.username='$common_name'ANDlog.username=user.usernameANDlog.status=0ANDTO_DAYS(NOW())-TO_DAYS(start_time)<=quota_cycleGROUPBYlog.usernameHAVINGSUM(bytes_received)+SUM(bytes_sent)>=quota_bytes)ASu);"$DB
将文件改为可执行属性:
chmod+x/etc/openvpn/connect.sh
chmod+x/etc/openvpn/disconnect.sh
修改OpenVPN配置文件openvpn-udp.conf、openvpn-tcp.conf,添加以下几行:
#recordindatabase
script-security2
client-connect./connect.sh
client-disconnect./disconnect.sh
其主要作用是:
在用户连接时,在数据库log表中新建一条记录,记录用户的IP地址、端口号、连接时间等信息。
在用户断开连接时,更新刚才添加的记录,记下用户的断开连接时间、发送数据量、接收数据量等。
然后,对用户的流量进行判断,若超过配额,则将用户锁定(active=0)。
user表中的quota_cycle是用户的流量计算周期,quota_bytes是用户每个周期内最多允许的流量。
connect.sh和disconnect.sh脚本文件中调用了OpenVPN的环境变量。
OpenVPN在执行脚本时,自动各种设置了环境变量,供脚本使用。
具体的环境变量可以查看这里。
2、使用cron每天对用户进行检查
以上操作在用户超过流量时自动将用户锁定。
每天还应该执行一次检查,把已经恢复流量的用户解锁。
可以通过cron实现此功能。
建立文件/etc/cron.daily/openvpn,内容如下:
#!
/bin/bash
DB='openvpn'
DBADMIN='openvpn'
DBPASSWD='openvpn'
mysql-u$DBADMIN-p$DBPASSWD-e"UPDATEuserSETactive=1"$DB
mysql-u$DBADMIN-p$DBPASSWD-e"UPDATEuserSETactive=0WHEREuser.usernameIN(SELECTusernameFROM(SELECTlog.usernameASusername,quota_bytesFROMuser,logWHERElog.username=user.usernameANDlog.status=0ANDTO_DAYS(NOW())-TO_DAYS(start_time)<=quota_cycleGROUPBYlog.usernameHAVINGSUM(bytes_received)+SUM(bytes_sent)>=quota_bytes)ASu);"$DB
mysql-u$DBADMIN-p$DBPASSWD-e"UPDATEuserSETactive=0WHEREenabled=0"$DB
其思路是:
先默认将所有用户解锁,然后将超过流量的用户锁定。
同时,管理员可以通过user表中的enabled字段手工禁用用户。
然后给文件可执行权限:
chmod+x/etc/cron.daily/openvpn
3、修改saslauthd的缓存时间
saslauthd默认有一段较长的缓存时间,在用户通过认证后的一段时间里,可以再次通过认证而不需要重新查询数据库。
这样不利于实现对超流量用户的立即锁定。
saslauthd启动时有一个-t参数,可以设置其超时时间。
修改/etc/default/saslauthd文件,将
OPTIONS="..."
一行,引号最后添上-t60,可将缓存时间设置为60秒。
当然,也可直接将其设置为0,即不缓存。
重启saslauthd服务和OpenVPN,使设置生效:
/etc/init.d/saslauthdrestart
/etc/init.d/openvpnrestart
综上所述,一个简单的基于用户名/密码认证和流量控制的OpenVPN系统就初步形成了。
沿用这个思路,我们还可以通过对连接、断开时间的统计,很容易地实现对用户在线时间的控制。
另外,我们还可以借助tc命令,实现对用户连接速率的控制。
更进一步,可以做一个Web界面,使用户能够修改密码、查询历史记录、查询流量等。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 用户名 密码 认证 流量 控制 OpenVPN 系统 实现