| 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他这样的认证是比较合理的。现时也比较直接明了,
设想一下,如果你的认证用户非常多,如有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
|