iptables是内置于多数发行版中的网络防火墙包过滤器。我也不知道该怎么解释,,别看很轻量化,但是功能很强大~
iptables的引入是用来替换掉老的ipchains,ipclains在Linux内核2.2系列中使用,用来作为封包过滤和防火墙的功能。但是ipchains的功能和定制化很局限。在Linux内核2.3系列开始引入了netfilter项目,其中iptables防火墙就是这个项目的一部分,在2.4内核中iptables取代了先前的ipchains作为内置的包过滤器。
对于iptables的历史我没有深究,这篇博客重点在于iptables的用法和规则设定。在网上简单了解一下发现,Linux包过滤功能的历史并不长,本篇参考了以下几个地方的内容:
iptables工作机制
iptables分为五个规则链:
- PREROUTING 数据包进入路由表之前
- INPUT 数据包入口
- FORWARD 转发关卡
- OUTPUT 数据包出口
-
POSTROUTING 数据包离开路由后
这五个规则链是五个钩子函数(hook),只要是经过本机的数据包,一定会经过这五个链中的一个。那么就可以通过配置过滤规则来实现特定的场景。
和四个表:
- filter 一般的过滤功能
- nat 用于nat功能(端口转发、地址映射等)
- mangle 对数据包进行修改(TOS、TTL)
- raw 优先级最高,为了不让iptables做数据包的连接跟踪处理,以提高性能。
其中每个表对应多个链,都有不同,这是每个表的默认规则链:
- filter:INPUT;FORWARD;OUTPUT;
- nat:PREROUTING;POSTROUTING;OUTPUT;
- mangle:PREROUTING;POSTROUTING;INPUT;OUTPUT;FORWARD;
- raw:OUTPUT;PREROUTING;
iptables的策略
规则链确定了作用的位置;而表则划分出了不同的功能。filter表主要是过滤的功能,针对特定的IP、端口、网段进行限制;nat表主要定义地址转换的功能等。
iptables
的策略主要分为两种:“通”策略和“堵”策略:
- 通策略,默认门是关着的,即默认规则为
DROP
,根据需要进行放行。 - 堵策略,默认门是开着的,即默认规则为
ACCEPT
,根据需要拦截数据包。
注意:iptables
的规则是严格按照先后顺序执行的,所以要将比较严格的规则前置,检查规则的时候是由上向下的顺序。
此外,iptables
还支持自定义链,必须跟某种特定的链关联起来,在此先不做讨论。
iptables规则语法
iptables的命令格式:
iptables -t [tables] COMMAND chain rules -j ACTION
- -t tables:四个表,缺省是filter表,可忽略此选项
- COMMAND:命令,定义对规则采取的操作
- chain:指定是在哪一条链上的操作
- rules:指定匹配规则
- -j ACTION:指定做出如何的处理
E.g.
禁止123.123.123.123地址对本机80端口的访问:
iptables -t filter -A INPUT -s 123.123.123.123 -p tcp --dport 80 -j DROP
iptables -t filter -A INPUT -s 123.123.123.123 -p tcp --dport 80 -j REJECT
默认OUTPUT链为“关”:
iptables -P OUTPUT DROP
查看详细规则:
iptables -L -n -v
COMMAND部分详解
链管理命令(立即生效)
-P:设置默认策略:开&&关
iptables -P OUTPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P OUTPUT REJECT
决定OUTPUT链默认接收或丢弃。不同的是REJECT是直接丢弃,而DROP是悄悄丢弃数据包。这在扫描端口的时候会有差别。
-F:清空规则链
iptables -t nat -F
iptables -F INPUT
分别是清空nat表的规则和清空filter表的INPUT链规则。
注意:由于是立即生效的命令,因此在清空filter表时先确定没有默认DROP的链,否则敲完回车后就会将你拒之门外了。有控制台还好,没有的话就麻烦的很了
-N:新建一个自定义链
iptables -N inboard_tcp_web
-X:用于删除用户自定义的空链
删除空链,因此删除之前最好先执行iptables -F
。
-E:用来给自定义链重命名
iptables -E oldname newname
-Z:清空链。清空链以及链默认规则的计数器:1.匹配数据吧个数;2.多少字节。
iptables -Z
规则管理命令
-A:追加规则。当前链的规则后新加一条规则。(iptables执行有前后顺序)
-I [num]:插入规则。插入为第几条规则
iptabels -t filter -I 1 -s 192.168.1.106 -p tcp --dport 80 -j DROP
-R [num]:替换。替换(修改)为第几条规则。相当于bash
中的mv
命令。
-D [num]:删除。删除第几条规则。
查看规则命令
iptables -L
子命令:
- -v/vv/vvv 详细信息
- -x 计数器显示精确值,不做单位换算
- –line-numbers 显示规则行号
- -t nat 显示指定位置的信息
关于规则匹配
地址匹配
- -s:匹配源地址
IP | IP/Mask | 0.0.0.0/0.0.0.0
- 感叹号
!
表示取反 - -d:匹配目的地址
- -p:匹配通信协议(TCP/UDP/ICMP)
- -i eth0:指定数据包流入的网卡
- -o eth1:指定数据包流出的网卡
协议匹配
-p tcp:匹配TCP通信协议:
-
--dport XX/XX-XX
指定目的端口,只能表示连续端口,不可指定非连续端口号 -
--sport XX/XX-XX
指定源端口,同上
-p tcp --tcp-flags
指定TCP的标志位(SYN,ACK,FIN,PSH,RST,URG)。一般格式如下:
iptables -A INPUT -p tcp --tcpflags syn,ack,fin,rst syn ...
iptables -A INPUT -p tcp --syn ...
一般分为前后两部分:syn,ack,fin,rst
表示受检查的标志位;syn
表示匹配必须为1的标志位,而且其他的必须为零。常用来匹配三次握手的第一个数据包。另一种写法是直接写成--syn
。
-p udp:匹配UDP通信协议(同tcp):
-
--dport XX/XX-XX
指定目的端口,只能表示连续端口,不可指定非连续端口号 -
--sport XX/XX-XX
指定源端口,同上
-p icmp:匹配icmp数据包,通常是ping包:
-
-p icmp --icmp-type 8
回显icmp请求 -
-p icmp --icmp-type 0
回显icmp应答
E.g.
以下操作中INPUT,OUTPUT默认丢弃
开放本机icmp请求权限:
iptables -A OUTPUT -s 192.168.1.100 -p icmp --icmp-type 8 -j ACCEPT
但是此时仍无反应,接下来开放本机的icmp应答权限:
iptables -A INPUT -d 192.168.1.100 -p icmp --icmp-type 0 -j ACCEPT
这时候就会成功ping通外部机器。但是此时外部主机是ping不通本机的,这就需要分别在INPUT和OUTPUT上做相反的规则,在此不做赘述。
-m 启用扩展模块:
-
-m multiport -p tcp --dport 21,22,23,80
启用多端口扩展模块 -
-m state --state NEW,ESTABLISH
增加状态检测模块
ACTION部分
DROP:悄悄丢弃。一般使用DROP,效果与REJECT相同,可以隐藏身份和防火墙结构。
REJECT:明示拒绝,端口扫描显示被拒绝。
ACCEPT:接收数据包。
这三个是常用动作,续更…
状态检测
通常,对于整个TCP协议来讲,是一个保持连接的通信协议。在三次握手四次挥手过程中,第一次握手称之为NEW连接;从第二次握手以后,标志位ack都等于1,称之为已建立的连接:ESTABLISH;类似FTP连接,监听端口独立于数据传输端口而存在,包括20,21两个端口,我们称之为RELATED;对于我们无法识别的状态,称之为INVALID。
- NEW 新建立的连接
- ESTABLISH 已存在的连接
- INVALID 无法识别的连接
- RELATED 有联系的连接(没用过,不深究)
这样做,可以指定源地址可以连接,禁用其他连接:
iptables -A INPUT -s 192.168.1.106/24 -d 192.168.1.100 -p tcp --dport 22 -m state --state NEW,ESTABLISH -j ACCEPT
iptables -A OUTPUT -d 192.168.1.106 -m state --state ESTABLISH -j ACCEPT
iptables -P INPUT DROP
iptables -P OUTPUT DROP
在OUTPUT链仅开放192.168.1.106
的规则太严格了,如果需要其他连接,可以改成这样:
iptables -R OUTPUT 1 -m state --state ESTABLISH -j ACCEPT
网友评论