一、前言

 

        所谓防火墙就是工作在主机或网络边缘,对进出的豹纹根据定义的规则做检查,进而对匹配到的报文作为相应处理的套件;

        防火墙有软件防火墙和硬件防火墙;根据位置可分为本机防火墙和网络防火墙;根据种类可分为包过滤、应用代理、状态检测。

·包过滤即检查每一个数据包,查看包中的一些基本信息,如源地址、目的地址、端口号、协议等

·应用代理工作在应用层,检查包的所有数据,相对来说会更加安全,但是效率不高,如果对速度要求高,可能会成为瓶颈

·状态检测是从动态包过滤上演化而来的,不仅有包过滤的功能,而且可以在每个连接建立时,防火墙会为这个连接构造一个会话状态,里面包含了这个连接数据包的所有信息,以后这个连接都会基于这个连接的信息进行。状态检测可以对包的内容进行分析,从而摆脱了,从而摆脱了传统防火墙仅局限于过滤包头信息的弱点,而且这种防火墙可以不必开放过多的端口,从而杜绝了开放过多端口带来的隐患。

 

 

二、iptables/netfilter

1、iptables的前身叫ipfirewall,2.20核心被ipchain所取代,Linux2.4以后叫iptables,他可以将规则组织成一张表,实现详细的访问控制功能。

iptables是一种工具,工作在用户空间,用于修改信息的过滤规则及其他配置。

netfilter是内核中的一部分,用于定义、保存响应的规则。

 

2、netfilter工作原理

netfilter在内核中提供了一系列表(table),每个表由若干链(chain)组成,每个链可以由一条或数条规则(rules)组成。在内核空间中设置了5个钩子函数对进出主机的数据包进行过滤。

1、PREROUTING (路由前)

2、INPUT (进入本机)

3、FORWARD (转发)

4、OUTPUT (本机流出)

5、POSTROUTING (路由后)
 

计算机生成了可选文字: mangle: INPUT  filter: INPUT  raw: OUTPUT  mangle: OUTPUT  nat: OUTPUT  filter: OUTPUT  mangle: POSTROUTING  nat: POSTROUTING  raw: PREROUTING  mangle: PREROUTING  nat: PREROUTING  mangle: FORWARD  filter: FORWARD

 

3、表、链、规则、动作

netfilter是表的容器,表是链的容器,链又是规则的容器。

表(Tables)

raw表 用于配置数据包,raw中的数据包不会被系统追踪。

mangle表  该表用于数据包的特殊变更操作,如TOS、TTL、MARK等特性。

nat表 能够修改数据包,并完成网络地址转换。

filter表 用于存放所有防火墙相关的默认表,通常使用该表进行过滤的设置。

计算机生成了可选文字: raw*  PREROlJTlNGi  OUTP  mangle 表  PREROUTIN*  POSTR01JTlNGi  INPUT 涟  P 翦 链  nat 表  PREROUTING 链  POSTROUTING  0 翦 P 酊 链  表  第 1 条 影 刂  第 2 条 影 刂  第 3 条 影 刂  INPUTi  FORWARD 链  P 酊 链

raw表有2个内置链: PREROUTING, OUTPUT

# iptables -t raw -L

Chain PREROUTING (policy ACCEPT)

target     prot opt source               destination        

Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination

 

mangle表有5个内置链: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING

# iptables -t mangle -L

Chain PREROUTING (policy ACCEPT)

target     prot opt source               destination        

Chain INPUT (policy ACCEPT)

target     prot opt source               destination        

Chain FORWARD (policy ACCEPT)

target     prot opt source               destination        

Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination        

Chain POSTROUTING (policy ACCEPT)

target     prot opt source               destination

 

nat表有3个内置链:PREROUTING, FORWARD, POSTROUTING

# iptables -t nat -L

Chain PREROUTING (policy ACCEPT)

target     prot opt source               destination        

Chain POSTROUTING (policy ACCEPT)

target     prot opt source               destination        

Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination

 

filter表有3个内置链: INPUT, FORWARD, OUTPUT

# iptables -t filter -L

Chain INPUT (policy ACCEPT)

target     prot opt source               destination        

Chain FORWARD (policy ACCEPT)

target     prot opt source               destination        

Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination

 

 

 

链 (Chains)

PREROUTING    路有前,到达的数据包

INPUT                路由后,发往本机的数据包

FORWARD        路由经过本地的数据包,目的地不是本机

OUTPUT            路由之前,本地产生的数据包

POSTROUTING 路由后,发往网卡接口之前的数据包

 

动作(Target)

ACCEPT    允许数据包通过

DROP       丢弃数据包

REJECT     丢弃数据包并返回错误

LOG          将符合条件的数据包写入日志

QUEUE     传递给应用程序处理该数据包

 

计算机生成了可选文字: PREROUTIN  raw  mangle  nat--DNAT  INPUT  mangle  filter  FORWARD  mangle  filter  LOCAL HOST  POSTROUTIN  mangle  nat--SNAT  OUTPUT  raw  mangle  nat  filter

 

4、数据报文的流向

 

4.1 如果是跟本机内部进行通信

流入:--> PREROUTING,  --> INPUT

流出:--> OUTPUT, --> POSTROUTING

 

4.2 有本机转发

请求: --> PRETOUTING, --> FORWARD, --> POSTROUTING

响应: --> PRETOUTING, --> FORWARD, --> POSTROUTING

 

4.3 数据报文的流向

源IP和目标IP由流向决定;

 

三、规则语法

写规则:先确定功能(表),确定报文流向,确定要实现的目标,确定匹配条件

Iptables --> 语法检查 --> netfilter   

注意:规则会立即生效,远程配置时,首先需要添加放行ssh的规则

 

格式:iptables [-t table] COMMAND chain CRETIRIA -j Target

-t table: raw,mangle,nat,filter

COMMAND:定义如何对规则进行管理

chain:定义在哪个链上生效规则,当定义策略时可以省略

CRETIRIA:指定匹配标准

-j Target:如何进行处理

 

例如:允许192.168.56.0/24段的主机访问本机的22端口

# iptables -A INPUT -s 192.168.56.0/24 -p tcp --dport 22 -j ACCEPT

# iptables -L -n -v --line-numbers   # 查看定义的规则详情并显示行号

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)

num   pkts bytes target     prot opt          in     out     source               destination    

行号   包数  字计数  目标     协议  选项 流入接口  流出接口  源地址      目的地址

1       36  2620 ACCEPT     tcp  --  *      *       192.168.56.0/24      0.0.0.0/0           tcp dpt:22

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)

num   pkts bytes target     prot opt in     out     source               destination        

Chain OUTPUT (policy ACCEPT 26 packets, 3104 bytes)

num   pkts bytes target     prot opt in     out     source               destination

 

 

四:COMMAND详解

1、链管理命令:

-P:设置默认策略

规则:iptables [-t table] -P chain target

eg:# iptables -t filter -P FORWARD DROP  //设置filter的FORWARD链默认为DROP

 

-N:   新建一个链

规则:iptables [-t table] -N chain

eg:# iptables -t filter -N http_in   // 在filter表新建一个http_in的链

 

-X: 删除用户自定义链

规则: iptables [-t table] -X [chain]

eg:# iptables -t filter -X http_in  //删除用户自定义链http_in ( 删除前此引用数 references 需要为0 )

 

-E: 重命名用户自定义链

规则: iptables [-t table] -E old-chain-name new-chain-name

eg:# iptables -t filter -E http_in httpd_in   //修改自定义链http_in 为httpd_in

 

-F: 清空规则

规则:iptables [-t table] -F [chain [rulenum]] [options...]

eg:# iptables -t filter -F  //清空filter表,链和规则可以省略,如果不写则为清空所有

 

-Z:    计数器清零

规则:iptables [-t table] -Z [chain [rulenum]] [options...]

eg: # iptables -t filter -Z OUTPUT  //将filter表的OUTPUT链计数器清空,如果不写,则为所有计数器清空

 

2、规则管理命令

-A:追加,在当前链最后添加一条规则

规则: iptables [-t table] {-A|-D} chain rule-specification

eg:# iptables -t filter -A INPUT -s 192.168.56.0/24 -p tcp --dport 80 -j ACCEPT  //允许192.168.56.0/24网络访问本机80端口

 

-I NUM:     插入一条规则

规则: iptables [-t table] -I chain [rulenum] rule-specification

eg:# iptables -t filter -I INPUT 2 -s 192.168.56.0/24 -p tcp --dport 80 -j DROP  //第二条插入一条规则,拒绝192.168.56.0/24网络访问本机80端口(不写第几行默认为第一行)

 

-D NUM: 删除一条规则

规则:iptables [-t table] -D chain rulenum

eg:# iptables -t filter -D INPUT 2   //删除filter表INPUT链的第二条规则

 

-R NUM:修改一条规则

规则:iptables [-t table] -R chain rulenum rule-specification

eg:# iptables -t filter -R INPUT 1 -s 192.168.56.0/24 -p tcp --dport 80 -j ACCEPT  //修改filter表INPUT链的第一条规则

 

3、查看管理命令

-L: 查看规则

子命令:

-n:不反解析主机名,直接以数组的方式显示ip

-v:显示详细信息  -vv   -vvv

-x:在计数器上显示精确值,不做单位换算

--line-numbers:显示规则的行号

-t 表名: 显示指定表的信息

eg:# iptables -t filter -L -n -v --line-numbers

Chain INPUT (policy ACCEPT 216 packets, 15244 bytes)

num   pkts bytes target     prot opt in     out     source               destination        

1        0     0 ACCEPT     tcp  --  *      *       192.168.56.0/24      0.0.0.0/0           tcp dpt:80

 

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)

num   pkts bytes target     prot opt in     out     source               destination        

 

Chain OUTPUT (policy ACCEPT 196 packets, 22160 bytes)

num   pkts bytes target     prot opt in     out     source               destination        

1        0     0 ACCEPT     tcp  --  *      *       192.168.56.202       0.0.0.0/0           tcp spt:80

 

 

五、CRETIRIA匹配条件

1、通用匹配: 源地址、目标地址的匹配

-s IP: 指定作为源地址匹配,这里不能为主机名,必须是IP地址或网络地址

IP | IP/MASK | 0.0.0.0/0.0.0.0

前面可以加!取反,表示除了哪个IP或网络之外

-d IP: 表示匹配目标地址

-p {tcp|udp|icmp}: 用于匹配协议

-I 网卡名称:从这块网卡流入的数据(流入一般是INPUT和PREROUTING)

 

-o 网卡名称: 从这块网卡流出的数据 (流出一般是OUTPUT和POSTROUTING)

 

2、扩展匹配

扩展匹配:调用netfilter额外模块实现特殊检查机制,(使用到相关功能,要使用iptables命令的-m选项来指定调用哪个模块)

 

2.1 隐式扩展:对协议的扩展

-p tcp [-m tcp]

[!] --sport PORT[-PORT]

[!] --dport PORT[-PORT]

--tcp-flags: TCP的标志位(SYN, ACK, FIN, PSH, RST, URG)all   none

有两个参数

1. 要检查标志位列表(用逗号分隔)

2. 必须为1的标志位列表(逗号分隔)

--tcp-flags syn,ack,fin,rst syn  此参数等于  --syn

表示检查syn,ack,fin,rst 4个位,其中syn必须为1,其他的必须为0。用于检测三次握手的第一次握手。

可简写为--syn

eg:# iptables -A INPUT -p tcp --dport 21 --tcp-flags syn,ack,rst,fin syn  -j ACCEPT  //允许tcp21端口的 syn,ack,rst,fin 其中syn为1 的数据包(即第一次握手)

# iptables -A OUTPUT -p tcp --sport 21 --tcp-flags all syn,ack  -j LOG  //检查tcp21端口的所有数据包,其中syn,ack为1 的记录到日志(即第二次握手)

 

-p udp [-m udp]:  UDP协议的扩展

[!] --dport  port[:port]

[!] --sport  port[:port]

eg:

 

-p icmp [-m icmp]: icmp数据报文的扩展

--icmp-type

0: echo-reply, ping响应

8: echo-request,ping请求

eg:

//响应外部ping本机

# iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT

# iptables -A OUTPUT -p icmp --icmp-type 0 -j ACCEPT 

//允许本机ping外部主机

# iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT

# iptables -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT

 

2.2  显式扩展

-m 扩展模块名称

模块: iptables,netfilter各拥有一部分代码

 

multiport: 多端口匹配

可以用于匹配非连续或连续端口;最多指定15个端口;

选项:

[!]  --source-ports,--sports port[,port|,port:port]...

[!] --destination-ports,--dports port[,port|,port:port]…

[!] --ports port[,port|,port:port]…

eg:

# iptables -I INPUT -d 192.168.56.102 -p tcp -m multiport --dports 22,80 -j ACCEPT  //允许访问本地22,80端口

# iptables -I OUTPUT -s 192.168.56.102 -p tcp -m multiport --sports 22,80 -j ACCEPT   //允许本地22,80 端口响应

 

Iprange: 用于匹配指定范围内的IP地址

匹配一段连续的地址而非整个网络时用

选项:

[!] --src-range from[-to]   匹配源地址

[!] --dst-range from[-to]   匹配目标地址

eg:

# iptables -A INPUT -d 192.168.56.102 -p tcp --dport 22-m iprange --src-range 192.168.56.1-192.168.56.100 -j ACCEPT  //允许 192.168.56.1-192.168.56.100 ip段访问本机22端口数据包

# iptables -A OUTPUT -s 192.168.56.102 -p tcp --sport 22 -m iprange --dst-range 192.168.56.1-192.168.56.100 -j ACCEPT  //允许响应 192.168.56.1-192.168.56.100 ip段22端口数据包

 

string: 字符串匹配,能够检测报文应用层中的字符串(linux  kernel >= 2.6.14)

字符匹配检查高效算法

bm,kmp

选项:

--algo {bm|kmp}    指定算法

[!] --string "STRING"    匹配指定的字串

[!] --hex-string"HEX_STRING":  HEX_STRING为编码成16进制的字串;

eg:iptables -A INPUT -m string --algo kmp --string "sex" -j DROP  //使用kmp 算法拒绝字符串有sex的包访问

 

time: 基于时间做访问控制

选项:

--datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]

--datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]

--timestart hh:mm[:ss]

--timestop hh:mm[:ss]

[!] --monthdays day[,day...]   Possible values are 1 to 31

[!] --weekdays day[,day...]   Possible values are Mon, Tue, Wed, Thu, Fri, Sat, Sun, or values  from 1 to 7, respectively.

eg:

# iptables -A FORWARD -p tcp --dport 80 -m time --timestart 9:00 --timestop 18:00 --weekday Mon,Tue,Wed,Thu,Fri -j DROP    //周一至周五每天8:00到18:00 禁止通过本机上网

 

connlimit: 连接数限制,对每个IP所能够发起并发数做限制;

选项:

[!] --connlimit-above N: 匹配大于N个限制

eg: //允许22最大连接数为2个,超过会被丢弃

# iptables -A INPUT -d 192.168.56.102 -p tcp --dport 22 -m connlimit --connlimit-above 2 -j DROP

 

limit: 速率限制

选项:

--limit rate[/second|/minute|/hour|/day]   限制包的速率

--limit-burst NUMBER: 最大通过包数,默认为5

eg://限制ping往本地的请求包数量为每分钟20个,最大通过包数为5个

# iptables -A INPUT -d 192.168.56.202 -p icmp --icmp-type 8 -m limit --limit 20/minute --limit-burst 5 -j ACCEPT

 

state:状态检查

选项:

[!] --state STATE

连接追踪中的状态有:

NEW:新建一个会话

ESTABLISHED:已建立的连接

RELATED:有关联的连接

INVALID:无法识别的连接

 

注意:

1、调整连接追踪功能所能容纳的连接的最大数目:

/proc/sys/net/nf_conntrack_max

2、当前追踪的所有连接

/proc/net/nf_conntrack

3、不同协议或连接类型追踪时的属性:

/proc/sys/net/netfilter目录:

 

例子:放行被动模式下FTP的服务

1、装载模块/lib/modules/KERNEL_VERSION/kernel/net/netfilter/

eg:

# modprobe nf_conntrack_ftp

# modprobe nf_nat_ftp

# modprobe nf_conntrack

2、放行请求报文

(1)放行NEW状态对21端口请求的报文;

eg:# iptables -A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT

(2)放行ESTABLISHED以及RELATED状态的报文

eg:# iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

 

3、放行响应报文

放行ESTABLISHED以及RELATED状态的报文

eg:# iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

 

六、target 详解

 

ACCEPT:     接受

DROP:         悄悄丢弃

REJECT:       明确拒绝并返回错误

SNAT:           源地址转换

DNAT:          目的地址转换

MASQUERADE: 源地址伪装

REDIRECT:             重定向;主要用于实现端口重定向

MARK:                    打标记

RETURN:                 返回,在自定义链执行完毕后使用RETURN来返回原规则链。

 

七、SNAT和DNAT的实现

1、SNAT基于源地址的转换

源地址转换就是在进行包的转发时修改数据包的源地址,此方法可以实现多个内网用户通过外网地址访问外网IP的功能呢个。

选项:

--to-source ipaddr[-ipaddr][:port[-port]]

 

例如:

# iptables -t nat -A POSTROUTING -s 192.168.56.0/24 -j SNAT --to-source 192.168.100.2

 

2、MASQUERADE

然而当外网IP为ADSL拨号自动获取的IP时,外网IP不固定,是动态的分配的。此时可以使用MASQUERADE来实现动态获取外网地址

 

例如:

# iptables -t nat -A POSTROUTING -s 192.168.56.0/24 -j MASQUERADE

 

3、DNAT基于目的地址的转换

对于目标地址转换,数据流向是从外到内,通过对服务器的目标地址转换,可以让客户端通过外网IP来访问响应服务,而真正的服务却在内网的服务器上,增加了安全性。

 

选项:

--to-destination [ipaddr][-ipaddr][:port[-port]]

 

例如:

# iptables -t nat -A PREROUTING -d 192.168.100.2 -p tcp --dport 80 -j DNAT --to-destination 192.168.56.102

 

 

 

八、iptables的规则保存与恢复

因为定义的规则当你重启的时候会失效,所以我们要想永久生效就要保存起来

1、 service iptables save 命令

此命令会保存到默认配置文件,开机自动加载 。 /etc/sysconfig/iptables

 

2、使用 iptables-save命令

# iptables-save > /tmp/iptables   # 手动保存配置到自定义目录

 

3、使用iptables-restore命令

# iptables-restore < /tmp/iptables   手动加载配置

 

注:

iptables的链接跟踪表最大容量为/proc/sys/net/ipv4/if_conntrack_max,链接碰到各种状态的超时后就会从表中删除。

所以解決方法一般有两个:

(1) 加大nf_conntrack_max 值

vi /etc/sysctl.conf

net.ipv4.nf_conntrack_max = 393216

net.ipv4.netfilter.nf_conntrack_max = 393216

 

(2): 降低 nf_conntrack timeout时间

vi /etc/sysctl.conf

net.ipv4.netfilter.nf_conntrack_tcp_timeout_established = 300

net.ipv4.netfilter.nf_conntrack_tcp_timeout_time_wait = 120

net.ipv4.netfilter.nf_conntrack_tcp_timeout_close_wait = 60

net.ipv4.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120