CentOS5.4_Squid代理服务器的计费与流量控制的实现

随着宽带网络用户数量的迅速膨胀,网络管理员通常面临IP地址缺乏、用户访问计费困难以及内部网络安全难于管理等一系列问题,而使用代理服务器是解决这些问题的有效方法之一。Squid以其权限管理灵活、性能高和效率快等特点成为Linux和UNIX平台下最为流行的高性能免费应用层代理服务器。但只有解决了该服务器软件本身不提供日志分析软件功能所带来的计费和流量控制等问题,才能提高其应用性能

实现思路

使用MySAR对Squid日志进行分析,将用户访问外网的记录保存在MySQL数据库中,然后利用所编写的程序,对用户的流量进行统计。当流量超过设置值时调用iptables防火墙,禁止用户再访问Squid服务器。

实现方法

操作前需要查看系统ulimit连接数,打开limit连接限制。

# ulimit -n

1024

# vi /etc/security/limits.conf

添加如下内容:

* soft core unlimited

* hard core unlimited

* soft fsize unlimited

* hard fsize unlimited

* soft data unlimited

* hard data unlimited

* soft nproc 65535

* hard nproc 65535

* soft stack unlimited

* hard stack unlimited

* soft nofile 409600

* hard nofile 409600

第一步:安装和配置Squid服务。

1.使用下面命令安装Squid:

# rpm -ivh /mnt/CentOS/squid-2.6.STABLE21-3.el5.i386.rpm

2.先将Squid主配置文件/etc/squid/squid.conf复制为/etc/squid/squid.conf.bak,然后删除/etc/squid/squid.conf配置文件的原有内容,并加上下面这些语句,有了这些最基本的设置Squid就可以启动使用了。

http_port 192.168.1.201:3128

cache_mem 64 MB

cache_dir ufs /var/spool/squid 4096 16 256

cache_effective_user squid

cache_effective_group squid

dns_nameservers 192.168.1.201

visible_hostname test.com.cn

cache_access_log /var/log/squid/access.log

cache_log /var/log/squid/cache.log

cache_store_log /var/log/squid/store.log

acl all src 0.0.0.0/0.0.0.0

http_access allow all

logfile_rotate 30

#设置循环保存日志文件的个数

3.使用命令/usr/sbin/squid -z建立硬盘缓冲区的缓存目录结构。

第二步:安装Apache和PHP解释器。

1.使用下面命令安装Apache服务:

# rpm -ivh /mnt/CentOS/httpd-2.2.3-31.el5.centos.i386.rpm

# rpm -ivh /mnt/CentOS/httpd-devel-2.2.3-31.el5.centos.i386.rpm

2.使用下面命令安装PHP解释器:

# rpm -ivh /mnt/CentOS/php-5.1.6-23.2.el5_3.i386.rpm

第三步:安装MySQL:

1.安装MySQL服务及相关程序

# rpm -ivh /mnt/CentOS/perl-DBD-MySQL-3.0007-2.el5.i386.rpm

# rpm -ivh /mnt/CentOS/mysql-server-5.0.77-3.el5.i386.rpm

# rpm -ivh /mnt/CentOS/mysql-devel-5.0.77-3.el5.i386.rpm

2.安装MySQL客户端程序。

# rpm -ivh /mnt/CentOS/mysql-5.0.77-3.el5.i386.rpm

3.安装PHP -MySQL支持包

# rpm -ivh /mnt/CentOS/php-mysql-5.1.6-23.2.el5_3.i386.rpm

4.启动MySQL服务

使用下列命令启动MySQL服务

/etc/init.d/mysqld start

5.修改MySQL用户root的口令。

缺省MySQL的root用户没有口令,为了保证数据库安全,应该使用以下命令修改MySQL用户root的口令(本例设置口令为test_dba):

mysqladmin -u root password test_dba

第四步:安装和设置MySAR。

1.访问http://giannis.stoilis.gr/software/mysar,点击 “download”下载最新版的MySAR安装软件mysar-2.1.4.tar.gz。

2.使用命令tar zxvf mysar-2.1.4.tar.gz -C /usr/local将其解压到/usr/local目录中。

3.使用命令vi /usr/local/mysar/www/install/index.php打开安装向导的源文件index.php,在第86行的PRIMARY KEY (id),前,插入语句"usr_iptables tinyint(1) unsigned NOT NULL default '0',",创建usr_iptables字段用于判断用户是否已被限制访问服务器。

4.使用命令vi /etc/httpd/conf/httpd.conf打开httpd.conf配置文件,在配置文件的末尾添加语句

“Alias /mysar/ "/usr/local/mysar/www/" ”

ServerName 192.168.1.201:8080

设置虚拟目录,使虚拟目录指向MySAR目录中的www子目录。

[root@jrcz squid-source]# cat /etc/httpd/conf/vhost_mysar.conf

# VirtualHost for mysar Solution

<VirtualHost *:8080>

ServerName 192.168.1.233

DocumentRoot /usr/local/mysar/www/

# Suexec config

SuexecUserGroup root root

</VirtualHost>

5.使用命令/etc/init.d/httpd restart重启Apache服务器。如图1所示,通过访问http://服务器IP地址或域名/mysar/这一地址打开MySAR的安装向导,并依照向导提示完成MySAR的安装。

# vi /usr/local/mysar/etc/config.ini

dbUser = mysar

dbPass = mysar

dbHost = localhost

dbName = mysar

config.ini文件需要重新创建才行。否则报错。

# rm -rf /usr/local/mysar/www/install

