免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 18992 | 回复: 27

呵呵,我也凑个热闹,转发一个原来写的 iptables 版 DNS 匹配模块 [复制链接]

论坛徽章:
0
发表于 2009-12-18 18:45 |显示全部楼层
只贴核心代码了,完整内容见附件

使用方法:

  1. iptables -A FORWARD -m domain --name "www.chinaunix.net" -j DROP
  2. iptables -A FORWARD -m domain --name "www.163.com" -j DROP
复制代码


ipt_domain.c
#if defined(MODVERSIONS)
#include <linux/modversions.h>
#endif
#include <linux/module.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
#&nbsp;&nbsp;&nbsp;&nbsp;include <linux/netfilter/x_tables.h>
#&nbsp;&nbsp;&nbsp;&nbsp;define ipt_register_match xt_register_match
#&nbsp;&nbsp;&nbsp;&nbsp;define ipt_unregister_match xt_unregister_match
#&nbsp;&nbsp;&nbsp;&nbsp;define ipt_match xt_match
#else
#&nbsp;&nbsp;&nbsp;&nbsp;include <linux/netfilter_ipv4/ip_tables.h>
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) */

#include <linux/types.h>
#include <linux/skbuff.h>
#include "ipt_domain.h"
#include <net/udp.h>


#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
static bool
#else
static int
#endif
match(const struct sk_buff *skb, const struct net_device *in,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const struct net_device *out,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const struct xt_match  *mymatch,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const void *matchinfo,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int offset,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned int myprotoff,
#else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const void *matchinfo,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int offset,
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const void *hdr,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u_int16_t datalen,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bool *hotdrop)
#else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int *hotdrop)
#endif
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
&nbsp;&nbsp;&nbsp;&nbsp;struct iphdr *ip = ip_hdr(skb);
#else
&nbsp;&nbsp;&nbsp;&nbsp;struct iphdr *ip = skb->nh.iph;
#endif
&nbsp;&nbsp;&nbsp;&nbsp;struct udphdr *udph;
&nbsp;&nbsp;&nbsp;&nbsp;const struct ipt_domain_info *info = matchinfo;

&nbsp;&nbsp;&nbsp;&nbsp;if (offset || ip->protocol != IPPROTO_UDP)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;

&nbsp;&nbsp;&nbsp;&nbsp;udph = (char *)ip + ip->ihl*4;

&nbsp;&nbsp;&nbsp;&nbsp;return ( (ntohs(udph->source) == 53 || ntohs(udph->dest) == 53)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&& (udph->len >= (8 + 12 + info->len + 5))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&& !strcmp(info->name,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(char *)((void *)udph + ntohs(udph->len) - info->len - 5))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);

}


#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
static bool
#else
static int
#endif
checkentry(const char *tablename,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const void *ip,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const struct xt_match *mymatch,
#else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const struct ipt_ip *ip,
#endif
&nbsp;&nbsp;&nbsp;&nbsp;   void *matchinfo,
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18)
&nbsp;&nbsp;&nbsp;&nbsp;   unsigned int matchsize,
#endif

&nbsp;&nbsp;&nbsp;&nbsp;unsigned int hook_mask)
{
//&nbsp;&nbsp;&nbsp;&nbsp;if (matchsize != IPT_ALIGN(sizeof(struct ipt_domain_info)))

//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;


&nbsp;&nbsp;&nbsp;&nbsp;return 1;
}


