• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • SQUID的ncsa_auth認證原理

    發表于:2007-05-25來源:作者:點擊數: 標簽:
    前天看了一下ncsa_auth認證程序的源碼,發現這個認證其實是非常簡單的。 squid啟動時運行ncsa_authpasswd密碼文件 如果你的認證用戶不是很多的話,寫個sh就可以解決問題了 ncsa_auth.sh 內容如下 #認證用戶名為abc密碼123 [code:1:e0e520c5be] whiletrue;do

    前天看了一下ncsa_auth認證程序的源碼,發現這個認證其實是非常簡單的。
    squid啟動時運行ncsa_auth passwd密碼文件

    如果你的認證用戶不是很多的話,寫個sh就可以解決問題了
    ncsa_auth.sh

    內容如下
    #認證用戶名為abc密碼123
    [code:1:e0e520c5be]
    while true ; do
     read a
     user=`echo a| /usr/bin/cut -d ' ' -f1`
     pass=`echo a|/usr/bin/cut -d ' ' -f2`
     if [ "$user" == "abc" ] ; then
             if [ "$pass" == "123" ] ; then
                        echo OK;
            else
                        echo ERR;
            fi
     else
             echo ERR
      fi
    done
    #結束

    呵呵,如果你的認證不是很頻繁的話。但是你希望與你的數據庫認證集成在一起的話
    你也可以用php連結數據庫達到這個目的
    在ncsa_auth.sh里的內容應該如下:
    /usr/local/bin/php /usr/local/etc/ncsa_auth.php

    在ncsa_auth.php內容
    <?php

    $fd = fopen('php://stdin', 'r'); 
    while(true){
            $buffer = fgets($fd, 4096);
            $lsstr=explode(' ',$buffer);
            $sql_str="select user from bbs_user where userid like '$lsstr[0]' and pass like '$lsstr[1]'";
            #如果用戶名與密碼正確的話
             if(true) echo 'OK';
             else echo 'ERR';
    }
    ?>
    [/code:1:e0e520c5be]
    拋磚引玉,希望大家在用squid認證能夠有所啟發,當然如果你覺得效率低下的話就使用C,直接修改squid自帶的ncsa_auth.c加了數據庫查詢語句就行了。

     ljily000 回復于:2005-03-06 21:11:31
    :em27: 

    頂!
    Good!

     段譽 回復于:2005-03-12 04:00:37
    頂上來,大家都了解一下。

    BTW:請大家多多關注我們這個板子,多推薦好帖子,增加我們這個板子的精華數量。謝謝??!

     shitian8848 回復于:2005-03-12 09:32:49
    正在弄squid的認證呢,呵呵,謝謝樓主了。
    UP!

     platinum 回復于:2005-03-12 10:45:27
    請教一下樓主
    [code:1:4e08dde378]
    while true ; do 
    read a 
    user=`echo a| /usr/bin/cut -d ' ' -f1` 
    pass=`echo a|/usr/bin/cut -d ' ' -f2` 
    if [ "$user" == "abc" ] ; then 
            if [ "$pass" == "123" ] ; then 
                       echo OK; 
           else 
                       echo ERR; 
           fi 
    else 
            echo ERR 
     fi 
    done 
    #結束 
    [/code:1:4e08dde378]
    這個shell用于哪里?
    好像和squid認證無關啊~
    另外,ncsa的密碼是MD5后的,而樓主這個shell是明碼

    我只是想知道,這個shell是做什么的呢?

     60133056 回復于:2005-03-12 13:45:32
    觀望 學習

     wingger 回復于:2005-03-12 14:28:08
    [quote:7f7046b6b5="platinum"]這個shell用于哪里?
    好像和squid認證無關啊~
    另外,ncsa的密碼是MD5后的,而樓主這個shell是明碼

    我只是想知道,這個shell是做什么的呢?[/quote:7f7046b6b5]

    我也想知道,是用這個來代替ncsa嗎?
    還是解剖他的原理?

     wxxszzz 回復于:2005-03-12 17:43:24
    看了上面大家的回貼,我就再解釋一下吧。

    我們使用htpasswd產生的那個密碼文件里的密碼是用MD5加密的。

    但是squid傳遞給ncsa_auth認證程序的密碼使用的是明碼,
    然后由ncsa_auth認證程序再用md5加密傳給他的密碼后
    再與用htpasswd產生的那個密碼文件里的密碼相比較。
    如果符合就認為密碼正確。

    另外以上的sh與使用php密碼認證的程序。
    就是接到squid的密碼后,不使用md5加密接收到的密碼,直接比較,

    以上的兩個程序
    他們都是可以直接替代ncsa_auth這個認證程序的。

    OK,如果還有疑問,可以再提問,不過我覺得SQUID他這樣的認證是比較合理的?,F時也比較直接明了,

    設想一下,如果你的認證用戶非常多,如有1000人以上同時認證,我們可以簡單的使用上面的高級語言如C、php、perl、java等語言,只要他的代碼里支持套接字sockets接口你就可以設計一個集中式的認證系統。

    以PHP舉例:

    代碼如頂摟的語言里只是稍微修改一下。
    [code:1:d8bd213a3b]
    在ncsa_auth.php內容 
    <?php 

    $fd = fopen('php://stdin', 'r'); 
    while(true){ 
           $buffer = fgets($fd, 4096); 
           $lsstr=explode(' ',$buffer); 
    #這里使用套接字把用戶名與密碼發送到后臺認證中心去
         $sfd=fscoket("x.x.x.x",)
           write      
           read
           fclose($sfd);

    fclose($fd);
    ?> 
    [/code:1:d8bd213a3b]
    這里之后,一個比較好的認證中心這可以產生了。之所以選用PHP認證,是因為這段時間用PHP比較多。
    這樣之后,你就可以使用多臺SQUID,多臺認證中心,一個中央數據庫。

    呵呵,不知道各位看過我的解釋與說明之后,是不是有所啟發呢?
    沒有做不到,只有想不到的事情。

     platinum 回復于:2005-03-16 07:21:21
    這個是ncsa_auth.c的源代碼
    [code:1:2a9999c6f7]
    /*
     * ncsa_auth.c
     *
     * AUTHOR: Arjan de Vet <Arjan.deVet@adv.iae.nl>
     *
     * Example authentication program for Squid, based on the original
     * proxy_auth code from client_side.c, written by
     * Jon Thackray <jrmt@uk.gdscorp.com>.
     *
     * Uses a NCSA httpd style password file for authentication with the
     * following improvements suggested by various people:
     *
     * - comment lines are possible and should start with a '#';
     * - empty or blank lines are possible;
     * - extra fields in the password file are ignored; this makes it
     *   possible to use a Unix password file but I do not recommend that.
     *
     */

    #include "config.h"
    #if HAVE_STDIO_H
    #include <stdio.h>
    #endif
    #if HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    #if HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    #if HAVE_STRING_H
    #include <string.h>
    #endif
    #if HAVE_SYS_TYPES_H
    #include <sys/types.h>
    #endif
    #if HAVE_SYS_STAT_H
    #include <sys/stat.h>
    #endif
    #if HAVE_CRYPT_H
    #include <crypt.h>
    #endif

    #include "util.h"
    #include "hash.h"

    static hash_table *hash = NULL;
    static HASHFREE my_free;

    typedef struct _user_data {
        /* first two items must be same as hash_link */
        char *user;
        struct _user_data *next;
        char *passwd;
    } user_data;

    static void
    my_free(void *p)
    {
        user_data *u = p;
        xfree(u->user);
        xfree(u->passwd);
        xfree(u);
    }

    static void
    read_passwd_file(const char *passwdfile)
    {
        FILE *f;
        char buf[8192];
        user_data *u;
        char *user;
        char *passwd;
        if (hash != NULL) {
            hashFreeItems(hash, my_free);
        }
        /* initial setup */
        hash = hash_create((HASHCMP *) strcmp, 7921, hash_string);
        if (NULL == hash) {
            fprintf(stderr, "ncsa_auth: cannot create hash table\n");
            exit(1);
        }
        f = fopen(passwdfile, "r");
        if (NULL == f) {
            fprintf(stderr, "%s: %s\n", passwdfile, xstrerror());
            exit(1);
        }
        while (fgets(buf, 8192, f) != NULL) {
            if ((buf[0] == '#') || (buf[0] == ' ') || (buf[0] == '\t') ||
                (buf[0] == '\n'))
                continue;
            user = strtok(buf, ":\n\r");
            passwd = strtok(NULL, ":\n\r");
            if ((strlen(user) > 0)  & passwd) {
                u = xmalloc(sizeof(*u));
                u->user = xstrdup(user);
                u->passwd = xstrdup(passwd);
                hash_join(hash, (hash_link *) u);
            }
        }
        fclose(f);
    }

    int
    main(int argc, char **argv)
    {
        struct stat sb;
        time_t change_time = 0;
        char buf[256];
        char *user, *passwd, *p;
        user_data *u;
        setbuf(stdout, NULL);
        if (argc != 2) {
            fprintf(stderr, "Usage: ncsa_auth <passwordfile>\n");
            exit(1);
        }
        while (fgets(buf, 256, stdin) != NULL) {
            if ((p = strchr(buf, '\n')) != NULL)
                *p = '\0';          /* strip \n */
            if (stat(argv[1],  sb) == 0) {
                if (sb.st_mtime != change_time) {
                    read_passwd_file(argv[1]);
                    change_time = sb.st_mtime;
                }
            }
            if ((user = strtok(buf, " ")) == NULL) {
                printf("ERR\n");
                continue;
            }
            if ((passwd = strtok(NULL, "")) == NULL) {
                printf("ERR\n");
                continue;
            }
            rfc1738_unescape(user);
            rfc1738_unescape(passwd);
            u = hash_lookup(hash, user);
            if (u == NULL) {
                printf("ERR\n");
            } else if (strcmp(u->passwd, (char *) crypt(passwd, u->passwd))) {
                printf("ERR\n");
            } else {
                printf("OK\n");
            }
        }
        exit(0);
    }
    [/code:1:2a9999c6f7]
    看了一下,關鍵問題是在這里
    [code:1:2a9999c6f7]
            if ((user = strtok(buf, " ")) == NULL) {
                printf("ERR\n");
                continue;
            }
            if ((passwd = strtok(NULL, "")) == NULL) {
                printf("ERR\n");
                continue;
            }
            rfc1738_unescape(user);
            rfc1738_unescape(passwd);
            u = hash_lookup(hash, user);
            if (u == NULL) {
                printf("ERR\n");
            } else if (strcmp(u->passwd, (char *) crypt(passwd, u->passwd))) {
                printf("ERR\n");
            } else {
                printf("OK\n");
            }
    [/code:1:2a9999c6f7]

    如果用ncsa_auth.php來做“認證中心”,squid又怎么去調用呢?

     wxxszzz 回復于:2005-03-16 10:04:32
    你沒仔細看我項樓的貼子啊.

    我寫得使用PHP認證是
    squid先調用的是ncsa_auth.sh這個文件
    也就是在squid.conf這個配置文件寫的認證程序為ncsa_auth.sh

    而這個ncsa_auth.sh文件的內容就是調用php去執行ncsa_auth.php
    ncsa_auth.sh這個文件的內容如下:
    [code:1:5cb36057b4]
    /usr/local/bin/php /usr/local/squid/etc/ncsa_auth.php
    [/code:1:5cb36057b4]
    #end
    由這個ncsa_auth.sh來調用ncsa_auth.php
    這樣就可以了啊.
    然后再在ncsa_auth.php
    里面獲得squid傳遞的用戶名與密碼.

    你仔細研究一下我樓上的那個貼子.
    就應該能夠明白,如果你告訴我說不懂PHP,那我也無話可說了

     platinum 回復于:2005-03-17 00:42:38
    嘿嘿,還真不懂PHP,不過你的原理我是明白了
    也可以
    [code:1:b068d37ad6]
    /bin/bash /xxx/ncsa_auth.sh
    [/code:1:b068d37ad6]
    這樣咯?

    也可以多個squid通過一個認證服務器,那個服務器通過PHP+MYSQL進行處理,密碼或明或MD5,放到數據庫里

    如果這樣想,自由度真的很大

     yxdyw 回復于:2005-04-04 10:14:42
    wxxszzz      
    騎士:
     一臺ADSL,一臺路由器,一臺單網卡linux主機,adsl接入路由器,在路由器上面拔號共享上網,我現在在路由器上面開放主機linux,把所有的網關都改為linux主機地址,利用squid+iptables實現透明代理,不知道如何實現,其中如何控制局域網上網?謝謝

     wxxszzz 回復于:2005-04-07 22:54:10
    嘿嘿,大概很少有人會這么做吧。

    如果三個東東都在一個網段的話,只能實現HTTP透明代理成功。其他的游戲啊QQ阿之類的就不行了。

    要實現HTTP,你只要把80端口重定向到SQUID的端口3128端口就行了。


    另外一個解決方案就是:

    把那臺LINUX的網卡再虛擬一塊網卡出來,做成兩個網段。

    其中一個網段跟內網相同。另外一個網段跟路由器相同,當然路由器就只能改成跟linux的網段一樣羅。

    這樣就成為了一個典型的雙網卡LINUX路由器了。所有的流量都經過LINUX再通過路由器出去。

    至于如何在LINUX下一塊網卡綁定兩個地址,查查這個論壇的精華吧。

    定義好了之后,最簡單的透明代理,使用IPTABLES只要三條語名。

    [code:1:a7530cf441]
    echo 1 >/proc/sys.net/ipv4/ip_forward
    iptables -t nat -A POSTROUTING -o eth0:1 -s 內網網段 -j MASQUERADE
    iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to LINUX內網地址:3128
    [/code:1:a7530cf441]
    OK

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>