3COM公司的SuperStack II Remote Access System 1500为中小型企业和Internet 服务提供商提供全面的远程访问服务。其在一个平台中集成了非常广泛的功能,以较低的设备开支,提供了拨入/拨出访问、采用拨号或帧中继和专线PPP连接的局域网间路由选择功能。其具有以下这些特点:
* 易于安装。基于HTML浏览器的安装向导、图形用户界面(GUI)和文档浏览。
* 先进、易于操作。NAT/PAT地址转换功能提供低成本高效率的共享ISP访问。DHCP服务器、中继和代理功能为本地和远程用户提供了简捷的LAN访问方式。
* 访问方式安全。包括本地验证,并可与RADIUS、 Windows NT 或NetWare NOS 服务器配合实现远程验证功能。
* I/O单元模块化。模块化单元,便于I/O卡的添加和扩展以及PRI访问单元的热插拔。
* Univerrsal ConnectTM技术。通过同一基本速率的 ISDN 连接,提供了业界领先的模拟连接方式(速率可高达V.90)和 ISDN 拨入访问方式。
* 可伸缩性。将 ISDN 和模拟连接方式集于一身,端口范围为4至24端口,可以随着您的需要进行扩展。
3COM RAS1500以较低价位为要求严格的用户提供了企业级网络的功能和优异性能,因此成为当前国内小型ISP首选的远程接入服务器 (Remonte Network Access Server),在国内各个小型ISP得到了广泛的应用。但是,虽然RAS1500可以通过网管软件 Transcend Network Supervisor (TNS)提供功能强大易用的记费认证功能,能满足中小型企业的需求,但是其昂贵的价格使小型ISP望而却步。因此如何以较低的价格实现RAS1500的认证和记费就成为当前使用RAS1500的小型ISP的难以解决问题。
本文讨论了如何使用linux作为3comRas1500的radius服务器,实现集中化的认证和记费功能,以减少管理的负担和费用。这里实现的radius服务器可以实现拨号用户的集中管理,可以实现拨号用户账号和系统账号集成或分开;并且在拨号账户独立时,实现web界面的管理,如:察看详细的log信息及各个用户的记账信息;实现用户拨号时间的限定,当该用户拨号时间到达限定以后,自动断开,而且不能再拨入。还可以实现用户的月拨号时间限定,每个月该用户只能使用限额的时间等等。
1.radius协议原理
Radius是Remote Authentication Dial In User Service-远程拨入用户认证服务的简写。其定义了在NAS(Network Access Server,拨号服务器,如:pastmaster,3com rs1500等)和集中存放认证信息的 radius服务器之间传输认证、授权和配置信息的协议。其协议的标准最新的定义在rfc2865和rfc2866中,也可以在http://www.freeradius.org/处得到相关的rfc。RADIUS以Client/Server模式工作,实现了对远程电话拨号用户的身份认证、授权和计费功能。其Client端多为网络访问服务器(NAS),主要用来将用户信息传递给Server;Server则对用户进行认证,并反回用户的配置信息。为保证传输的安全性,在 Client和Server之间传送的数据均以MD5方式加密。RADIUS Server端和Client端通信主要有两种情况,一种是接入认证,另一种是计费请求。
RADIUS是一种基于UDP协议的上层协议,认证服务的监听端口号为1812,记费服务的监听端口号为1813。标准的RADIUS数据包的结构包括Code、ID、Length、Authenticator和Attributes几部分。
Code表示该包的类型。ID号区分不同消息并给予相应的应答。Length为该RADIUS包的总长度,Authenticator 是供 MD5加密使用的字符串。Attributes则对应包中具体内容,Attributes包括三个部分:type、length、value。type表示该Attribute的具体含义;length为该type的长度;value是该type的具体值。
1.1接入请求 (Access-Request)
type length
01 USERNAME(以00为结束) ≥3(其长度为加入00后的长度)
02 PASSWORD(以00为结束) 6
04 IP-ADDRESS 6(接入服务器NAS地址)
05 NAS-PORT 6(物理端口号)
3D PORT-TYPE 6
18 STATE ≥3(此处可不使用)
1F CALLING-STATION-ID ≥3(电话呼入被叫号)
IE CALLED-STATION-ID ≥3(电话呼入主叫号)
2C ACCT-SESSION-ID(以00为结束) ≥3(以00结束其长度为加入00后的长度)
当用户请求连接时,Client端给Server发送认证请求,在请求包中带有username、password、NAS_port等。 Server端收到该请求后会到users文件中查找对应信息,当用户的username和password正确时,Server会返回Access- Accept信息,否则返回Access-Reject信息。
1.2.同意接入 (Access-Accept)
type length
06 SERVICE-TYPE 6
07 FRAMED-PROTOCOL 6
其中, SERVICE-TYPE是用户的服务类型,大部分用户是Framed(其值为2);FRAMED-PROTOCOL则是用户所使用的协议,多为PPP(其值为1)或SLIP(其值为2)。Access-Accept包是由Server端发给Client端用户的数据包,此时 Server已认证通过了该用户,返回确认信号和该用户的配置参数.这些参数是在users文件中配入的。
1.3.拒绝接入 (Access-Reject)
无type位。Access-Reject包是用户认证不通过时,Server发送给client端的否认信号。
1.4.计费请求 (Accounting-Request)
type length
01 USERNAME(以00为结束) ≥3(其长度为加入00后的长度)
04 IP-ADDRESS 6
05 NAS-PORT 6
3D PORT-TYPE 6
28 ACCT-STATUS-TYPE 6(1:start;2:stop)
29 ACCT-DELAY-TIME 6
2C ACCT-SESSION-ID(以00为结束) ≥3(其长度为加入00后的长度)
2D ACCT-AUTHENTIC 6(1:RADIUS;2:local;3:remote)
2E ACCT-SESSION-TIME 6
1F CALLING-STATION-ID ≥3(被叫号)
1E CALLED-STATION-ID ≥3(主叫号)
07 FRAMED-PROTOCOL 6
08 FRAMED-IP-ADDRES 6(NAS地址)
2A ACCT-INPUT-OCTETS 6(仅用于stop中,表示多少字节从此端口输入)
2B ACCT-OUTPUT-OCTETS 6(仅用于stop中,表示多少字节从此端口送出)
2F ACCT-INPUT-PACKETS 6(仅用于stop中,表示多少包送给了用户)
计费请求信息分为两种情况:一是start即当用户认证通过并连接成功时发出的信息;一是stop即用户断链时发出的信息,通知该用户断链,停止计费。两者是由ACCT-STATUS-TYPE来区分的。Server记录这些信息到detail文件中,以供二次开发时使用。
1.5.计费应答 (Accounting- Response)
当Server收到Client端送来的计费请求时,会返回Accounting-Response包,告诉Client端已收到该信息,该包无type位。
上面为radius协议的简单的原理,但是笔者推荐在动手之前阅读rfc2865和rfc2866,这样可以在安装除错中解决很多问题。
2.下载安装必需的支持软件
这里介绍使用Linux环境下的radius服务器软件-icradius来实现radius服务器,其主页地址为:http://radius.innercite.com,当前最新版本为0.17。包括icradius一共需要下载以下软件:
* icradius http://icradius.hislora.com.au/
* perl http://www.perl.com
* mysql http://www.mysql.com
* Perl DBI http://www.mysql.com/downloads/contrib.html
* mySQL DBD Modules http://www.mysql.com/downloads/contrib.html
* perl的Authen::RADIUS模块 http://www.mirror.ac.uk/sites/ftp.internat.freebsd.org/pub/FreeBSD/packages-4.1 /All/p5-Authen-Radius-0.05.tgz[peek]
笔者是在内核版本2.2.14-5.0的Redhat6.2环境下,使用的icradius为0.17版;perl为redhat6.2自带的 5.005_03版;mysql下载的是rpm包形式发布的3.23.22-1的源代码;perl DBI为1.13版; mySQL DBD Modules为1.2214版本。所有的软件都为源代码方式下载。
2.1.Mysql的安装;
笔者使用的rpm包方式的源代码,因此首先要解开rpm包:
[root@radiusd ideal]# rpm -ivh MySQL-3.23.22-1.src.rpm
MySQL ##################################################
然后:
[root@radiusd ideal]# cd /usr/src/redhat/SOURCES/
[root@radiusd SOURCES]# ls -al
total 6432
drwxr-xr-x 2 root root 4096 Oct 29 14:07 .
drwxr-xr-x 7 root root 4096 Oct 30 2000 ..
-rw-r--r-- 1 root root 6560696 Jul 30 11:23 mysql-3.23.22-beta.tar.gz
-rw-rw-r-- 1 root root 3082 Jul 30 11:23 mysql.gif
[root@radiusd SOURCES]# tar xvgz mysql-3.23.22-beta.tar.gz
解压源代码包,就会在当前目录下生成mysql-3.23.22-beta的子目录,其中包含了mysql的源代码,然后使用下面的命令进行安装:
./configure
make
make install
scripts/mysql_install_db
就实现了Mysql数据库服务器安装,其中启动mysql服务器的命令为:
/usr/local/mysql/bin/safe_mysqld &
现在就实现了mysql数据库服务器的安装和运行,下面我们应当设立基本的用户权限信息。缺省的,mysql拥有一个缺省的具有对数据库完全访问可控制的用户,名字为root,所以首先应当为该用户添加访问密码:
[root@radiusd src]# mysql -u root mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 183 to server version: 3.23.22-beta
Type 'help' for help.
mysql>
这样就进入了mysql服务器的客户程序,然后发出sql语句命令:
UPDATE user SET Password = PASSWORD ('new_password') WHERE user = 'root';
FLUSH PRIVILEGES;
这里的new_password是为mysql的root用户设立的密码。但是一般推荐再创建一个权限和root完全相同的用户,命令如下:
INSERT INTO user
VALUES ('host','user','passwd',
'y','y','y','y','y','y','y','y','y','y','y','y','y','y');
一般,mysql与icradius服务器都是运行在同一个服务器上,这时候,host为localhost,若你的icradius服务器运行在另外一台服务器上,则你需要在这里设定host为你的icradius服务器的名字。用户为你设定的用户名,密码为该用户的密码。
2.2.perl DBI的安装
perl DBI的安装非常简单,只要解开压缩包:tar xvfz DBI-1.13.tar.gz,然后进入解开得到的子目录以后,发出如下的命令:
perl Makefile.PL
make
make test
make test TEST_VERBOSE=1 (若上一步出现了问题时,才使用该命令)
make install (只有在前面的测试通过以后才能发出该命令)
2.3.mySQL DBD Modules的安装
perl DBI的安装非常简单,只要解开压缩包:tar xvfz Msql-Mysql-modules-1.2214.tar
.gz 。然后进入解开得到的子目录以后,发出如下的命令:
perl Makefile.PL(会被询问以下问题:
[root@radiusd Msql-Mysql-modules-1.2214]# perl Makefile.PL
Which drivers do you want to install?
1) MySQL only
2) mSQL only (either of mSQL 1 or mSQL 2)
3) MySQL and mSQL (either of mSQL 1 or mSQL 2)
4) mSQL 1 and mSQL 2
5) MySQL, mSQL 1 and mSQL 2
Enter the appropriate number: [3] 1
### 在我们这里的需求,应该回答1
Do you want to install the MysqlPerl emulation? You might keep your old
Mysql module (to be distinguished from DBD::mysql!) if you are concerned
about compatibility to existing applications! [n] n 这里回答n
Where is your MySQL installed? Please tell me the directory that
contains the subdir 'include'. [/usr/local]
### 这是缺省的mysql安装目录,如果你按照上面的方式安装,
###则mysql自动被安装到这个目录下,则这里直接回车即可
Which database should I use for testing the MySQL drivers? [test] 直接回车即可
On which host is database test running (hostname, ip address
or host:port) [localhost]
### 若mysql服务器和icradius服务器安装在同一个服务器上 则这里直接回车即可
User name for connecting to database test? [undef] root
### 这里输入root
Password for connecting to database test? [undef] passwd
### 这里输入mysql的root用户的密码
make
make test
make install
2.4.perl的Authen::RADIUS模块的安装
首先,解压软件包 tar xvfz p5-Authen-Radius-0.05.tgz,则会在当前目录下生成文件+COMMENT、+CONTENTS、+DESC及+MTREE_DIRS和目录lib。然后创建目录:
mkdir /usr/lib/perl5/5.00503/Authen/
然后拷贝该perl模块到创建的目录下:
cp lib/perl5/site_perl/5.005/Authen/Radius.pm /usr/lib/perl5
/5.00503/Authen/
即可。
3.Icradius的安装配置
3.1.解压编译软件包:
tar xvfz icradius-0.17.tar.gz
cd icradius-0.17/src
然后拷贝针对linux的Make文件Makefile.lnx为Makefile:
Makefile.lnx Makefile
然后运行:
make
make install
3.2.创建radius数据库
首先需要创建数据库raidus:连接mysql数据库:
mysql -u root -pyourpassword
>CREATE DATABASE radius; ### 创建radius数据库
然后需要创建radius数据库需要的各个表格,这里要使用使用icradius-0.17目录下的script子目录下的radius.db文件,该文件已经定义了所需要的各个表格,这里只要使用命令:
mysql -u root -pyourpassword radius < radius.db
即可。这时就创建得到了radius认证计费所需要的各个表格。这里一共定义了以下表格:
Tables_in_radius
dictionary
hints
nas
radacct
radacct_summary
radcheck
radgroupcheck
radgroupreply
radreply
realmgroup
realms
usergroup
这里各个表格的含义大致是:
dictionary表格定义了在radius消息中的属性及属性值和其数字ID的对应关系,还定义了每个属性值允许的数据类型。
nas定义了该radius管理的访问服务器的信息,如其ip地址,设备名字等等。
radacct用来保存记账信息;
radacct_summary也是用来保存记账信息。
radcheck定义了当用户拨入时需要检查的属性,如:密码,时间限额等等。
radgroupcheck定义了某个组的成员在拨入时,需要检查的公共属性。每个用户都可以属于一个组
radgroupreply定义了该组成员在拨入验证通过以后,在应答信息内需要定义的属性及其对应的属性值。
radreply定义了成员在拨入验证通过以后,在应答信息内需要定义的属性及其对应的属性值。
usergroup定义了用户和组的对应关系。
3.3.填充各个表格
下一步需要向上面创建的各个数据库的表格中添加内容。
对于directionary表格的内容,icradius软件提供了一个脚本文件-script/dictimport.pl来创建,首先需要编辑该文件,修改my $dbusername = 'root';my $dbpassword = 'rootpass';为对应的数据库管理员的用户名和密码。然后运行该脚本如下:
[root@radiusd scripts]# ./dictimport.pl ../raddb/dictionary
对于3comRas1500来说,还需要加载usr的dictionary文件如下:
[root@radiusd scripts]# ./dictimport.pl ../raddb/dictionary.usr
第二需要向nas表格中添加内容如下,首先进入mysql:
[root@radiusd scripts]# mysql -u root -pszpzclljxk radius
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 30 to server version: 3.23.22-beta
Type 'help' for help.
mysql>
发出sql语言命令如下:
insert into nas
values (0,"3comras1500","ras1500","192.168.2.32","usr",24,"mlix1819",
"public","on");
这了,第一个字段含义为标示该nas设备的id号,为数字类型;第二个字段为设备名;第三个字段为设备的简称;第四个字段为设备的ip地址;第五个设备类型,对于3com设备类型为usr;第六个为设备的端口总数;第七个字段为radius服务器和nas之间共享的密码;第八个字段为snmp协议的共同体名;最后一个为snmp是否开放。
srcipts目录下的radius.cgi是一个实现web界面管理用户及记费信息的cgi程序,但是要在使用该脚本程序以前,首先要在radcheck表格中添加如下内容:
INSERT INTO radcheck VALUES ("","admin","Password","adminuserpassword");
INSERT INTO radcheck VALUES ("","admin","Radius-Operator","Yes");
这里,admin为radius的管理员用户名,adminuserpassword为管理员密码。
然后将radius.cgi和usage.cgi拷贝到www服务器的cgi-bin目录下,再编辑这两个文件,正确的设定数据库管理员的用户名和密码。然后指定两个文件中的$cookiedomain及$radhost为空。两个文件中的$radsecret指定为nas和radius共享的密码。
3.4.配置启动radiusd
在/etc/目录下创建子目录raddb:
[root@radiusd /etc]# mkdir /etc/raddb
在该目录下创建文件client,并设定其访问权限:
[root@radiusd raddb]# touch clients
[root@radiusd raddb]# chmod 664 clients
拷贝/home/radius/etc/raddb/目录下的radiusd.conf拷贝到/etc/raddb目录下:
[root@radiusd raddb]# cp /tmp/radius/etc/raddb/radius.conf /etc/raddb/
把/usr/src/icradius-0.17/raddb/中的除了radius.conf以外的所有文件拷贝到/etc/raddb目录中。
然后拷贝mysql的库文件到系统库目录中:
[root@radiusd /lib]# cp /usr/local/lib/mysql/* /lib
其中在/usr/icradius-0.17/redhat/目录下有一个名为rc.radiusd-redhat的文件,其是redhat环境下radiusd的启动文件,将其拷贝到/etc/rc.d/init.d目录下:
cp /usr/src/icradius-0.17/redhat/rc.radiusd-redhat /etc/rc.d/init.d/rc.radiusd
编辑文件/etc/raddb/radius.conf文件,将第5行中,password后面修改为mysql的管理员密码。
编辑文件/etc/rc.d/init.d/rc.radius,修改
RADIUSD=/usr/sbin/radiusd
WATCHER=/usr/sbin/radwatch
为
RADIUSD=/usr/local/sbin/radiusd
WATCHER=/usr/local/sbin/radwatch
拷贝/usr/src/icradius-0.17/scripts目录下的radwatch到/usr/local/sbin目录下。
拷贝/usr/src/icradius-0.17/scripts目录下的radiusd.cron.daily到/etc/cron.daily/目录下。
拷贝/usr/src/icradius-0.17/scripts目录下的radiusd.cron.monthly到/etc/cron.daily/目录下。
然后就可以启动radiusd了:/etc/rc.d/init/rc.radiusd start。
这个时候,px ax就应该看到下面这些进程:
19090 pts/1 S 0:00 sh /usr/local/bin/safe_mysqld
19114 pts/1 S 0:00 /usr/local/libexec/mysqld --basedir=/usr/local --data
19116 pts/1 S 0:00 /usr/local/libexec/mysqld --basedir=/usr/local --data
19117 pts/1 S 0:00 /usr/local/libexec/mysqld --basedir=/usr/local --data
19164 pts/1 S 0:00 sh /usr/local/sbin/radwatch /usr/local/sbin/radiusd -
19165 pts/1 S 0:00 /usr/local/sbin/radiusd -f -y
19167 pts/1 S 0:00 /usr/local/libexec/mysqld --basedir=/usr/local --data
19168 pts/1 S 0:00 /usr/local/libexec/mysqld --basedir=/usr/local --data
19169 pts/1 S 0:00 /usr/local/libexec/mysqld --basedir=/usr/local --data
19170 pts/1 S 0:00 /usr/local/libexec/mysqld --basedir=/usr/local --data
19171 pts/1 S 0:00 /usr/local/libexec/mysqld --basedir=/usr/local --data
19174 pts/1 S 0:00 /usr/local/sbin/radiusd -f -y
19175 pts/1 S 0:00 /usr/local/libexec/mysqld --basedir=/usr/local --data
察看系统开放的端口:nestat -l,输出中应该有以下内容:
udp 0 0 *:radacct *:*
udp 0 0 *:radius *:*
然后察看radius的log文件,最后应该是下面的内容:
Sun Oct 29 18:46:17 2000: Info: Starting - reading configuration files ...
Sun Oct 29 18:46:17 2000: Info: SQL: Attempting to connect to root@localhost:rad
ius
Sun Oct 29 18:46:18 2000: Info: Ready to process requests.
这就说明radius服务器已经成功的运行,这时候,应该按照3comras1500的SysManage.pdf中的shuoming正确的设置ras1500。
4.以web界面管理用户
上面的图是radius的管理界面,在这里输入radius管理员的用户名和密码,则可以进入下面所示的管理界面:
这个管理界面是浅显易懂的,这里我以最常见的情况为例子来说明如何添加用户。
首先创建一个组,该组具有所有用户都应该具有的特性,选择Manage Groups->Add New Group->为该组起一个名字:all_user->选择add group。
随后进入组属性设置界面,在这个界面里,在reply item中设置以下属性:
Reply Items
Attribute Value Check To Remove
Framed-IP-Address 255.255.255.254 ||
Framed-IP-Netmask 255.255.255.0 ||
Framed-Protocol PPP ||
Framed-Compression Van-Jacobson-TCP-IP ||
这里Framed-IP-Address为255.255.255.254表示由nas从自己的ip pool中选择一个ip地址分配给该用户。其他属性都是非常清楚的了。
然后添加用户:Manage Users->Add New user->为该用户组起一个名字:test,并设定该用户的密码 -> add user,然后就进入了用户属性设置界面,然后选择add to group -> 选择all_user组->确定,然后就可以看到,该用户的下面这些reply item:
Reply Items
Attribute Value Check To Remove Group
Framed-IP-Address 255.255.255.254 -- all_user
Framed-IP-Netmask 255.255.255.0 -- all_user
Framed-Protocol PPP -- all_user
Framed-Compression Van-Jacobson-TCP-IP -- all_user
若需要设置该用户的时间限额,则选择check item下面的add check item,选择Total-Time—Limte,后面输入时间限制的数字(时间单位为秒)因此三分钟的时间限额对应的Total-Time—Limte属性值为180,选择 add check item,就会为该用户加入了时间限额为3分钟。
5.其他一些问题
所有的问题都应该可以通过阅读readme和faq.txt来解决。这里仅仅讨论两种常见的问题。
1、若运行radius是出现segmentation fault,则可能需要作以下一些工作:
在加载dictionary以前,执行下面的sql语句:
insert into dictionary values ('','VENDOR','USR','429','','');
然后运行 dictimport来加载dictionary.usr,再执行下面的sql语句:
update dictionary set vendor = "USR" where type = "ATTRIB_NMC";
update dictionary set type = "ATTRIBUTE" where type = "ATTRIB_NMC";
2、若希望限制用户登录时间,则在用户的Check Items中添加使用login-time属性。时间格式为被"|"或","隔离开来的串。天可能为Mo, Tu, We, Th, Fr, Sa ,Su. 分别代表星期1-星期日,其中wk表示工作日,也就是周一到周五(Wk for Mo-Fr)。"Any" or "Al" 表示每一天。时间格式为hhmm-hhmm 的格式。例如:
Wk2305-0855,Sa,Su2305-1655 |
允许一个用户在工作日的晚上23:05到早上8:55,周六全天,周日晚23:05到下午16:55。
3、按照上面的例子,当设置了时间限额以后,用户使用时间超过该限额则自动断线,而且不能再登录进入,但是该web界面没有提供如何清除使用时间的方法,这样当需要为用户增加时间限制,需要在以前的时间限额上添加新的时间限额,管理起来非常麻烦,这里我写了一个小小的cgi来清除用户的使用记录。
内容如下: clear_acct.cgi 和 web界面
只要输入要清除记账的用户名和mysql管理员密码就可以清除用户的记账信息。
4、此外我写了一个小小的提供用户察看自己的拨号时间使用情况的cgi程序,使用户可以输入自己的拨号密码通过验证以后,察看自己的拨号log记录
cgi程序 web页面
icrraius不仅仅支持3comras500,其他的拨号服务器也支持,但是笔者没有作试验,感兴趣的同志可以试一试。