分享
 
 
 

linux防火墙实现技术比较

王朝system·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

一 前言

此文是在aka(www.aka.org.cn)的一次讲座稿【12】基础之上修改而成(催稿,没办法),着重阐述linux下

的防火墙的不同实现之间的区别,以ipchains, iptables, checkpoint FW1为例。

二 基本概念

2.0

在进入正题之前,我将花少许篇幅阐述一些基本概念。尽管防火墙的术语这些年基本上没有太大的变化,但是如果你以前只看过90年代初的一些文献的话,有些概念仍然会让你混淆。此处只列出一些最实用的,它们不是准确的定义,我只是尽可能的让它们便于理解而已。

2.1 包过滤:

防火墙的一类。80年代便有论文来描述这种系统。传统的包过滤功能在路由器上常可看到,而专门的防火墙系统一般在此之上加了功能的扩展,如状态检测等。它通过检查单个包的地址,协议,端口等信息来决定是否允许此数据包

通过。

2.2 代理:

防火墙的一类。工作在应用层,特点是两次连接(browser与proxy之间,proxy与web server之间)。如果对原理尚有疑惑,建议用sniffer抓一下包。代理不在此文的讨论范围之内。

2.3 状态检测:

又称动态包过滤,是在传统包过滤上的功能扩展,最早由checkpoint提出。传统的包过滤在遇到利用动态端口的协议时会发生困难,如ftp。你事先无法知道哪些端口需要打开,而如果采用原始的静态包过滤,又希望用到的此服务的话,就需要实现将所有可能用到的端口打开,而这往往是个非常大的范围,会给安全带来不必要的隐患。 而状态检测通过检查应用程序信息(如ftp的PORT和PASS命令),来判断此端口是否允许需要临时打开,而当传输结束时,端口又马上恢复为关闭状态。

2.4 DMZ非军事化区:

为了配置管理方便,内部网中需要向外提供服务的服务器往往放在一个单独的网段,这个网段便是非军事化区。防火墙一般配备三块网卡,在配置时一般分别分别连接内部网,internet和DMZ。

2.5

由于防火墙地理位置的优越(往往处于网络的关键出口上),防火墙一般附加了NAT,地址伪装和VPN等功能,这些不在本文的讨论范围。

三 检测点

3.0 综述

包过滤需要检查IP包,因此它工作在网络层,截获IP包,并与用户定义的规则做比较。

3.1 ipchains

摘自【3】

----------------------------------------------------------------

| ACCEPT/ lo interface |

v REDIRECT _______ |

--> C --> S --> ______ --> D --> ~~~~~~~~ -->|forward|----> _______ -->

h a |input | e {Routing } |Chain | |output |ACCEPT

e n |Chain | m {Decision} |_______| --->|Chain |

c i |______| a ~~~~~~~~ | | ->|_______|

k t | s | | | | |

s y | q | v | | |

u | v e v DENY/ | | v

m | DENY/ r Local Process REJECT | | DENY/

| v REJECT a | | | REJECT

| DENY d --------------------- |

v e -----------------------------

DENY

总体来说,分为输入检测,输出检测和转发检测。但具体到代码的时候,输出检测实际分散到了几处(不同的上层协议走IP层的不同的流程):

UDP/RAW/ICMP报文:ip_build_xmit

TCP报文:ip_queue_xmit

转发的包:ip_forward

其它:ip_build_and_send_pkt

正如ipchains项目的负责人Rusty Russell所说,在开始ipchians不久,便发现选择的检测点位置错了,最终只能暂时将错就错。一个明显的问题是转发的包在此结构中必须经过三条链的匹配。地址伪装功能与防火墙模块牵扯过于紧密,如果不详细了解其原理的话,配置规则很容易出错。

此部分详细的分析可参见我早期的一份文章【9】。

3.2 iptables

A Packet Traversing the Netfilter System:

--->PRE------>[ROUTE]--->FWD---------->POST------>

Conntrack | Filter ^ NAT (Src)

Mangle | | Conntrack

NAT (Dst) | [ROUTE]

(QDisc) v |

IN Filter OUT Conntrack

| Conntrack ^ Mangle

| | NAT (Dst)