6.使用命令vi /usr/local/mysar/bin/mysar-importer.php打开mysar-importer.php文件(注:该文件的作用是读取Squid的日志文件/var/log/squid/access.log,并对日志进行分析,然后将相应的数据写入数据库中),并在134行插入以下红色三行代码,用于判断访问的目的主机是否为网内主机(该处假设网内目的主机为IP地址192.168.*.*),如果为网内目的主机,则访问流量不进行统计。找到语句“debug('Record received: ',40,__FILE__,__LINE__);”在该语句前插入如下语句。
$test_head=preg_split("[//]",$record[6]);
if (substr($test_head[1],0,7)=="192.168")
{continue 1 ;}

7.使用命令vi /usr/local/mysar/etc/mysar.cron打开文件mysar.cron,并在文件末尾添加语句“01 1 * * * root squid -k rotate”,使Squid的日志每天循环保存一次(注:由于MySAR是通过分析Squid日志的方法来统计流量的,如果日志文件太大会降低MySAR的运行效率,同时也可能使统计出错)。然后再使用命令crontab /usr/local/mysar/etc/mysar.cron设置自动作业,这时就可以通过访问http://服务器IP地址或域名/mysar/查看用户使用Squid代理服务器访问外网的情况了。

第五步:编写C程序用于执行iptables命令。

出于安全上的考虑,PHP程序默认情况下是不允许直接调用Linux系统命令的,因此通过该C程序来间接调用iptables命令可以在很大程度上保护服务器的安全。具体程序源代码如下。

#include <stdio.h>

#include <getopt.h>

#include <unistd.h>

int main(int argc ,char *argv[])

{int optch;

while( (optch = getopt( argc , argv , "ad" ) ) != -1 )/*分析命令行参数*/

{switch( optch ) {

case 'd':

execlp("iptables","iptables","-I","INPUT","-s",argv[2],"-j","DROP",(char *) 0 );

break;/*设置iptable规则,禁止用户访问服务器*/

case 'a':

execlp("iptables","iptables","-D","INPUT","-s",argv[2],"-j","DROP",(char *) 0 );

break;/*删除iptable规则*/

default: printf("error \n");} }}

1.编写完成后以.c为后缀名保存文件(本例文件名为uip.c),然后再分别使用gcc -c uip.c –o uip

2.使用命令chmod u+x uip修改程序uip的执行权限,使PHP程序能够调用它。

第六步:编写PHP程序mysar.php用于管理代理用户。

#!/usr/bin/php

<?php
$link = mysql_connect("localhost", "root", "ygjalarm");
//mysql_connect(服务器名,mysql用户名,mysql密码)
if (!$link) {die('Could not connect: ' . mysql_error());
exit;}
mysql_select_db("mysar",$link);
$result = mysql_query("select traffic.ip, hostnames.hostname,sum(traffic.bytes) from traffic,hostnames where traffic.ip=hostnames.ip and hostnames.usr_iptables=0 group by traffic.ip");
if (!$result) {
die("query failed: " . mysql_error());
}
//汇总每个用户的流量,并得到该用户的IP地址信息
while ($row = mysql_fetch_array ($result)) {
if($row["sum(traffic.bytes)"]>= 107374182400)

{system('./uip -d '.$row["hostname"]);
$usr_update= mysql_query("update hostnames set usr_iptables=1 where hostname='".$row["hostname"]."'");}}
//判断用户的总流量是否大于107374182400B,如果大于则调用c程序设置iptables规则,禁止用户访问代理服务器
?>

该程序通过统计数据库中代理用户的流量数据判断是否超出限制,如果超出则调用c程序设置iptables规则,禁止用户访问代理服务器。

注意事项:

1. cron计划任务里应该包括以下几项:

*/5 * * * * /usr/local/mysar/bin/mysar-resolver.php > /usr/local/mysar/log/mysar-resolver.log 2>&1

*/5 * * * * /usr/local/mysar/bin/mysar-maintenance.php > /usr/local/mysar/log/mysar-maintenance.log 2>&1

*/5 * * * * /usr/local/mysar/bin/mysar-importer.php > /usr/local/mysar/log/mysar-importer.log 2>&1

*/5 * * * * /usr/local/mysar/bin/mysar-ip.php > /usr/local/mysar/log/mysar-ip.log 2>&1

01 1 * * * root squid -k rotate

2.在页面安装 mysar数据库时,可能会报错,会提示手动创建:

# vi /usr/local/mysar/etc/config.ini

dbUser = mysar

dbPass = mysar

dbHost = localhost

dbName = mysar

config.ini文件需要重新创建才行。否则报错找不到config.ini文件。

2. 第一次启动mysqld时,如果报错:

101020 15:21:29 [Warning] option 'max_join_size': unsigned value 18446744073709551615 adjusted to 4294967295

101020 15:21:29 [Warning] option 'max_join_size': unsigned value 18446744073709551615 adjusted to 4294967295

解决方法:

#echo “max_join_size=4294967295”>>/etc/my.cnf

#mysql -uroot -p

mysql> select @@max_join_size;

+-----------------+

| @@max_join_size |

+-----------------+

| 4294967295 |

+-----------------+

1 row in set (0.00 sec)

再重启mysqld服务即可:

# service mysqld restart

Stopping MySQL: [ OK ]

Starting MySQL: [ OK ]

总结:

通过以上六个步骤的设置,解决了基于Linux系统代理服务器Squid的计费与流量控制。不仅有效掌握了用户的上网情况,而且实现了对大量占用网络带宽的用户的有效的控制。