PPTP+FreeRADIUS+MySQL搭建VPN认证和流量控制
最近帮论坛上朋友建了个OpenVPN+PPTP的VPN服务器,记下来过程以备不时之需。
系统环境是CentOS 5.6 xen,所有过程中软件均从源码编译。
需要软件:
PopTop: http://poptop.sourceforge.net/
PPPd: http://ppp.samba.org/
FreeRADIUS: http://freeradius.org/
RADIUSClient: http://wiki.freeradius.org/Radiusclient
MySQL: http://www.mysql.com/
同时为了方便管理数据库,最好再装个php,使用phpmyadmin来管理。
编译过程很简单,pptpd、pppd和freeradius都是
./configure && make && make install
就可以了。
完成之后freeradius的启动脚本在redhat/里面,pptpd需要自己写一个,很简单:
#!/bin/sh
#
# Startup script for pptpd
#
# chkconfig: 345 40 70
# description: PPTP server
# processname: pptpd
# config: /etc/pptpd.conf
# Source function library.
. /etc/rc.d/init.d/functions
# See how we were called.
case "$1" in
start)
echo -n "Starting pptpd: "
if [ -f /var/lock/subsys/pptpd ] ; then
echo
exit 1
fi
/usr/local/sbin/pptpd -d
echo
touch /var/lock/subsys/pptpd
;;
stop)
echo -n "Shutting down pptpd: "
killproc pptpd
echo
rm -f /var/lock/subsys/pptpd
;;
status)
status pptpd
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
esac
exit 0
--------------------------------------------------------------------------------
然后修改一些FreeRADIUS的配置文件,位于/usr/local/etc/raddb/
sites-enabled/default
在所有的unix和files前面加上注释,并去掉所有sql前面的注释。
radiusd.conf
去掉include sql.conf前面的注释。
clients.conf
这个文件控制连接的客户端的地址以及secret code。
secret要记下来,测试和写配置文件的时候要用。默认是testing123
sql.conf
这个文件控制连接到sql的参数。
改成实际数据库的用户名和密码。
sql/mysql/dialup.conf
取消
sql_user_name = "%{%{Stripped-User-Name}:-%{%{User-Name}:-none}}"
前面的注释,把下一行注释掉。
同时如果需要打开simultanoues-use(控制同时在线用户数)的话需要把simul_query_check取消注释。
--------------------------------------------------------------------------------
然后建立基本数据库:
/usr/local/mysql/bin/mysql -uroot -p
create database radius; grant all privileges on radius.* to radius@localhost identified by "radiuspassword"; flush privileges; exit;
/usr/local/mysql/bin/mysql -uradius -p radius < /usr/local/etc/raddb/sql/mysql/schema.sql
建立表格:
INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('user','Auth-Type',':=','Local');
INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('user','Service-Type',':=','Framed-User');
INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('user','Framed-IP-Address',':=','255.255.255.255');
INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('user','Framed-IP-Netmask',':=','255.255.255.0');
INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('user','Acct-Interim-Interval',':=','600');
INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('user','Max-Monthly-Traffic',':=','5368709120');
INSERT INTO radgroupcheck (groupname,attribute,op,VALUE) VALUES ('user','Simultaneous-Use',':=','1');
以上前四行不用改动,acct-interim-interval是计算流量的间隔(600秒),意味着每隔10分钟记录当前流量。倒数第二行是每月最大流量,这里是5G(单位是字节)。最后一行是允许同时连接数目。
--------------------------------------------------------------------------------
输入测试用户信息:
INSERT INTO radcheck (username,attribute,op,VALUE) VALUES ('test','Cleartext-Password',':=','test');
INSERT INTO radusergroup (username,groupname) VALUES ('test','user');
用户名与密码必须以明文/NTLM Crypt形式保存,因为MS-CHAPv2不支持MD5保存的密码。
--------------------------------------------------------------------------------
由于上步中有非内置的attribute Max-Monthly-Traffic,所以需要在/usr/local/etc/raddb/dictionary里面定义:
ATTRIBUTE Max-Monthly-Traffic 3003 integer
--------------------------------------------------------------------------------
初步测试:
/etc/init.d/freeradius stop radiusd -X & radtest test test localhost 1649 testing123
如果结果中有Access-Accept就代表成功了,否则退回去检查设置。
测试成功的话添加在认证时检测流量的语句,打开/usr/local/etc/raddb/sites-enabled/default,找到authorize一节插入:
update request {
Group-Name := "%{sql:SELECT groupname FROM radusergroup WHERE username='%{User-Name}' ORDER BY priority}"
}
if ("%{sql: SELECT SUM(acctinputoctets+acctoutputoctets) FROM radacct WHERE username='%{User-Name}' AND date_format(acctstarttime, '%Y-%m-%d') >= date_format(now(),'%Y-%m-01') AND date_format(acctstoptime, '%Y-%m-%d') <= last_day(now());}" >= "%{sql: SELECT value FROM radgroupreply WHERE groupname='%{Group-Name}' AND attribute='Max-Monthly-Traffic';}") {
reject
}
--------------------------------------------------------------------------------
设置radiusclient:
打开/usr/local/etc/radiusclient/radiusclient.conf,修改
authserver localhost:1812
acctserver localhost:1813
修改server:
最后加上localhost secret(就是FreeRadius的client.conf里面定义的secret)
修改dictionary:
最后加上
INCLUDE /usr/local/etc/radiusclient/dictionary.merit
INCLUDE /usr/local/etc/radiusclient/dictionary.microsoft
如果没有dicitionary.microsoft的话看这里:http://wiki.freeradius.org/PopTop
--------------------------------------------------------------------------------
一切正常后设置pptp:
把源码包里面的options.pptpd和pptpd.conf拷到/etc/
修改options.pptpd:
取消ms-dns前面的注释,后面的ip改为8.8.8.8
加入一行noaccomp,以提供对iOS 4.3+的支持(否则连上就断)。
最后加上插件:
plugin /usr/local/lib/pppd/2.4.5/radius.so
plugin /usr/local/lib/pppd/2.4.5/radattr.so
radius-config-file /usr/local/etc/radiusclient/radiusclient.conf
修改pptpd.conf:
ppp路径改为/usr/local/sbin/pppd
option路径为/etc/options.pptpd
注释掉logwtmp避免619错误
最后的localip根据需要设置
示例:localip 192.168.100.1
remoteip 192.168.100.100-150
重 要的一点:一定要注释掉delegate,之前没有注释结果连接的时候log显示LCP terminated by peer跟着一堆乱码直接掉线,客户端则显示720,注释掉就好了。(虽然个人认为不应该注释,因为delegate的作用是让radius来处理ip分 配)
启动服务测试下是否能连接,多用radiusd -X看输出信息。
--------------------------------------------------------------------------------
最后是相应的iptables设置:/etc/sysconfig/iptables
nat里面加入:
-A POSTROUTING -s 192.168.100.0/255.255.255.0 -o eth0 -j MASQUERADE
filter里面加入:
-A INPUT -i lo -j ACCEPT
-A INPUT -i ! lo -d 127.0.0.0/8 -j REJECT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -j ACCEPT
-A INPUT -p gre -j ACCEPT
-A INPUT -p tcp -m state --state NEW --dport 1723 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -j REJECT
-A FORWARD -i ppp+ -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j TCPMSS --set-mss 1356
设置mss以防止过大的包被丢弃,从而造成无法载入。
大功告成!
本文参考:
http://wiki.freeradius.org/PopTop
http://freeradius.1045715.n5.nabble.com/group-variable-td2776238.html
http://hi.baidu.com/ox188/blog/item/4ae1373f33d90fe455e723a4.html
http://www.accountingenhancements.com/filetree/pptp-HOWTO-linux-2.6.9.txt
http://discussions.apple.com/thread.jspa?threadID=2778039&start=60&tstart=0
Tags: FreeRADIUS, MySQL, PPTP, VPN
Posted in VPN, 折腾 | 22 Comments »
看了此文,收益匪浅!今天又看了半天的文档。
就为了解决用户不正常掉线,会在radacct留下一个acc*stop的字段为NULL的情况。而freeradius判读是否多用户在线,就是查询一个用户名在这个表中有几个NULL。在这种情况下,如果设置只允许单用户登录,那么这个帐号将无法登录,不知道,这个问题应该怎么解决,求教。
不正常掉线数据库里面会有Lost-Carrier,应该不会影响记录的,除非你的Freeradius/Mysql/Radiusplugin没有正常运行。
plugin /usr/local/lib/pppd/2.4.5/radattr.so
radius-config-file /usr/local/etc/radiusclient/radiusclient.conf
我配置的时候一直没加这两个,可以正常运行。而且,在看到您这篇博文之前,一直没有人提到这两个文件。我觉得,最后一个radius的配置文件其实不加也行,因为radius主要实现的是认证,ppp就提供一个链接。ppp不需要知道radius都干了什么。
Radiusclient里面规定了Freeradius的连接方式吧(1812和1813端口)
plugin /usr/local/lib/pppd/2.4.5/radattr.so
radius-config-file /usr/local/etc/radiusclient/radiusclient.conf
这两个插件是干什么的阿?我是通过yum安装的freeradius2。在这个插件里,我只添加了radius.so。
Radiusclient是帮助pppd和freeradius联系的……是Radiusclient的配置文件,必须调用的。
大哥,我已经给你加友情链接了……虽然我的pr值只有2……还希望你别嫌弃给我也加个友链吧
没问题,我的pr才1呢。呵呵
update request {
Group-Name := "%{sql:SELECT groupname FROM radusergroup WHERE username='%{User-Name}' ORDER BY priority}"
}
if ("%{sql: SELECT SUM(acctinputoctets+acctoutputoctets) FROM radacct WHERE username='%{User-Name}' AND date_format(acctstarttime, '%Y-%m-%d') >= date_format(now(),'%Y-%m-01') AND date_format(acctstoptime, '%Y-%m-%d') = "%{sql: SELECT value FROM radgroupreply WHERE groupname='%{Group-Name}' AND attribute='Max-Monthly-Traffic';}") {
reject
}
这个query我尝试了……不知道为什么确不能对流量已经超限的用户reject。接着研究吧……
date_format(acctstoptime, '%Y-%m-%d') <= "%{sql: SELECT value FROM radgroupreply WHERE groupname='%{Group-Name}'
有个小于符号你打掉了。Wordpress处理这个有点问题,我的blog文章里面无法打出来<=,Wordpress老是自动加了个空格在中间。
组的default怎么设置阿?
以files为基础的,可以直接写个default,用sql的怎么写呢?
另外,那个优先级是干什么的阿?我在文档里没找到这个说明radusergroup表的优先级。
你是说radgroupreply?
priority无所谓的
装个代码插件呗~
试过wp-syntax,行长度不对,估计css有问题懒得改了
嗯,我现在也懒了,折腾太麻烦了~
奇怪,为什么我看不到回复呢?
应该是我WP Super Cache的问题
流量检测的语句有问题,多了一个空格 < = last_day(now());}" ,应该是<= last_day(now());}"
wordpress自动加的……
请教一下,为什么我编译完,在/usr/local/etc/raddb/里面没有任何文件呢?
记得不是很清楚了,在源代码的包里面找一下应该有
[...] 在PPTP VPN服务器上配置FreeRADIUS+DaloRADIUS实现用户跟踪管理 PPTP+FreeRADIUS+MySQL搭建VPN认证和流量控制 ARA (ASN RADIUS admin) – FreeRADIUS [...]