v | Filter

2.4内核中的防火墙系统不是2.2的简单增强,而是一次完全的重写,在结构上发生了非常大的变化。相比2.2的内核,2.4的检测点变为了五个。

在每个检测点上登记了需要处理的函数(通过nf_register_hook()保存在全局变量nf_hooks中),当到达此检测点的时候,实现登记的函数按照一定的优先级来执行。严格的从概念上将,netfilter便是这么一个框架,你可以在适当的位置上登记一些你需要的处理函数,正式代码中已经登记了许多处理函数(在代码中搜nf_register_hook的调用),如在NF_IP_FORWARD点上登记了装发的包过滤功能。你也可以登记自己的处理函数,具体例子可参看【8】与【10】。

3.3 FW1

FW1是chekpoint推出的用于2.2内核的防火墙。由于其发布的模组文件带了大量的调试信息,可以从反汇编的代码中窥探到到许多实现细节。

FW1通过dev_add_pack的办法加载输入过滤函数,如果对这个函数不熟悉,请参看【14】。但是此处有个问题:在net_bh()中,传往网络层的skbuff是克隆的,即

skb2=skb_clone(skb, GFP_ATOMIC);

if(skb2)

pt_prev->func(skb2, skb->dev, pt_prev);

这样的话如果你想丢弃此包的话,光将其free掉是不够的,因为它只是其中的一份拷贝而已。

FW1是怎么解决这个问题的呢?见下面的代码(从汇编代码翻译成的C程序):

packet_type *fw_type_list=NULL;

static struct packet_type fw_ip_packet_type =

{

__constant_htons(ETH_P_IP),

NULL, /* All devices */

fw_filterin,

NULL,

NULL, /* next */

};

fwinstallin(int isinstall )

{

packet_type *temp;

/*安装*/

if(isinstall==0){

dev_add_pack(&fw_ip_packet_type);

fw_type_list = fw_ip_packet_type->next;

for(temp = fw_type_list; temp; temp=temp->temp)

dev_remove_pack(temp);

}

/*卸载*/

else {

dev_remove_pack(&fw_ip_packet_type);

for(temp = fw_ip_packet_type; temp; temp=temp->next)

dev_add_pack(temp);

}

}

不难看出,FW1把ip_packet_type歇载掉了,然后自己在自己的处理函数(fw_filterin)中调ip_recv。

输出的挂载和lkm的手法一样,更改dev->hard_start_xmit。dev结构在2.2版本的发展过程中变了一次,为了兼容FW1对这点也做了处理(通过检查版本号来取偏移)。

