Chinaunix首页 | 论坛 | 博客
  • 博客访问: 170540
  • 博文数量: 33
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 501
  • 用 户 组: 普通用户
  • 注册时间: 2013-03-26 11:00
文章分类

全部博文(33)

文章存档

2014年(11)

2013年(22)

我的朋友

分类: LINUX

2014-04-24 10:20:04

如果http GET包经过ip层(有些厂商走了加速机制后,http的GET可能不经过IP层),可以用这两个命令之一完成:
  iptables -I FORWARD 1 -i br0 -p tcp --dport 80 -m string --algo kmp --string "sina.cn" -j DROP
  iptables -I FORWARD 1 -i br0 -p tcp --dport 80 -m string --algo bm --string "" -j REJECT --reject-with host-unreach
最好用第二条。这个实现方法有个缺点:不能对https进行url过滤。

如果http的GET包不经过ip层,就需要通过对DNS解析的截获来达到url过滤的目的。这个就可以同时达到对http和https的url过滤。
  iptables -t nat -I PREROUTING 1 -i br0 -p udp --dport 53 -m string --algo bm --url-filter "sina.cn" -j DROP
其中,url-filter是我在libipt_string.c中添加的,添加的代码如下:
-------------------------------------------------------------

 "--string [!] string          Match a string in a packet\n"
+"--url-fiter url          Match a string in a packet\n"
 "--hex-string [!] string      Match a hex string in a packet\n",
  ....

        { "hex-string", 1, 0, '5' },
+       { "url-filter", 1, 0, '6' },
        {0}
  ....

+ static void
+parse_url(const char *s, struct ipt_string_info *info)
+{      
+#define URL_LEN_MAX 128
+#define URL_LEVEL_MAX 10
+       char url[URL_LEN_MAX] = {0};
+       unsigned char part_len = 0;
+       int levels = 0;
+       int copied = 0;
+       char *p = NULL;
+
+       if (strlen(s) <= URL_LEN_MAX) {
+               /*for detail, please refer to format of url in dns request packet*/
+               for (levels=0; levels
+                       p = strchr(s, '.');
+                       if (p){
+                               part_len = (unsigned char)(p - s);
+                               (info->pattern+copied)[0] = part_len;
+                               copied += 1;
+
+                               strncpy(info->pattern+copied, s, p-s);
+                               copied += (int)(p-s);
+
+                               s = p+1;
+                       } else {
+                               part_len = (unsigned char)(strlen(s));
+                               (info->pattern+copied)[0] = part_len;
+                               copied += 1;
+
+                               strncpy(info->pattern+copied, s, strlen(s));
+                               copied += strlen(s);
+                               break;
+                       }

+               }
+               info->patlen = copied;
+               return;
+       }
+       exit_error(PARAMETER_PROBLEM, " url too long `%s'", s);
+}
+
  ...

                *flags |= STRING;
                break;
-
+       case '6':
+               if (*flags & STRING)
+                       exit_error(PARAMETER_PROBLEM,
+                                  "Can't specify multiple --url-filter");
+               check_inverse(optarg, &invert, &optind, 0);
+               parse_url(argv[optind-1], stringinfo);
+               if (invert)
+                       stringinfo->invert = 1;
+               stringinfo->patlen=strlen((char *)&stringinfo->pattern);
+               *flags |= STRING;
+               break;
        default:
----------------------------------------------------
以上只是在通常情况下做到url过滤,没有做很多的判断,如:
1. 上面实现中,url最多允许127字节,而实际上,肯定不止这么点,但是通常情况下不会太长,太长了谁去访问你呀,记都记不住啊。
2. 以为例,其中有两个“.”,上面的实现中最多允许出现10个"."。同样的,我还没见过超过5个"."的,所以一般情况下,10个足够用了。
阅读(6652) | 评论(0) | 转发(0) |
0

上一篇:URL中参数的解析

下一篇:没有了

给主人留下些什么吧!~~