static struct ipt_match domain_match = {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
&nbsp;&nbsp;&nbsp;&nbsp;{ NULL, NULL },
&nbsp;&nbsp;&nbsp;&nbsp;"domain",
&nbsp;&nbsp;&nbsp;&nbsp;&match,
&nbsp;&nbsp;&nbsp;&nbsp;&checkentry,
&nbsp;&nbsp;&nbsp;&nbsp;NULL,
&nbsp;&nbsp;&nbsp;&nbsp;THIS_MODULE
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
&nbsp;&nbsp;&nbsp;&nbsp;.name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= "domain",
&nbsp;&nbsp;&nbsp;&nbsp;.match&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= &match,
&nbsp;&nbsp;&nbsp;&nbsp;.checkentry&nbsp;&nbsp;&nbsp;&nbsp;= &checkentry,
&nbsp;&nbsp;&nbsp;&nbsp;.me&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= THIS_MODULE,
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) */
&nbsp;&nbsp;&nbsp;&nbsp;.name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= "domain",
&nbsp;&nbsp;&nbsp;&nbsp;.match&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= &match,
&nbsp;&nbsp;&nbsp;&nbsp;.family         = AF_INET,
&nbsp;&nbsp;&nbsp;&nbsp;.matchsize      = XT_ALIGN(sizeof(struct ipt_domain_info)),
&nbsp;&nbsp;&nbsp;&nbsp;.checkentry&nbsp;&nbsp;&nbsp;&nbsp;= &checkentry,
&nbsp;&nbsp;&nbsp;&nbsp;.me&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= THIS_MODULE,
#endif
};


static int __init init(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;return ipt_register_match(&domain_match);
}


static void __exit fini(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;ipt_unregister_match(&domain_match);
}


module_init(init);
module_exit(fini);


MODULE_AUTHOR("Platinum, bbs.chinaunix.net");
MODULE_DESCRIPTION("A module to match DOMAIN. VERSION: 0.0.3");
MODULE_LICENSE("GPL");


[ 本帖最后由 platinum 于 2009-12-18 18:49 编辑 ]

domain-0.0.3.tar.gz

4.14 KB, 下载次数: 646

评分

参与人数 1可用积分 +30 收起 理由
T-Bagwell + 30 精品文章,白金终于放血了

查看全部评分

论坛徽章:
0
发表于 2009-12-18 19:23 |显示全部楼层
冒昧的问一下:
iptables -A FORWARD -m domain --name "www.chinaunix.net" -j DROP

iptables -A FORWARD -s www.chinaunix.net -j DROP
iptables -A FORWARD -d www.chinaunix.net -j DROP
的区别是什么?

论坛徽章:
0
发表于 2009-12-18 21:29 |显示全部楼层
白金兄这个domain 以前就学习过了^_^

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2009-12-18 23:07 |显示全部楼层
顶一下白金兄的好文

论坛徽章:
0
发表于 2009-12-18 23:20 |显示全部楼层
顶一下,最近很多强文啊。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2009-12-18 23:30 |显示全部楼层
是啊,希望大家多多发好文,一起交流。。

论坛徽章:
0
发表于 2009-12-19 10:55 |显示全部楼层
让楼上几位大牛见笑了,和你们比我还差得太远了

论坛徽章:
0
发表于 2009-12-19 10:57 |显示全部楼层
原帖由 marsaber 于 2009-12-18 19:23 发表
冒昧的问一下:
iptables -A FORWARD -m domain --name "www.chinaunix.net" -j DROP

iptables -A FORWARD -s www.chinaunix.net -j DROP
iptables -A FORWARD -d www.chinaunix.net -j DROP
的区别是什么?

不一样,后者是匹配 IP 地址,而前者是匹配 DNS 域名解析
当多个域名公用一台服务器时,后者会误杀
当一个域名多个 IP 时,后者会漏杀
当用户使用 hosts 的方式自定义 HOST 及 IP,前者会无效
所以,各有优缺点

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2009-12-19 11:08 |显示全部楼层
原帖由 platinum 于 2009-12-19 10:55 发表
让楼上几位大牛见笑了,和你们比我还差得太远了


白金兄不要过谦了,不管是资历还是经验,你都是大佬啊。:wink:
希望能够多分享一下开发设计的经验给偶们这些后来者。。。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2009-12-19 11:10 |显示全部楼层
原帖由 platinum 于 2009-12-19 10:57 发表

不一样,后者是匹配 IP 地址,而前者是匹配 DNS 域名解析
当多个域名公用一台服务器时,后者会误杀
当一个域名多个 IP 时,后者会漏杀
当用户使用 hosts 的方式自定义 HOST 及 IP,前者会无效
所以,各有 ...


也就是第1条规则,如果本地缓存已经有DNS的解析结果时,就不会被命中了。
但是后面的规则其本质是内部转换成IP,然后按照IP去过滤了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP