1 iptables 的概念

什么是iptables

iptables 是一个配置Linux 内核防火墙的命令行工具,是 netfilter 项目的一部分。netfilter位于内核空间,用于管理网络数据包,具有NAT、数据包修改、数据包过滤,等防火墙功能。


iptables 链

是数据包在主机上的传播途径;链由众多规则组成防火墙根据这些规则判断数据包的流向。数据包在主机上的流向如下图所示:

链的类别

  • PREOUTING:路由前
  • FOWARD:转发
  • POSTROUTING:路由后
  • INPUT:输入链;输入本机的数据包
  • OUTPUT:输出链;由本机输出的数据包

iptables 表

上相同类型的规则的集合,不同的表对应不同的功能。iptables提供了4种表

  • filter:负责过滤功能;内核模块:iptables_filter
  • nat:网络地址转换功能;内核模块:iptable_nat
  • mangle:拆解报文,做出修改,并重新封装 ;内核模块:iptable_mangle
  • raw:关闭nat表上启用的连接追踪机制;内核模块:iptable_raw

表链关系

不同的上依据功能上的不同拥有不同种类的,而且之间具有不同的优先级。

同一条链上表的优先级为:raw > mangle > nat > filter

在不同上的分布如图所示:

不同表所属的链关系如下图:


iptables 规则

规则匹配条件动作构成;防火墙根据匹配条件来匹配数据包,满足条件则执行相应的动作;否则继续匹配下一条规则。

匹配条件

匹配条件分为基本匹配条件和扩展匹配条件;

  • 基本匹配条件:源IP目的IP
  • 扩展匹配条件,扩展匹配条件是netfilter的一部分,以模块的形式存在;要使用这些条件需要依赖于相应的扩展模块;常见扩展条件有:源端口目的端口

动作

动作被称为target(这样说并不准确,我们暂且这样称呼),动作也可以分为基本动作和扩展动作

  • ACCEPT:允许数据包通过。
  • DROP:直接丢弃数据包,不给任何回应信息。
  • REJECT:拒绝数据包通过,必要时会给数据发送端一个响应的信息。
  • REDIRECT:在本机做端口映射。
  • SNAT:源地址转换,解决内网用户用同一个公网地址上网的问题。
  • DNAT:目标地址转换。
  • MASQUERADE:是SNAT的一种特殊形式,适用于动态的、临时会变的ip上。
  • LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则

2 iptables 的增删查改

查看 iptables 的规则

# 查看某一张表
iptables -t 表名 -L

# 查看某一条链
iptables -L 链名

# 查看某张表中一条链
iptables -t 表名 -L 链名

# 参数含义
-n : numeric 数字化显示IP和port
-v : verbose 显示详细信息
-x : expand 显示计数器精确值
--line : 显示规则的序号
-t : table 后跟表名
-L : list 后跟链名

# 常见用法
iptables -t 表名 -nvxL
iptables -nvxL 链名
iptables --line -t 表名 -nvxL 链名

增加 iptables 的规则

添加规则必须同时指定表和链

# 在 指定表 的 指定链 的尾部添加一条规则
iptables -t 表名 -A 链名 匹配条件 -j 动作
# 示例
iptables -t filter -A INPUT -s 192.168.1.146 -j DROP

# 在 指定表 的 指定链 的首部添加一条规则
iptables -t 表名 -I 链名 匹配条件 -j 动作
# 示例
iptables -t filter -I INPUT -s 192.168.1.146 -j ACCEPT

# 在 指定表 的 指定链 的指定位置添加一条规则
iptables -t 表名 -I 链名 规则序号 匹配条件 -j 动作
# 示例
iptables -t filter -I INPUT 5 -s 192.168.1.146 -j REJECT

# 设置 指定表 的 指定链 的默认策略(默认动作)
iptables -t 表名 -P 链名 动作

# 参数含义
-A : append 在链的末尾追加一条规则
-I : insert 在链的头部插入一条规则
-j : targe 指定相应的动作
-P : policy 指定链的默认策略

删除 iptables 的规则

# 删除 指定表 的 指定链 中特定序号的规则
iptables -t 表名 -D 链名 规则序号
# 示例
iptables -t filter -D INPUT 3

# 删除 指定表 的 指定链 的指定规则
iptables -t 表名 -D 链名 匹配条件 -j 动作
# 示例
iptables -t filter -D INPUT -s 192.168.1.146 -j DROP

# 删除 指定表 的 指定链 的所有规则
iptables -t 表名 -F 链名

# 删除 指定表 的所有规则
iptables -t 表名 -F

# 参数含义
-D : delete 删除
-F : flush 清空

修改 iptables 的规则

# 修改指定表中指定链的指定规则
iptables -t 表名 -R 链名 规则序号 规则原本的匹配条件 -j 动作
# 示例
iptables -t filter -R INPUT 3 -s 192.168.1.146 -j ACCEPT

# 修改指定表的指定链的默认策略(默认动作)
iptables -t 表名 -P 链名 动作

# 参数含义
-R : replace 修改规则
-P : policy 默认策略

保存规则

# 保存规则
service iptables save

# 保存规则到文件
iptables-save > file

# 从文件载入规则
iptables-restore < file

3 iptables 的匹配条件

IP 地址

-s : source 源IP地址
-d : destination 目的IP地址

指定单个地址

-s ip

指定多个地址

-s ip1,ip2,ip3    # 逗号两侧不能添加空格

指定网段

-s 网络地址/掩码
# 示例
-s 10.1.2.0/24

取反

! -s ip    # 指定多个ip时不能用取反

协议类型

-p : protocol 协议
-p 协议类型    # tcp udp udplite icmp esp ah stcp ...
-p all    # 匹配所有协议(默认)

网卡接口

-i : in-interface 数据流入的网卡接口
-o : out-interface 数据流出接口
-i 网卡名    # 可通过 ifconfig 或 ip addr 查看

扩展匹配条件

要使用扩展条件则需要需要依赖特定的模块,需要使用 -m 模块名 引入

指定端口

-m : module 指定相应模块, eg. tcp
--sport : 源端口
--dport : 目的端口

指定单个端口

-m tcp --sport 端口号

指定端口范围

# 指定端口1 到 端口2的范围
-m tcp --sport 端口1:端口2

# 指定端口1后所有(到65535)
-m tcp --sport 端口1:

# 指定1到端口2之间所有端口
-m tcp --sport :端口2

指定多个离散端口

# 需要用到扩展模块 multiport
-m multiport --dport port1,port2,port3

# 混合使用,离散端口和范围端口同时使用
-m multiport --dport port1,port2:port3

指定IP范围——iprange模块

# 指定 目的ip 或 源ip
-m iprange --src-range ip1-ip2
-m iprange --dst-range ip1-ip2

# 支持取反符号
-m iprange ! --src-range ip1-ip2

匹配字符串——string模块

# string 支持过滤数据包中的字符串
-m string --algo bm --string "xxxx"

# 参数含义
--algo : algorithm 指定字符串匹配算法,有bm、kmp等

匹配时间——time模块

# 按小时指定
-m time --time-start time1 --time-stop time2
# 时间格式
h:minutes:s    # 指定时分秒

# 按周指定时间
-m time --weekdays 6,7    

 # 按月指定时间
-m time --monthdays 23,24   

# 指定日期范围
-m time --datestarttime date1 --datestop date2
# 日期格式
y-month-d    # 指定年月日

# 取反
# 只有--monthdays 和 --weekdays 可以取反

匹配连接数量——connlimit模块

# 限制每个 ip的连接上限数
-m connlimit --connlimit-above 连接上限数

# 限制某个网段中每个 ip的连接上限数
-m connlimit --connlimit-above 连接上限数 --connlimit-mask 子网掩码

匹配流量速率——limit

# 限制包的数量
-m limit --limit 包数量/时间单位
# 时间单位
/second
/minute
/hour
/day

# 指定桶令牌的容量
-m limit --limit-burst 令牌数

桶令牌算法

​ 我们可以这样想象,有一个木桶,木桶里面放了5块令牌,而且这个木桶最多也只能放下5块令牌,所有报文如果想要出关入关,都必须要持有木桶中的令牌才行,这个木桶有一个神奇的功能,就是每隔6秒钟会生成一块新的令牌,如果此时,木桶中的令牌不足5块,那么新生成的令牌就存放在木桶中,如果木桶中已经存在5块令牌,新生成的令牌就无处安放了,只能溢出木桶(令牌被丢弃),如果此时有5个报文想要入关,那么这5个报文就去木桶里找令牌,正好一人一个,于是他们5个手持令牌,快乐的入关了,此时木桶空了,再有报文想要入关,已经没有对应的令牌可以使用了,但是,过了6秒钟,新的令牌生成了,此刻,正好来了一个报文想要入关,于是,这个报文拿起这个令牌,就入关了,在这个报文之后,如果很长一段时间内没有新的报文想要入关,木桶中的令牌又会慢慢的积攒了起来,直到达到5个令牌,并且一直保持着5个令牌,直到有人需要使用这些令牌,这就是令牌桶算法的大致逻辑。

icmp扩展

# 匹配特定的icmp报文类型
-p icmp --icmp-type 协议类型号

4 iptables 自定义链

为什么需要自定义链

​ 当默认链中的规则非常多时,不方便管理。例如,INPUT链中存放了200条规则,这200条规则有针对httpd服务的,有针对sshd服务的,有针对私网IP的,有针对公网IP的。假如,需要修改针对httpd服务的相关规则,就需要从头看一遍这200条规则,找出针对httpd的规则,不便于管理。

​ 因此,iptables中可以自定义链,通过自定义链即可解决上述问题。例如,自定义一条链,链名叫IN_WEB,我们可以将所有针对80端口的入站规则都写入到这条自定义链中;也可以将针对sshd的出站规则放入到OUT_SSH自定义链中。


创建自定义链

iptables -t 表名 -N 自定义链名

# 参数含义
-N : new 新建自定义链

引用自定义链

iptables -t 表名 -A 链名 匹配条件 -j 自定义链名

# 参数含义
-j : target target除了可以跟动作还可以接自定义链

重命名自定义链

iptables -E 自定义链名 新链名

# 参数含义
-E : rename-chain 重命名自定义链

删除自定义链

删除自定义链要满足两个条件:

  • 自定义链没有被任何默认链引用;需要在默认链中删除对应规则
  • 自定义链中没有任何规则;需要使用 -F 清空自定义链
iptables -X 自定义链

# 参数含义
-X : delete-chain 删除自定义链

5 iptables 的动作

REJECT

REJECT可添加参数 --reject-with

REJECT --reject-with 拒绝参数

# 参数选项
icmp-net-unreachable
icmp-host-unreachable
icmp-port-unreachable
icmp-proto-unreachable
icmp-net-prohibited
icmp-host-pro-hibited
icmp-admin-prohibited

SNAT

# 指定修改后的源地址
SNAT --to-source ip

DNAT

# 指定修改后的目的地址
SNAT --to-destination ip:port

MASQUERADE

​ 当使用动态IP时,SNAT会很麻烦,因为每次IP地址发生变化以后,都要重新配置SNAT规则;可以通过MASQUERADE即可解决这个问题,MASQUERADE会动态的将源地址转换为可用的IP地址

# 自动选择修改后的源地址
-j MASQUERADE

REDIRECT

# 在本机进行端口映射
-j REJECT --to-ports port

6 iptables 指令速查

参考自朱双印的个人日志