一、原理

防火墙的概述

工作于网络或主机边缘,对进出本网络或本主机的网络报文按照事先设定好的匹配规则进行检查,对能够被规则所匹配的报文按照规则定义的处理机制进行处理的组件。


防火墙分类

1、从软硬形式上分为软件防火墙和硬件防火墙以及芯片级防火墙。

2、从技术分为“包过滤型”和“应用代理型”两大类。

3、从结构分为单一主机防火墙、路由器集成式防火墙和分布式防火墙三种。

4、按应用部署位置分为边界防火墙、个人防火墙和混合防火墙三大类。

5、按性能分为百兆级防火墙和千兆级防火墙。

6、按防火墙使用方法分为网络层防火墙,物理层防火墙和链路层防火墙三类。


iptables使用简介

iptables防火墙由Netfilter项目开发,自2001年1月Linux2.4内核发布以来,它就成为Linux一部分了。

多年来,iptables已发展成为一个功能强大的防火墙,它已具备通常只会在专用的商业防火墙中才能发现的大多数功能。例如,iptables提供了全面的协议状态跟踪、数据包的应用层检查、速率限制和一个功能强大的机制以指定过滤策略。所有主流的Linux发行版都包含了iptables,而且许多发行版在系统安装过程中就提示用户部署iptables策略。


iptables表的定义

表示iptables构建块,它描述了其功能的大类,如包过滤或网络地址转换(NAT)。iptables中共有4个表:filter、nat、mangle和raw。过滤规则应用于filter表,NAT规则应用于nat表,用于修改分组数据的特定规则应用于mangle表,而独立于Netfilter连接跟踪子系统其作用的规则应用于raw表。


iptable链的定义

每个表都有自己的一组内置链,用户还可以对链进行自定义,这样用户就可以建立一组规则,它们都关联到一个共同的标签如INPUT_ESTABLISHED或DMZ_NETWORK。最终要的是内置链是filter表中的INPUT、OUTPUT、FORWARD链。

□当一个数据包有内核中的路由计算确定为指向本地Linux系统(即该数据报指向一个本地套接字)之后,它将经过INPUT链的检查。

□OUTPUT链保留给由Linux系统自身生成的数据包。

□FORWARD链管理经过Linux系统路由的数据包(即当iptables防火墙用于连接两个网络,并且两个网络之间的数据包必须流经该防火墙)。

另外两个对于关键iptables部署很重要的链是nat表中的PREOUTING和POSTINGOUTING链,它们分别用于在内核进行IP路由计算之前和之后修改数据报的头部。

如下图所示iptables数据报流程图


iptables详解_数据包

iptables匹配

--source(-s)----匹配源IP地址或网络
--destination(-d)---匹配目标IP地址或网络
--protocol(-p)----匹配IP值
--in-interface(-i)----流入接口(例如,eth0)
--out-interface(-o)---流出接口
--state---匹配一组连接状态
--string---匹配应用层数据字节序列
--comment---在内核内存中为一个规则关联多达256个字节的注释数据
显示扩展匹配
-m state --state   匹配状态的
-m mutiport --source-port   端口匹配 ,指定一组端口
-m limit --limit 3/minute   每三分种一次
-m limit --limit-burst  5   只匹配5个数据包
-m string --string --algo bm|kmp --string "xxxx"  匹配字符串
-m time --timestart 8:00 --timestop 12:00  表示从哪个时间到哪个时间段
-m time --days    表示那天
-m mac --mac-source xx:xx:xx:xx:xx:xx 匹配源MAC地址
-m layer7 --l7proto qq   表示匹配腾讯qq的 当然也支持很多协议,这个默认是没有的,需要我们给内核打补丁并重新编译内核及iptables才可以使用 -m layer7 这个显示扩展匹配

iptable目标

ACCEPT----运行数据包通过;
DROP---丢弃数据包,不对该数据包做进一步的处理,对接收栈而言,就好像该数据包从来没有被接收一样;
LOG---将数据包信息记录到syslog;
REJECT---丢弃数据包,同时发送适当的响应报文
RETURN---在调用链中继续处理数据包


iptables几种状态机制

NEW:其所指的是每一条连接中的第一个数据报

RELATED:"被动产生的响应数据包,而且这个数据报不属于现在任何连接的数据包"

ESTABLISHED: 只要发送并接到应答,一个数据包的状态就从NEW变为ESTABLEISHED,而且该状态会继续匹配这个连接后继数据包。

INVALID:它不属于ESTABLISHED、NEW、RELATED这三种,通常将其视为恶意的数据包而丢弃

注:有关TCP状态的详细内容请查看此博客链接iptables连接状态详解

二、实战

(1)报文匹配

首先关闭INPUT、OUTPUT、FORWARD的默认策略

iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP


放行192.168.2.0网段的地址访问本机名node1,地址192.168.2.221的22端口

iptables -A INPUT -s 192.168.2.0/24 -d 192.168.2.221 -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT  -s 192.168.2.221 -d 192.168.2.0/24 -p tcp --sport 80 -j ACCEPT

匹配的报文响应:

[root@node1 ~]# iptables -L -n -v --line-number
Chain INPUT (policy DROP 42 packets, 4720 bytes)
    1      612 47362 ACCEPT     tcp  --  *      *       192.168.2.0/24       192.168.2.221       tcp dpt:22
1      108 14880 ACCEPT     tcp  --  *      *       192.168.2.221        192.168.2.0/24      tcp spt:22


放行192.168.2.0网段的地址访问本机名node1,地址192.168.2.221的80端口        

iptables -I INPUT 2 -s 192.168.2.0/24 -d 192.168.2.221 -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -s 192.168.2.221 -d 192.168.2.0/24 -p tcp --sport 80 -j ACCEPT


192.168.2.221的主机ping通192.168.2.0网段,同时是192.168.2.0网段也可以ping通该主机

iptables -A OUTPUT -s 192.168.2.221 -d 192.168.2.0/24 -p icmp --icmp-type 8 -j ACCEPT
iptables -A INPUT -s 192.168.2.0/24 -d 192.168.2.221 -p icmp --icmp-type 0 -j ACCEPT


iptables -A OUTPUT -s 192.168.2.221 -d 192.168.2.0/24 -p icmp --icmp-type 0 -j ACCEPT
iptables -A OUTPUT -s 192.168.2.221 -d 192.168.2.0/24 -p icmp --icmp-type 8 -j ACCEPT

注:icmp 8 是请求,icmp 0是响应

基于放行SSH端口的状态匹配

iptables -I INPUT 1 -s 192.168.2.0/24 -d 192.168.2.221 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -R OUTPUT 1 -s 192.168.2.221 -d 192.168.2.0/24 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

总结:对于OUTPUT链来说,可以将所有已建立的报文,统统写成一条语句进行匹配。优化IPTALBES查询

iptables -I OUTPUT 1 -s 192.168.2.221 -m state --state ESTABLISHED -j ACCEPT

基于开放FTP服务的请求

首先需要开启iptalbes中FTP模块功能。有以下两种方法:

   1、modprobe nf_conntrack_ftp

   2、编辑/etc/sysconfig/iptables-config文件

  IPTABLES_MODULES="nf_conntrack_ftp"

iptables -A INPUT -s 192.168.2.0/24 -d 192.168.2.221 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT  -s 192.168.2.0/24 -d  192.168.2.221 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -R OUTPUT 1  -s 192.168.2.221 -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables多端口匹配,将之前的21,22,80端口服务合并成一条策略

iptables -I INPUT 2  -d 192.168.2.221 -s 192.168.2.0/24 -p tcp -m state --state  NEW -m multiport --destination-ports 21,22,80 -j ACCEPT

通过测试,发现每次新的请求后,该报文所匹配的策略都会增1

pkts bytes target     prot opt in     out     source               destination   
 848 64014 ACCEPT     all  --  *      *       192.168.2.0/24       192.168.2.221       state RELATED,ESTABLISHED
   7   364 ACCEPT     tcp  --  *      *       192.168.2.0/24       192.168.2.221       state NEW multiport dports 21,22,80

limit速率匹配:对22端口每分钟12个连接请求,一次最多2个

iptables -I INPUT 2 -s 192.168.2.0/24 -d 192.168.2.222 -m state --state NEW -m limit --limit 12/min --limit-burst 2 -j ACCEPT

(2)虚拟机环境配置

网络拓扑草图,如下:

iptables详解_数据包_02

虚拟机环境配置:


route add default gw 192.168.2.222

① 测试主机node1 ping 主机iptables eth1:172.16.100.1;可以ping通。原理:地址属于主机不属于网卡,这个地址属于iptables,不需要做路由   转发。

②测试主机node1 eth0:192.168.2.221能否ping同172.16.100.10;先将主机iptables开启路由转发模式

systel -w net.ipv4.ip_forward=1

测试结果,仍然ping不通;原理:172.16.100.10要与192.168.2.221通信,必须要把172.16.100.10的默认网关指向172.16.100.1。否则主机找不到网络。

route add default gw 172.16.100.1

测试结果,主机node1 eth0:192.168.2.221可以ping通主机web/ftp eth0:172.16.100.10;同理node1可以与web/ftp服务器的80,21端口互通。

(3)SNAT实战

原理:SNAT target是用来做源网络地址转换的,就是重写包的源IP地址。作用就是让所有从本地网出发的包看起来都是从一台主机发出的,这台主机一般就是防火墙。

SNAT只能用在nat表的POSTROUTING链。

①凡是源地址192.168.2.0网络来的报文请求,统统做SNAT转发到172.1600.1的地址上

iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -j SNAT --to-source 172.16.100.1

测试结果:主机node1 访问主机web/ftp服务器的80端口请求

curl http://172.16.100.10
<h1>www.test.com</h1>

查看主机web/ftp apache日志

172.16.100.1 -- [10/Dec/2013:10:35:03 +08000}"GET /HTTP/1.1" 200

证实web访问的地址是172.16.100.1,SNAT已经生效成功。

②实现SNAT多端口匹配,放行源地址192.168.2.0/24过来的21,22,80端口服务请求

iptables -I FORWARD 1 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -s 192.168.2.0/24 -m state --state NEW -p tcp -m multiport --destination-ports 21,22,80 -j ACCEPT

测试后,主机node1,ssh、ftp、web都可以访问。

(4)DNAT实战

DNAT原理:

   DNAT target是用来做目地网络地址转换的,就是重写包的目的IP地址。如果一个包被匹配了,那么和它属于同一个流的所有的包都会被自动转换,然后就可以被路由到正确的主机或网络。DNAT target适合在,你的WEB服务器在局域网内部,而且公网地址有限,那就可以用target让防火墙把所有到它自己HTTP端口包转发给内部局域网正在的WEB服务器。

注意:DNAT target只能用在nat表的PREOUTING和OUTPUT链中。如果并发量非常大,有上千或上万个并发请求的生产环境中,不要使用DNAT方式。否则负载过大,直接压垮服务器。

DNAT网络设计草图如下:

iptables详解_数据包_03


2、DNAT实战

①分析:提示给用户公布的WEB地址是192.168.2.222,这台机器上没有提供web服务,需要通过DNAT target将请求过来的包转发给真正内部WEB服务器172.16.100.10

首先需要在路由之前,添加一条规则,凡是目的地址为192.168.2.222,TCP 80端口的数据包,通过DNAT服务转发到172.16.100.10

注:务必开启DNAT,路由转发功能。

具体操作如下:

iptables -t nat -A PREOUTING -d 192.168.2.222 -p tcp --dport 80 -j DNAT --to-destination 172.16.100.10

测试结果如下:

curl http://192.168.2.222
<h1>www.jiabin.com</h1>

证实了DNAT服务生效,用户访问目标地址192.168.2.222的请求,最终相应到真实的web服务器172.16.100.10

同理也可以在NAT表中添加对ssh服务的DNAT转发

iptables -t nat -A PREOTING -d 192.168.2.222 -p tcp --dport 22 -j DNAT --to-destination 172.16.100.10

②FORWARD链配置:

iptables -P FORWARD DROP
#DROP FORWARD的默认规则
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
#匹配ESTABLISHED,RELATED状态的请求报文
iptables -A FORWARD -d 172.16.100.10 -p tcp --dport 80 -m state --state NEW -j ACCEPT
#放行目标地址172.16.100.10,端口80服务的报文请求
iptables -A FORWARD -d 172.16.100.10 -p tcp --dport 22 -m state --state NEW -j ACCEPT
#放行目标地址172.16.100.10,端口22服务的请求报文


总结:IPTABLES是一门艺术,非常的强大。可以防DOS攻击,做端口转换、做7层过滤等等。在这里我就不一一例举了,总之需要熟练的掌握这个工具,需要多下功夫,多去思考,多多操作。