Linux内核--基于Netfilter的内核级包过滤防火墙实现

fenxinzi 2012-05-29

测试内核版本:Linux Kernel 2.6.35----Linux Kernel 3.2.1

知识基础:本防火墙的开发基于对Linux内核网络栈有个良好的概念,本人对网络栈的分析是基于早期版本(Linux 1.2.13),在明确了网络栈架构的前提下,上升一步分析高级版本内核中的Netfilter防火墙实现原理,然后进行模块或内核编程,开发一款基于包过滤的个人防火墙。

包过滤防火墙:包过滤防火墙是用一个软件查看所流经的数据包的包头(header),由此决定整个包的命运。它可能会决定丢弃(DROP)这个包,可能会接受(ACCEPT)这个包(让这个包通过),也可能执行其它更复杂的动作。工作于网络层,能对IP数据报进行首部检查。例如:IP源地址,目的地址,源端口和目的端口等。

本防火墙的包过滤功能如下:  

* 拒绝来自某主机或某网段的所有连接。
  * 允许来自某主机或某网段的所有连接。
  * 拒绝来自某主机或某网段的指定端口的连接。
  * 允许来自某主机或某网段的指定端口的连接。
  * 拒绝发去某主机或某网段的所有连接。
  * 允许发去某主机或某网段的所有连接。
  * 拒绝发去某主机或某网段的指定端口的连接。
  * 允许发去某主机或某网段的指定端口的连接。

Netfilter框架是Linux内核分析和过滤特定协议数据包处理框架,为其他模块动态参与网络层数据包处理提供了方便的途径。

本防火墙的简单功能就是检查数据包是否符合过滤的条件,如果不符合就舍弃(Drop),否则就接受(Accept),这里定义八个链表头结点

  1. struct ip_node  ip_allowed_in_node_head;/*允许的远程主机或网络IP地址头节点*/  
  2. struct ip_node  ip_denied_in_node_head;/*拒绝的远程主机或网络IP地址头节点*/  
  3. struct ip_node  ip_allowed_out_node_head;/*允许的本地主机或网络IP地址头节点*/  
  4. struct ip_node  ip_denied_out_node_head;/*拒绝的本地主机或网络IP地址头节点*/  
  5.   
  6. struct port_node port_allowed_in_node_head;/*允许的远程主机或网络传输层端口号头节点*/  
  7. struct port_node port_denied_in_node_head;/*拒绝的远程主机或网络传输层端口号头节点*/  
  8. struct port_node port_allowed_out_node_head;/*允许的本地主机或网络传输层端口号头节点*/  
  9. struct port_node port_denied_out_node_head;/*拒绝的本地主机或网络传输层端口号头节点*/  

用于保存配置文件中的地址或端口信息。

定义两个钩子函数hook_func_in和hook_func_out,分别将其挂载到INET协议族的入口NF_INET_LOCAL_IN和出口NF_INET_LOCAL_OUT:

  1. static struct nf_hook_ops my_netfilter[] =  
  2. {  
  3.     {  
  4.         .hook       =hook_func_in,  
  5.         .owner      =THIS_MODULE,  
  6.         .pf     =PF_INET,  
  7.         .hooknum    =NF_INET_LOCAL_IN,  
  8.         .priority   =100  
  9.     },  
  10.     {  
  11.         .hook       =hook_func_out,  
  12.         .owner      =THIS_MODULE,  
  13.         .pf     =PF_INET,  
  14.         .hooknum    =NF_INET_LOCAL_OUT,  
  15.         .priority   =100  
  16.     }  
  17. };  

