php写的squid验证辅助器


2008-11-08 23:17

公司的代理服务器用的是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

更进一步: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 ) ;
}

? >

http://bbs.chinaunix.net/viewthread.php?tid=1276393

你可能感兴趣的:(php写的squid验证辅助器)