还有一款linux下的防火墙产品WebGuard(http://www.gennet.com.tw/b5/csub_webguard.html)采用的手法与FW1其非常类似。有兴趣的人可以自行研究一下。

四 规则

4.0 综述

4.1 ipchains

man ipfw可以看到这一段的详细解释。关键数据结构如下:

规则链用ip_chain结构来表示,缺省有input,ouptput,forward三条链。在配置规则的时候,也可以添加新的链。每条链事实上就是一组相关的规则,以链表的形式存储。

struct ip_chain

{

ip_chainlabel label; /* Defines the label for each block */

struct ip_chain *next; /* Pointer to next block */

struct ip_fwkernel *chain; /* Pointer to first rule in block */

__u32 refcount; /* Number of refernces to block */

int policy; /* Default rule for chain. Only *

* used in built in chains */

struct ip_reent reent[0]; /* Actually several of these */

};

每条规则用一个ip_fwkernel结构表示:

struct ip_fwkernel

{

struct ip_fw ipfw;

struct ip_fwkernel *next; /* where to go next if current

* rule doesn't match */

struct ip_chain *branch; /* which branch to jump to if

* current rule matches */

int simplebranch; /* Use this if branch == NULL */

struct ip_counters counters[0]; /* Actually several of these */

};

ip_fwkernel中的一个重要部分就是ip_fw,用来表示待匹配的数据包消息:

struct ip_fw

{

struct in_addr fw_src, fw_dst; /* Source and destination IP addr */

struct in_addr fw_smsk, fw_dmsk; /* Mask for src and dest IP addr */

__u32 fw_mark; /* ID to stamp on packet */

__u16 fw_proto; /* Protocol, 0 = ANY */

__u16 fw_flg; /* Flags word */

__u16 fw_invflg; /* Inverse flags */

__u16 fw_spts[2]; /* Source port range. */

__u16 fw_dpts[2]; /* Destination port range. */

__u16 fw_redirpt; /* Port to redirect to. */

__u16 fw_outputsize; /* Max amount to output to

NETLINK */

char fw_vianame[IFNAMSIZ]; /* name of interface "via" */

__u8 fw_tosand, fw_tosxor; /* Revised packet priority */

};

2.2内核中网络包与规则的实际匹配在ip_fw_check中进行。

4.2 iptables

一条规则分为三部分:

struct ipt_entry file://主要用来匹配IP头

struct ip_match file://额外的匹配(tcp头,mac地址等)

struct ip_target file://除缺省的动作外(如ACCEPT,DROP),可以增加新的(如REJECT)。

man iptable:

>A firewall rule specifies criteria for a packet, and a

>target. If the packet does not match, the next rule in

>the chain is the examined; if it does match, then the next

>rule is specified by the value of the target, which can be

>the name of a user-defined chain, or one of the special

>values ACCEPT, DROP, QUEUE, or RETURN.

2.4内核中网络包与规则的实际匹配在ip_do_table中进行。这段代码的流程在

netfilter hacking howto 4.1.3描述的非常清楚。

简化代码如下:

/* Returns one of the generic firewall policies, like NF_ACCEPT. */

unsigned int

ipt_do_table(struct sk_buff **pskb,

unsigned int hook,

const struct net_device *in,

const struct net_device *out,

struct ipt_table *table,

void *userdata)

{

struct ipt_entry *e;

struct ipt_entry_target *t;

unsigned int verdict = NF_DROP;

table_base = (void *)table->private->entries

+ TABLE_OFFSET(table->private,

cpu_number_map(smp_processor_id()));

e = get_entry(table_base, table->private->hook_entry[hook]);

...

ip_packet_match(ip, indev, outdev, &e->ip, offset);

...

IPT_MATCH_ITERATE(e, do_match, *pskb, in, out, offset, protohdr, datalen, &hotdrop)

...

t = ipt_get_target(e);

...

verdict = t->u.kernel.target->target(pskb, hook, in, out, t->data, userdata);//非标准的target走这一步

...

return verdict;

}

流程:

--->NF_HOOK();(/include/linux/netfilter.h)

--->nf_hook_slow;(/net/core/netfilter.c)

--->nf_iterate();(/net/core/netfilter.c)

--->然后运行登记的函数;如果你希望有一套ipt_entry结构规则,并将它放到table里,你此时便可调用ipt_do_table来匹配。

在2.4内核中,规则本身也是可扩展的,体现可自己定义并添加新的ip_match和ip_target上。

4.2 FW1

未作分析。

五 与应用层的交互

5.0 综述

防火墙除了内核里的功能以外,还需要在应用层有相应的的配置工具,如添加修改规则等,这就涉及如何与内核通信的问题。

内核模块有三种办法与进程打交道:首先是系统调用,缺点是必须添加新的系统调用或修改原有的,造成对内核代码原有结构的变换;第二种办法是通过设备文件(/dev目录下的文件),不必修改编译原有的代码,但在使用之前要先用mknod命令产生一个这样的设备;第三个办法便是使用proc文件系统。

5.1 ipchains

由于ipchains是已经是内核的正式一部分,它采用了修改系统调用的办法来添加修改命令,采用的办法就是扩展setsockopt系统调用:

int setsockopt (int socket, IPPROTO_IP, int command, void *data, int length)

man ipfw可以获得这方面的细节。

ipchains应用程序首先要需要建立一个raw socket(libipfwc.c),然后在之上调用setsockopt。

sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)

调用顺序:

ipchains在应用层调用setsockopt,进入内核:

--->sys_socketcall(net/socket.c)

--->sys_setsockopt(net/socket.c)

--->inet_setsockopt[1] [url=http://www.chinamx.com.cn/Article/os/Linux/200605/20060530130021_28777_2.html][2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有