说明一下自己定义的一些宏和引用的头文件:

  1. #ifndef MODULE   
  2. #define MODULE   
  3. #endif   
  4.   
  5. #ifndef __KERNEL__   
  6. #define __KERNEL__   
  7. #endif   
  8. //#define NET_DOWN   
  9. #define MY_FIREWALL_DEBUG   
  10.   
  11. #include <asm/system.h>   
  12. #include <linux/module.h>   
  13. #include <linux/types.h>   
  14. #include <linux/kernel.h>   
  15. #include <linux/string.h>   
  16.   
  17. #include <linux/net.h>   
  18. #include <linux/socket.h>   
  19. #include <linux/sockios.h>   
  20. #include <linux/in.h>   
  21. #include <linux/inet.h>   
  22.   
  23.   
  24. #include <net/ip.h>   
  25. #include <net/protocol.h>   
  26. #include <linux/skbuff.h>   
  27. #include <net/sock.h>   
  28. #include <net/icmp.h>   
  29. #include <net/raw.h>   
  30. #include <net/checksum.h>   
  31. #include <linux/netfilter_ipv4.h>   
  32. #include <linux/tcp.h>   
  33. #include <linux/udp.h>   
  34. #include <linux/igmp.h>   
  35.   
  36. #include <linux/fs.h>   
  37. #include <linux/mm.h>   
  38. #include <asm/uaccess.h>   
  39.   
  40. #define YES 1   
  41. #define NO 0   
  42.   
  43. #define IP_MAX_LEN 20   
  44. #define PORT_MAX_LEN 20   
  45.   
  46. #define ALLOWED_IP_IN 0   
  47. #define DENIED_IP_IN 1   
  48. #define ALLOWED_IP_OUT 2   
  49. #define DENIED_IP_OUT 3   
  50.   
  51. #define ALLOWED_PORT_IN 0   
  52. #define DENIED_PORT_IN 1   
  53. #define ALLOWED_PORT_OUT 2   
  54. #define DENIED_PORT_OUT 3   
  55.   
  56. #define ALLOWED_IN_IP_CONF_FILE_DIR "/etc/my_firewall/ip_allowed_in"   
  57. #define DENIED_IN_IP_CONF_FILE_DIR "/etc/my_firewall/ip_denied_in"   
  58. #define ALLOWED_IN_PORT_CONF_FILE_DIR "/etc/my_firewall/port_allowed_in"   
  59. #define DENIED_IN_PORT_CONF_FILE_DIR "/etc/my_firewall/port_denied_in"   
  60.   
  61. #define ALLOWED_OUT_IP_CONF_FILE_DIR "/etc/my_firewall/ip_allowed_out"   
  62. #define DENIED_OUT_IP_CONF_FILE_DIR "/etc/my_firewall/ip_denied_out"   
  63. #define ALLOWED_OUT_PORT_CONF_FILE_DIR "/etc/my_firewall/port_allowed_out"   
  64. #define DENIED_OUT_PORT_CONF_FILE_DIR "/etc/my_firewall/port_denied_out"   
  65.   
  66. //DEFINE FOR WORK_MODE   
  67.   
  68. /*不工作状态,默认*/  
  69. #define MODE_FREE 0   
  70. /*允许来自某主机或某网段的所有连接*/  
  71. #define MODE_IP_ONLY_ALLOWED_IN 1   
  72.   
  73. /*拒绝来自某主机或某网段的所有连接*/  
  74. #define MODE_IP_ONLY_DENIED_IN 2   
  75.   
  76. /*允许来自某主机或某网段指定端口的连接*/  
  77. #define MODE_IP_PORT_ALLOWED_IN 3   
  78.   
  79. /*拒绝来自某主机或某网段的指定端口的连接*/  
  80. #define MODE_IP_PORT_DENIED_IN 4   
  81.   
  82. /*允许本地主机或本地网络与其他主机或网络的所有连接*/  
  83. #define MODE_IP_ONLY_ALLOWED_OUT 5   
  84.   
  85. /*拒绝本地主机或本地网络与其他主机或网络的所有连接*/  
  86. #define MODE_IP_ONLY_DENIED_OUT 6   
  87.   
  88. /*允许本地主机或网络与其他主机或其他网络的指定端口的连接*/  
  89. #define MODE_IP_PORT_ALLOWED_OUT 7   
  90.   
  91. /*拒绝本地主机或网络与其他主机或其他网络的指定端口的连接*/  
  92. #define MODE_IP_PORT_DENIED_OUT 8  

相关推荐