1、防火墙浅解
iptables最大的优点是可以配置有状态的防火墙,带有连接跟踪的防火墙就称为带有状态机制的防火墙,相比非状态防火墙而言更安全,因为可以编写更缜密的安全过滤策略。
有状态的防火墙能够指定并记住为发送或接收信息包所建立的连接状态,防火墙可以从信息包的连接跟踪状态获得该信息。在决定过滤新的信息包时,防火墙所使用的这些状态信息可以增加其效率和速度。有四种有效状态,分别为:ESTABLISHED、INVALID、NEW和RELATED。
ESTABLISHED:指该信息包属于已建立的连接,该连接一直用于发送和接收信息包且完全有效。
INVALID:该信息包与任何已知的流或连接都不关联,可能包含错误的数据或头。
NEW:该信息包已经或即将启动新的连接,或者它与尚未发送和接受信息包的连接相关联。
RELATED:表示该信息包正在启动新的连接,或者它与已建立的连接相关联。

2、防火墙基本语法
对数据报而言,有两种流向:
PREROUTINGFORWARDPOSTROUTING (NAT路由器)
PREROUTINGINPUT本机OUTPUTPOSROUTING (主机防火墙)
Iptables会根据不同的数据包处理功能使用不同的规则表。主要的是以下三个:
Filter表:默认的表,包含真正的防火墙规则。内建规则链有:INPUT、OUTPUT、FORWARD
Nat表:包含源地址、目的地址和端口转换使用的规则。内建规则链有:PREROUTING、OUTPUT、POSTROUTING
Mangle表:包含用于设置特殊的数据包路由标志的规则,这些标志会被filter表中的规则检查。内建规则链有:PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING。
五条规则链:
INPUT链:当一个数据包由内核中的路由计算确定目标是本机系统后,会通过INPUT链的检查
OUTPUT链:保留给系统自身生成的数据包
FORWARD链:经过linux系统路由的数据包
PREROUTING链:用于修改目的地址(DNAT)
POSTROUTING链:用于修改源地址(SNAT)

详细语法如下所示:
iptables [-t 表名] <-A| D | I | R>链名[规则编号] [-i | o 网卡名称] [-p 协议类型] [-s 源地址 | 源子网] [ --sport 源端口号] [ -d 目标ip地址| 目标子网] [ --dport 目标端口号] <-j 动作>

参数说明:
[-t 表名]:定义默认策略将应用于哪个表。没指定默认是filter表
-A:在规则列表中新增一条规则,
-I:插入一条规则,可以指定插入位置,没指定默认在第一条规则前插入
-D:删除规则,可以跟完整的规则描述,也可跟规则编号
-R:替换某条规则,不会改变规则顺序,但必须要指定替换的规则编号
-L:显示防火墙规则,不指定默认查看filter表
-v:显示详细信息
-n:以数字形式显示IP和端口。一般与-v连用
-F:删除指定表中的所有规则
-X:删除自定义空链,如果链里面有规则,则无法删除
-Z:将指定表中的数据包计数器和流量计数器归零
-P:设置默认策略

处理数据包的动作及说明:
ACCEPT:接收数据包
DROP:丢弃数据包
REJECT:拦截该数据包,并发回数据包通知对方
REDIRECT:将数据包重新转向到本机或另一台主机的某个端口
SNAT:改变数据包源地址
DNAT:改变数据包目标地址
MASQUERADE:IP伪装,只能用于ADSL等拨号上网的伪装,如果主机的IP地址是静态固定的,就要使用SNAT
LOG:日志功能,将符合规则的数据包相关信息记录在日志中,以便分析排错

实操练习:
注:在命令行进行增删改查的防火墙规则都会在服务器重启后失效,想永久有效可写入/etc/sysconfig/iptables文件里,然后重启防火墙。命令行里的话,service iptables save
查看:
Linux系统下防火墙学习_第1张图片
默认查看filter表:
Linux系统下防火墙学习_第2张图片
Linux系统下防火墙学习_第3张图片
查看某个表中某条链里面的规则:
Linux系统下防火墙学习_第4张图片
Linux系统下防火墙学习_第5张图片
增删查改:
iptables -A INPUT DROP
将进入你主机的所有数据包全部丢弃
iptables -A INPUT -m state --state NEW -j DROP
将所有进入你主机的状态为NEW 的数据包全部丢弃,不包含ESTABLISHED和RELATED状态的数据包。也就是不再允许其他的机器对你的主机发起连接,但你的主机可以主动连接其他的机器,但也仅限于连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
加上上面这条规则,就允许状态为ESTABLISHED和RELATED的连接产生的数据通过
添加:
Linux系统下防火墙学习_第6张图片
删除:
Linux系统下防火墙学习_第7张图片
插入:
Linux系统下防火墙学习_第8张图片
修改:
Linux系统下防火墙学习_第9张图片
修改后:
Linux系统下防火墙学习_第10张图片

更细致的规则编写
Iptables -A INPUT -s 192.168.12.13 -p tcp -dport 22 -j ACCEPT
表示只允许IP地址为192.168.12.13的机器对本机进行SSH连接
限制一段IP的话可用:192.168.12.0/24,表示,192.168.12.1-255此区间内的IP都被限制能或者不能SSH连接本机

利用这些基础的防火墙知识,写一个iptables脚本,实现别人不能ping通自己,但自己可以ping通别人的功能:
Linux系统下防火墙学习_第11张图片

9-13行:使用modprobe命令在内核加载一些ip,iptables相关模块
15-16行:设置所有规则链的默认策略为DROP
19:设置允许接收本地回环数据
20:设置允许接收状态为ESTABLISHED和RELATED的连接所发往本机的数据
21:设置允许接收来自22、80端口的数据
22:设置允许接收来自ping命令的应答消息。本机要ping别的主机,别的主机会发送确认信息,我们主机要接收并回复才能确认可以ping通
24-27:和19-22意义相同,不过作用目标是OUTPUT链。

icmp协议中,icmp-type为8表示ping request,即ping请求,imcp-type为0表示echo relay,即回显应答,ICMP也是TCP/IP的一种,也需要三次握手,在上面的代码中,本机可以不断发出request请求去ping别人同时接收来自被ping主机的echo relay,即可以ping通,但是在OUTPUT链中没有设置可以发送echo relay,别的主机ping本机时收不到回应,三次握手建立不成功,ping执行失败。
其实,在Linux系统下,禁ping有一个更简单的操作,这里为了用防火墙实现所以有了以上内容:
禁ping操作:
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
sysctl -p
以上两条操作可实现上面代码的相同功能。

规则扩展:
iptables -A INPUT -s 10.0.10.0/24 -d 10.0.10.62 -p tcp -m state --state NEW -m multiport --dport 21,22,80 -j ACCEPT
多端口规则匹配:使用参数 -m multiport 可以指定15个以内的非连续端口
上例中匹配到的端口全部放行
iptables -A INPUT -s -m iprange --src-range 10.0.10.100-10.0.10.200
--dst-range:目标IP段
指定匹配连续的IP段
iptables -A INPUT -s 10.150.133.141 -d 10.18.8.193 -p icmp --icmp-type 8 -m limit --limit 20/min --limit-burst 5 -j ACCEPT
限制icmp一次连接可发的ping包的数量
--limit:限制指定包的传入速度
上面的例子是用来比对:每分钟平均流量是否超过一次20个封包。还有每秒钟/second、每小时/hour、每天/day。
--limit-burst:限制特定包瞬间传入的峰值
上面的例子是用来比对一次同时涌入的封包是否超过5个,超过此上限的封包将被直接丢弃