防火墙功能技术与实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1 引言
本文以防火墙功能分类为框架,逐个探讨了每项功能的详细技术及实现,其中具体实现均取自linux系统.
之所以采用linux系统作技术分析,主要是因为其本身已基本实现了防火墙系统的各类功能且经受了足够考验,因此具有极大的参考价值.
本文所描述的功能如下:
1. NAT;
2. 负载均衡(load balance,又称virtual server);;
3. 包过滤;
4. 日志;
5.流量统计
6. VPN;
7. 内容安全;
8. 身份验证;
9. 入侵监测.
防火墙的核心功能(包过滤,伪装,负载均衡)在IP层实现,其余大部分功能属于应用层实现(VPN除外,因为利用了封装机制,很难说究竟在那一层).尽管我们说核心功能在IP层实现, 但实际上只是这些功能函数
(call_in_firewall(),call_fw_firewall(),call_out_firewall(),
ip_fw_masquerade(),及ip_fw_demasquerade()等)在网络层被调用,真正在完成这些功能时也用到了上层协议(TCP/UDP/ICMP)的头信息(如根据端口,flag标志,ICMP类型进行过滤等).
2 linux网络部分代码分析
(注:加入这一部分主要是因为目前没有一篇文章结合最新的2.2内核讲述了linux的网络原理,在此介绍一下其流程会有助于整体的理解.)
Linux网络层采用统一的缓冲区结构skbuff(include/skbuff.h)。底层从网络设备接收到数据帧后,分配一块内存,然后将数据整理成skbuff的结构.在网络协议处理的时候,数据均以skbuff的形式在各层之间传递、处理.
一个个单独的skbuff被组织成双向链表的形式.
Skbuff的强大功能在于它提供了众多指针,可以快速的定位协议头位置;它也同时保留了许多数据包信息(如使用的网络设备等),以便协议层根据需要灵活应用.
整个网络层的流程如下(以两个进程通过TCP/IP进行通信为例):
IP协议层有三个关键函数:ip_rcv()、ip_forward()、ip_output(),分别处理IP层的接收、转发和发送工作.防火墙的功能函数将在此三个函数中调用.
3功能实现分析
1. NAT.
简单的讲,网络地址转换(NAT)是将一个(或一组)IP地址转换成另一个(或一组)IP地址.
由于网络地址的缺乏和出于安全等因素的考虑,许多公司和机构采用了私有IP 地址(RFC 1918)来建立自己的内部网络,但为了实现与internet的互连,必须对外表现为合法的IP.通过带有NAT功能的路由器或防火墙,便可实现私有与合法IP的转换.
概念上,NAT可分为静态NAT (static address translation)和动态
NAT(dynamic address
translation):
静态NAT-----------私有IP与合法IP之间是一一映射关系,每一个内部IP都有一个外部IP与之对应,系统通过维持一张固定的映射表来实现此种功能.
linux中,在2.2.4版本中曾有专门的一部分处理静态的地址转换,并用相应的应用层工具
ipnatadm 来管理,但到了2.2.13内核(我主要看的版本)中,无论是文件还是相关函数都有了
非常大的改变.与静态地址转换相关的文件只有/ipv4/ip_nat_dumb.c,其中只有ip_do_nat()
一个函数.此函数在ip_forward(),和ip_output()中被调用.其作用是修改转发和发送的包的
源和目的地址(仅此功能而已).但是我却未能发现与之相关的上层接口和应用层管理工具.
(编译内核时要指定CONFIG_IP_ROUTE_NAT 和
CONFIG_IP_MULYIPLE_TABLE).
动态NAT--------------动态的决定外部与内部的IP地址之间的映射关系.此时可用的合法IP数往往少于内部网的主机数,极端的情况便是linux中的IP伪装(多对一的映射).
对实际的应用来说,此时仅仅改变IP地址已经不够,必须同时利用TCP/UDP的端口号来实现多台主机共用一个地址.此时防火墙必须维持一个动态的映射表,且随时要对此表进行更新.
原理如下图所示:
伪装功能相关文件有(均在 /ipv4目录):
ip_masq.c ip_masq_app.c ip_masq_autofw.c
ip_masq_cuseeme.c ip_masq_ftp.c ip_masq_irc.c
ip_masq_mfw.c ip_masq_mod.c ip_masq_portfw.c
ip_masq_quake.c ip_masq_raudio.c ip_masq_user.c
ip_masq_vdolive.c
头文件有:
#include
#include
#ifdef CONFIG_IP_MASQUERADE_MOD
#include
#endif
其中最主要的文件是ip_masq.c,它定义了对应用层的接口和实际的地址伪装处理过程.其余文件大多是根据专门应用的扩展.
流程为(没有结合包过滤):
当IP层接受到信息(ip_rcv)以后,在确定信息准确无误后,查路由,伪装的包和去往防火墙本身的包的目的地址均是防火墙的对外地址,IP层将用
ip_local_deliver()进行处理,其中便调用了ip_fw_demasquerade()。解伪装会将真正的目的地址和端口恢复出来,经过再次查路由,如果是发往本地的包,则交给相应的上层去处理(tcp_ipv4_rcv, udp_rcv, raw_rcv 等),否则调用
ip_forward().
ip_fw_masquerade()则在ip_forward()中被调用.
具体算法:
公开地址与内部地址的映射表采用的数据结构是ip_masq(在
/include/net/ip_masq.h中定义),其格式为:
struct ip_masq {
struct list_head m_list, s_list, d_list; /* hashed d-linked list heads */
atomic_t refcnt; /* reference count */
struct timer_list timer; /* Expiration timer */
/******************************************************************** ***
以下几个是最重要的参数,分别为所用的协议(protocol),源、目的地址(saddr,daddr),源、目的端口(sport,dport),经伪装后的地址、端口(maddr,mport).
********************************************************************* */
__u16 protocol; /* Which protocol are we talking? */
__u16 sport, dport, mport; /* src, dst & masq ports */
__u32 saddr, daddr, maddr; /* src, dst & masq addresses */
/******************************************************************** **/
struct ip_masq_seq out_seq, in_seq;