首先找几本网络编程的书看。
基本了解IP/TCP协议的工作流程。
然后利用原始套接字来捕获数据包,学会对数据包的一些简单利用(可以把我前一篇文章的函数全用一遍)。
接着就可以开始防火墙之旅了。
做一个防火墙,我们首先要知道怎样捕获数据包。
上面的网站介绍了4种捕获数据包的方法,我选择采用的是用netfilter。
这种方法需要内核编程。
要进行内核编程,首先要建立内核树。
编译完内核树就可以开始编写你的防火墙了。
以下是一个简单的模板:
1 #include <linux/kernel.h> 2 #include <linux/module.h> 3 #include <linux/debugfs.h> 4 #include <linux/init.h> 5 #include <linux/types.h> 6 #include <linux/slab.h> 7 #include <linux/netdevice.h> 8 #include <linux/skbuff.h> 9 #include <linux/netfilter_ipv4.h> 10 #include <linux/in.h> 11 #include <linux/proc_fs.h> 12 #include <linux/fs.h> 13 #include <linux/ip.h> 14 #include <linux/netfilter_bridge.h> 15 16 /*在钩子点运行的函数 17 函数的返回值包括: 18 NF_ACCEPT 19 数据包继续在正常的 TCP/IP 路径上传输。 20 NF_DROP 21 丢弃数据包;不进一步处理。 22 NF_STOLEN 23 已获得数据包;不进一步处理。 24 NF_QUEUE 25 对数据包排队(通常用于用户空间处理)。 26 NF_REPEAT 27 再次触发这个钩子。 28 */ 29 30 /*处理要接收的数据包*/ 31 static unsigned int PacketIn(unsigned int hook, 32 struct sk_buff *skb, 33 const struct net_device *in, 34 const struct net_device *out, 35 int (*okfn)(struct sk_buff *) 36 ) 37 { 38 39 } 40 41 /*处理要发出的数据包*/ 42 static unsigned int PacketOut(unsigned int hook, 43 struct sk_buff *skb, 44 const struct net_device *in, 45 const struct net_device *out, 46 int (*okfn)(struct sk_buff *) 47 ) 48 { 49 50 } 51 52 /*处理要转发的数据包*/ 53 static unsigned int PacketForward(unsigned int hook, 54 struct sk_buff *skb, 55 const struct net_device *in, 56 const struct net_device *out, 57 int (*okfn)(struct sk_buff *) 58 ) 59 { 60 61 } 62 63 /*netfilter结构初始化*/ 64 static struct nf_hook_ops scs_ops[] __read_mostly ={ 65 {/*进入的数据包*/ 66 .hook = PacketIn, 67 .pf = PF_INET, 68 .hooknum = NF_INET_LOCAL_IN, 69 .priority = NF_IP_PRI_FIRST, 70 }, 71 {/*发送的数据包*/ 72 .hook = PacketOut, 73 .pf = PF_INET, 74 .hooknum = NF_INET_LOCAL_OUT, 75 .priority = NF_IP_PRI_FIRST, 76 }, 77 {/*转发的数据包*/ 78 .hook = PacketForward, 79 .pf = PF_INET, 80 .hooknum = NF_INET_FORWARD, 81 .priority = NF_IP_PRI_FIRST, 82 }, 83 }; 84 static int init_hook_icmp(void) 85 { 86 /*把钩子注册到内核*/ 87 nf_register_hooks(scs_ops, ARRAY_SIZE(scs_ops)); 88 return 0; 89 } 90 91 static void fini_hook_icmp(void) 92 { 93 /*把钩子注销*/ 94 nf_unregister_hooks(scs_ops, ARRAY_SIZE(scs_ops)); 95 } 96 97 MODULE_LICENSE("GPL"); 98 module_init(init_hook_icmp); 99 module_exit(fini_hook_icmp);
注意内核编程与普通编程所用的函数不一样,编译方法也不一样。
这里有两个例子可以参考一下。
一个简单的入侵检测功能:
过滤的一个例子:
因为防火墙不只是在后台运行,它需要一个应用程序来显示数据或进行其他与用户交互的操作。
所以我们要知道内核与用户空间的通信方式。
目前就这里了。