歡迎您光臨本站 註冊首頁

用php寫一個squid驗證輔助器(authentication helper)

←手機掃碼閱讀     火星人 @ 2014-03-04 , reply:0

用php寫一個squid驗證輔助器(authentication helper)

  公司的代理伺服器用的是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 編輯 ]

《解決方案》

    樓主實驗過沒有,很感興趣

《解決方案》

    是的,已經實際在用,效果不錯。

《解決方案》

    這樣能保證帳號不被盜用么?

《解決方案》

    樓主厲害

《解決方案》

 

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



[火星人 ] 用php寫一個squid驗證輔助器(authentication helper)已經有486次圍觀

http://coctec.com/docs/service/show-post-27145.html