免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6442 | 回复: 12
打印 上一主题 下一主题

[proxy] [原创] 用php写一个squid验证辅助器(authentication helper) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-09-25 16:43 |只看该作者 |倒序浏览
公司的代理服务器用的是squid,基于IP地址和MAC地址进行权限验证允许部分用户访问Internet。无奈列位高手们早已通晓盗用IP、MAC的方法来绕过squid的限制。近来考虑改为帐号认证。

由于同时在维护一个邮件服务器(qmail + vpopmail + mysql),邮件帐号用mysql管理,内网用户人手一邮箱。为了便于用户记忆,想直接使用邮件帐号和密码作为squid的帐号密码。

程序嘛,比较靠谱的是mysql_auth,无奈对c一窍不通,只能借鉴一下它的思路......干脆自己写一个吧。

其他已知资料:
《Squid中文权威指南》,第12章有一个perl的例子以及以下文字:

在squid和基本验证器之间的接口非常简单。squid发送用户名和密码到验证器进程,他们以空格分开并以新行结束。验证器在其他stdin里读取用户名和密码。在检查信用项后,验证器将OK或ERR写入stdout。

任何“不安全的URL”字符会参照RFC1738规则进行编码。这样,名字“jack+jill”变成了"jack%2bjill"。squid接受包含空格的用户名和密码。例如“a password”变成了“a%20password”。在解码用户名和密码后,验证器程序能处理空格和其他的特殊字符。


要点总结:从stdin读取用户名和密码,用户名和密码以空格分隔,可能涉及解码。vpopmail里用户帐号和密码分别是pw_name和pw_passwd列,建一个表squid,只有一列pw_name,把有权用户的用户名添加到表squid里,用pw_name列关联两个表查询获得pw_passwd,和用户的输入做比较,一致即验证成功。

PHP代码如下:
#!/usr/bin/php

<?php
ini_set("display_errors", false);

function valid($u, $p, $sql_link) {
    $result = false;
    $res = mysql_query("select pw_passwd from squid a, vpopmail b where a.pw_name='$u' and a.pw_name=b.pw_name", $sql_link);
    $rows = mysql_num_rows($res);
    if (1 == $rows) {
        $data = mysql_fetch_object($res);
        $passwd = $data->pw_passwd;
        if ($passwd == crypt($p, $passwd)) {
            $result = true;
        }
    }
    return $result;
}

while (!feof(STDIN)) {

    $sql_link = mysql_connect("x.x.x.x", "xxx", "yyy");
    mysql_select_db("vpopmail", $sql_link);


    $input = trim(fgets(STDIN));
    $data = explode(' ', $input);
    $username = rawurldecode($data[0]);
    $password = rawurldecode($data[1]);
    if (valid($username, $password, $sql_link)) {
        fwrite(STDOUT, "OK\n");
    } else {
        fwrite(STDOUT, "ERR\n");
    }


    mysql_close($sql_link);
}

?>



上述代码保存为/usr/lib/squid/my_auth.php,属性如下:
-rwsr-x--- 1 root squid 843 09-25 15:12 /usr/lib/squid/my_auth.php

squid.conf的相关配置:
acl acl_valid_user proxy_auth REQUIRED
http_access allow acl_valid_user
http_access deny all

auth_param basic program /usr/lib/squid/my_auth.php
auth_param basic children 5
auth_param basic realm 互联网访问权限验证
auth_param basic credentialsttl 2 hours
auth_param basic casesensitive on


[ 本帖最后由 pangty 于 2008-10-1 20:13 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-09-25 17:07 |只看该作者
楼主实验过没有,很感兴趣

论坛徽章:
0
3 [报告]
发表于 2008-09-25 17:16 |只看该作者
是的,已经实际在用,效果不错。

论坛徽章:
0
4 [报告]
发表于 2008-09-26 09:05 |只看该作者
这样能保证帐号不被盗用么?

论坛徽章:
0
5 [报告]
发表于 2008-09-26 10:23 |只看该作者
楼主厉害

论坛徽章:
0
6 [报告]
发表于 2008-09-26 11:05 |只看该作者

更进一步:squid基于mysql的用户+ip绑定认证

昨天写的《用php写一个squid验证辅助器(authentication helper)》实现了squid基于mysql的用户帐号认证,今天再进一步修改一下程序,支持基于mysql的用户+ip绑定认证功能。

使用/etc/squid/acl_valid_user.txt存放用户的ip和帐号信息,ip和帐号以空格分隔,帐号与mysql数据表里的用户帐号是一致的,格式如下:
192.168.1.100 pangty
192.168.1.200 test

相应的修改squid.conf,使用ip_user_check来进行帐号与ip的关联检查
external_acl_type ip_user_check children=5 %SRC %LOGIN /usr/lib/squid/ip_user_check -f /etc/squid/acl_valid_user.txt
acl acl_ip_user_check external ip_user_check
   
acl acl_valid_user proxy_auth REQUIRED
http_access allow acl_valid_user acl_ip_user_check
http_access deny all
   
auth_param basic program /usr/lib/squid/my_auth.php
auth_param basic children 5
auth_param basic realm 互联网访问权限验证
auth_param basic credentialsttl 2 hours
auth_param basic casesensitive on

my_auth.php验证辅助程序加入对acl_valid_user.txt的验证,原来在mysql里创建的squid表作废。
#!/usr/bin/php

<?php
ini_set("display_errors", false);

$datafile = "/etc/squid/acl_valid_user.txt";

function valid($u, $p, $sql_link) {
        $result = false;
        $res = mysql_query("select pw_passwd from vpopmail where pw_name='$u'", $sql_link);
        $rows = mysql_num_rows($res);
        if (1 == $rows) {
                $data = mysql_fetch_object($res);
                $passwd = $data->pw_passwd;
                if ($passwd == crypt($p, $passwd)) {
                        $result = true;
                }
        }
        return $result;
}

$data = file_get_contents($datafile);
$line = preg_split ("/\n/", $data);
foreach ($line as $l) {
        $l = trim($l);
        if (!empty($l)) {
                list($k, $v) = preg_split("/ +|\s+/", $l);
                $userarr[$v] = $k;
        }
}

while (!feof(STDIN)) {

        $sql_link = mysql_connect("x.x.x.x", "xxx", "yyy");
        mysql_select_db("vpopmail", $sql_link);


        $input = trim(fgets(STDIN));
        list($u, $p) = split(" ", $input);
        $username = rawurldecode($u);
        $password = rawurldecode($p);
        if (array_key_exists($username, $userarr) && valid($username, $password, $sql_link)) {
                fwrite(STDOUT, "OK\n");
        } else {
                fwrite(STDOUT, "ERR\n");
        }

        mysql_close($sql_link);
}

?>



[ 本帖最后由 pangty 于 2008-10-1 20:14 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2008-09-26 11:06 |只看该作者
这里好冷清啊

论坛徽章:
0
8 [报告]
发表于 2008-09-26 11:58 |只看该作者
不错,好东西!:)

论坛徽章:
0
9 [报告]
发表于 2008-09-26 12:52 |只看该作者
这版是比较冷清,这里大部分都是为squid来的,squid这东西……

来这里的人一部分很容易找到答案,一部分不太可能找到答案,所以就冷清了。

论坛徽章:
0
10 [报告]
发表于 2008-09-30 10:00 |只看该作者
楼主这个应该加精华
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP