一、前言
所谓防火墙就是工作在主机或网络边缘,对进出的豹纹根据定义的规则做检查,进而对匹配到的报文作为相应处理的套件;
防火墙有软件防火墙和硬件防火墙;根据位置可分为本机防火墙和网络防火墙;根据种类可分为包过滤、应用代理、状态检测。
・包过滤即检查每一个数据包,查看包中的一些基本信息,如源地址、目的地址、端口号、协议等
・应用代理工作在应用层,检查包的所有数据,相对来说会更加安全,但是效率不高,如果对速度要求高,可能会成为瓶颈
・状态检测是从动态包过滤上演化而来的,不仅有包过滤的功能,而且可以在每个连接建立时,防火墙会为这个连接构造一个会话状态,里面包含了这个连接数据包的所有信息,以后这个连接都会基于这个连接的信息进行。状态检测可以对包的内容进行分析,从而摆脱了,从而摆脱了传统防火墙仅局限于过滤包头信息的弱点,而且这种防火墙可以不必开放过多的端口,从而杜绝了开放过多端口带来的隐患。
二、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 (路由后)
3、表、链、规则、动作
netfilter是表的容器,表是链的容器,链又是规则的容器。
表(Tables)
raw表 用于配置数据包,raw中的数据包不会被系统追踪。
mangle表 该表用于数据包的特殊变更操作,如TOS、TTL、MARK等特性。
nat表 能够修改数据包,并完成网络地址转换。
filter表 用于存放所有防火墙相关的默认表,通常使用该表进行过滤的设置。
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 传递给应用程序处理该数据包
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,链接碰到各种状态的超时后就会从表中删除。
所以解�Q方法一般有两个:
(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