« »
2008-03-31MySQL,PHP

92

使用PHP的命令行模式搭建基于MySQL的Squid认证

PHP 代码:


<code>#!/usr/bin/php -q
&lt;?php
//连接MySQL数据库的设置
//MySQL服务器名,通常都是localhost
$servername = 'localhost'; 
//数据库用户名
$dbusername = 'dbusername';
//数据库用户密码
$dbpassword = 'dbpassword';
//数据库名
$dbname = 'dbname';
//存储认证帐号的数据表
$tablename = 'users';
//存储用户名的字段
$usercolumn = 'usercolumn';
//存储密码的字段
$pwdcolumn = 'pwdcolumn';//通过STDIN获取输入。STDIN是PHP命令行模式下的常量,相当于$stdin = fopen('php://stdin', 'r'); 
    while (STDIN){
        unset($link_id,$input,$username,$password,$input_array,$result,$fetch_array);
        //连接数据库并选择数据库,出错则输出ERR。
        if (!$link_id = mysql_connect($servername,$dbusername,$dbpassword)){
            print("ERR\n");
            exit();
        }
        if(!mysql_select_db($dbname,$link_id)){
            print("ERR\n");
            mysql_close($link_id);
            exit();
        }
        //获取输入。输入格式是 "用户名 密码"
        $input=fgets(STDIN,256);
        if ($input==""){
            $input_array[0]="";
            print("ERR\n");
        }else{
        //将输入分割为用户名和密码。我的算法显然是很笨的,Webmin的perl脚本(后面有)简直美妙啊,可惜不懂-_-!
            $input_array=split(" ",$input);
            $username=$input_array[0];
            if($username==""){
                print("ERR\n");
            }else{
                $input_array[0]="";
                $password=rtrim(ltrim(join(" ",$input_array)),"\n");
                if($password==""){
                    print("ERR\n");
                }else{
                //查询数据库,正确则输出OK,错误输出ERR
                    $password=encryptpwd($username,$password);
                    $query="SELECT * FROM ".$tablename." WHERE ".$usercolumn."='".$username."' AND ".$pwdcolumn."='".$password."' AND active='1'";
                    $result=mysql_query($query,$link_id);
                    if ($result){
                        $num_rows=mysql_num_rows($result);
                        if ($num_rows==1){
                            print("OK\n");
                        }else{
                            print("ERR\n");
                        }
                    }else{
                        print("ERR\n");
                    }
                    mysql_free_result($result);
                }
            }
        }
        mysql_close($link_id);
    }

function encryptpwd($username,$password){
//密码加密函数
$mode=1;
    switch ($mode) {
        case 0:
        $salt=$username;
            //$salt = substr(time(), -2);
            $encrypted=crypt($password,$salt);
            break;
        case 1:
            $encrypted=md5($password);
            break;
        case 2:
            $encrypted=base64_encode(md5($password));
            $encrypted="$$encrypted$";
            break;
    } 
    return $encrypted;
}
?&gt;

</code>

写完后保存在某个位置,比如/etc/squid/php_auth.php
然后设为可执行
代码:


#chmod 755 /etc/squid/php_auth.php

建立MySQL数据库:
PhpMyadmin很方便的
先建立一个数据库,起个名字
然后输入以下内容建立数据表并插入数据。表名和字段名可以自己设置啦

代码:


CREATE TABLE `users` (
  `uid` int(11) NOT NULL auto_increment,
  `usercolumn` varchar(16) NOT NULL default '',
  `pwdcolumn` varchar(64) NOT NULL default '',
  PRIMARY KEY  (`uid`)
) TYPE=MyISAM ;INSERT INTO `users` VALUES ('','001', MD5('001'));

测试:
代码:


#/etc/squid/php_auth.php  回车后会等待输入

输入
代码:


001 001 用空格分隔用户名和密码,回车

正确会显示OK,错误显示ERR
Ctrl+C退出

Squid的外部认证程序其实只需要能从STDIN获取输入,并且能正确时输出OK\n,错误输出ERR\n就行了,用什么语言写都是可以的。

好了,脚本已经写好,数据库也有了,现在该让Squid知道我们要它用我们写的脚本来验证用户了

Squid的设置:
在/etc/squid/squid.conf中添加这些

代码:


auth_param basic realm Squid proxy server  #会在验证窗口显示哦
auth_param basic program /etc/squid/php_auth.php #外部认证程序
auth_param basic credentialsttl 2 hour #验证信任时间(大概是这样吧),过了这个时间就会重新要求验证
auth_param basic children 5 #客户验证程序数目#acl设置
acl auth proxy_auth REQUIRED #要求访问验证

#代理约束规则
#http_access deny !auth #没验证的没得看哦
http_access allow auth  #验证的pass pass啦

还有,要验证就不能透明代理。唉,这让偶相当郁闷

附:Webmin的Squid认证脚本。正则表达式看不懂啊
代码:


#!/usr/bin/perl
# squid-auth.pl
# A basic squid authentication programopen(AUTH, $ARGV[0]);
while(&lt;AUTH&gt;) {
        s/\r|\n//g;
        s/#.*$//;
        if (/^(\S+):(\S+)/) {
                $auth{$1} = $2;
                }
        }
close(AUTH);

$| = 1;
while(&lt;STDIN&gt;) {
        s/\r|\n//g;
        local ($u, $p) = split(/\s+/, $_);
        print $auth{$u} &amp;&amp;
              $auth{$u} eq crypt($p, $auth{$u}) ? "OK\n" : "ERR\n";
        }

补充说明:
当用户更改了用户名或密码后,还需要
代码:


#squid -f -k reconfigure

否则验证就通不过,我也不知道为什么
可以在修改用户名和密码的PHP里面加一条
PHP 代码:


<code>exec("squid -k reconfigure"); 
</code>

并且还有因为apache和squid的运行用户不同,php无法成功执行以上命令,所以我把apache的运行用户改成和squid一样
把/etc/apache/httpd.conf里面
代码:


User www-data

改成
代码:


User proxy

这样就都没问题了

您还可能感兴趣的内容

日志信息 »

该日志于2008-03-31 04:44由 x72 发表在MySQL, PHP分类下, 通告目前不可用,你可以至底部留下评论。

没有评论

发表评论 »


返回顶部