用php写一个squid验证
發表於 : 2009-02-18 14:36:37
http://mirrors.ta139.com/pangty/show-37-1.html
公司的代理服务器用的是squid,基于IP地址和MAC地址进行权限验证允许部分用户访问Internet。无奈列位高手们早已通晓盗用IP、MAC的方法来绕过squid的限制。近来考虑改为帐号认证。
由于同时在维护一个邮件服务器(qmail + vpopmail + mysql),邮件帐号用mysql管理,内网用户人手一邮箱。为了便于用户记忆,想直接使用邮件帐号和密码作为squid的帐号密码。
程序嘛,比较靠谱的是mysql_auth,无奈对c一窍不通,只能借鉴一下它的思路......干脆自己写一个。
其他已知资料:《Squid中文权威指南》,第12章:
在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代码
1. #!/usr/bin/php
2.
3. <php>pw_passwd;
13. if ($passwd == crypt($p, $passwd)) {
14. $result = true;
15. }
16. }
17. return $result;
18. }
19.
20. while (!feof(STDIN)) {
21. $sql_link = mysql_connect("x.x.x.x", "xxx", "yyy");
22. mysql_select_db("vpopmail", $sql_link);
23.
24. $input = trim(fgets(STDIN));
25. $list($u, $p) = split(" ", $input);
26. $username = rawurldecode($u);
27. $password = rawurldecode($p);
28. if (valid($username, $password, $sql_link)) {
29. fwrite(STDOUT, "OK\n");
30. } else {
31. fwrite(STDOUT, "ERR\n");
32. }
33.
34. mysql_close($sql_link);
35. }
36.
37. ?>
上述代码保存为/usr/lib/squid/my_auth.php,属性如下:
代码
1. -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
公司的代理服务器用的是squid,基于IP地址和MAC地址进行权限验证允许部分用户访问Internet。无奈列位高手们早已通晓盗用IP、MAC的方法来绕过squid的限制。近来考虑改为帐号认证。
由于同时在维护一个邮件服务器(qmail + vpopmail + mysql),邮件帐号用mysql管理,内网用户人手一邮箱。为了便于用户记忆,想直接使用邮件帐号和密码作为squid的帐号密码。
程序嘛,比较靠谱的是mysql_auth,无奈对c一窍不通,只能借鉴一下它的思路......干脆自己写一个。
其他已知资料:《Squid中文权威指南》,第12章:
在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代码
1. #!/usr/bin/php
2.
3. <php>pw_passwd;
13. if ($passwd == crypt($p, $passwd)) {
14. $result = true;
15. }
16. }
17. return $result;
18. }
19.
20. while (!feof(STDIN)) {
21. $sql_link = mysql_connect("x.x.x.x", "xxx", "yyy");
22. mysql_select_db("vpopmail", $sql_link);
23.
24. $input = trim(fgets(STDIN));
25. $list($u, $p) = split(" ", $input);
26. $username = rawurldecode($u);
27. $password = rawurldecode($p);
28. if (valid($username, $password, $sql_link)) {
29. fwrite(STDOUT, "OK\n");
30. } else {
31. fwrite(STDOUT, "ERR\n");
32. }
33.
34. mysql_close($sql_link);
35. }
36.
37. ?>
上述代码保存为/usr/lib/squid/my_auth.php,属性如下:
代码
1. -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