iptables 是 Linux 中比较底层的网络服务,它控制了 Linux 系统中的网络操作,在 CentOS 中的 firewalld 和 Ubuntu 中的 ufw 都是在 iptables 之上构建的,只为了简化 iptables 的操作,因此,对于学习了解 iptables 对我们了解 firewalld 和 ufw 的工作机制都是很有益处,当然,这里提一句,firewalld 和 ufw 不仅仅是对 iptables 上层封装那么简单,还有 ipv6 支持等功能。同时,iptables 不仅仅是防火墙这么简单,它基本上能实现你在 linux 上对于网络的所有需求,例如我曾经就使用过 iptables 构建过一个简单的 ap,用到的原理就是 iptables 的转发功能,更多关于 iptables 的功能让我在下面给你介绍。

Iptables 总览

在描述 iptables 的各种功能之前,先看一张 iptables 的网络图:

图 1:Iptables 网络图

可以发现,iptables 在网络流中有四个 table,分别是:natfilterrawmangle
此外,还有五条链,分别是:INPUTOUTPUTFORWARDPREROUTING 以及 POSTROUTING

Iptables 解析

数据流走向

  1. 一个数据包进入网卡时,它首先进入 PREROUTING 链,内核根据数据包目的 IP 判断是否需要转发出去。
  2. 如果数据包就是进入本机的,它就会沿着图向下移动,到达 INPUT 链。数据包到了 INPUT 链后,任何进程都会收到它。本机上运行的程序可以发送数据包,这些数据包会经 过 OUTPUT 链,然后到达 POSTROUTING 链输出。
  3. 如果数据包是要转发出去的,且内核允许转发,数据包就会如图所示向右移动,经过 FORWARD 链,然后到达 POSTROUTING 链输出。

规则、表和链

  1. 规则(rules)

    规则(rules)其实就是网络管理员预定义的条件,规则一般的定义为 “如果数据包头符合这样的条件,就这样处理这个数据包”。规则存储在内核空间的信息包过滤表中,这些规则分别指定了源地址、目的地址、传输协议(如 TCP、UDP、ICMP)和服务类型(如 HTTP、FTP 和 SMTP)等。当数据包与规则匹配时,iptables 就根据规则所定义的方法来处理这些数据包,如放行(accept)、拒绝(reject)和丢弃(drop)等。配置防火墙的主要工作就是添加、修改和删除这些规则。

  2. 链(chains)

    链(chains)是数据包传播的路径,每一条链其实就是众多规则中的一个检查清单,每一条链中可以有一条或数条规则。当一个数据包到达一个链时,iptables 就会从链中第一条规则开始检查,看该数据包是否满足规则所定义的条件。如果满足,系统就会根据该条规则所定义的方法处理该数据包;否则 iptables 将继续检查下一条规则,如果该数据包不符合链中任一条规则,iptables 就会根据该链预先定义的默认策略来处理数据包。

  3. 表(tables)

    表(tables)提供特定的功能,iptables 内置了 4 个表,即 raw 表、filter 表、nat 表和 mangle 表,分别用于实现包过滤,网络地址转换和包重构的功能。

    1. raw 表
      只使用在 PREROUTING 链和 OUTPUT 链上, 因为优先级最高,从而可以对收到的数据包在连接跟踪前进行处理。一但用户使用了 RAW 表, 在 某个链上, RAW 表处理完后, 将跳过 NAT 表和 ip_conntrack 处理, 即不再做地址转换和数据包的链接跟踪处理了.

    2. filter 表
      主要用于过滤数据包,该表根据系统管理员预定义的一组规则过滤符合条件的数据包。对于防火墙而言,主要利用在 filter 表中指定的规则来实现对数据包的过滤。Filter 表是默认的表,如果没有指定哪个表,iptables 就默认使用 filter 表来执行所有命令,filter 表包含了 INPUT 链(处理进入的数据包),RORWARD 链(处理转发的数据包),OUTPUT 链(处理本地生成的数据包)在 filter 表中只能允许对数据包进行接受,丢弃的操作,而无法对数据包进行更改

    3. nat 表
      主要用于网络地址转换 NAT,该表可以实现一对一,一对多,多对多等 NAT 工作,iptables 就是使用该表实现共享上网的,NAT 表包含了 PREROUTING 链(修改即将到来的数据包),POSTROUTING 链(修改即将出去的数据包),OUTPUT 链(修改路由之前本地生成的数据包)

    4. mangle 表
      主要用于对指定数据包进行更改,在内核版本 2.4.18 后的 linux 版本中该表包含的链为:INPUT 链(处理进入的数据包),FORWARD 链(处理转发的数据包),OUTPUT 链(处理本地生成的数据包)POSTROUTING 链(修改即将出去的数据包),PREROUTING 链(修改即将到来的数据包)

规则表之间的优先顺序

raw ——> mangle ——> nat ——> filter

规则链之间的优先顺序

  1. 第一种情况:入站数据流向

    从外界到达防火墙的数据包,先被 PREROUTING 规则链处理(是否修改数据包地址等),之后会进行路由选择(判断该数据包应该发往何处),如果数据包 的目标主机是防火墙本机(比如说 Internet 用户访问防火墙主机中的 web 服务器的数据包),那么内核将其传给 INPUT 链进行处理(决定是否允许通 过等),通过以后再交给系统上层的应用程序(比如 Apache 服务器)进行响应。

  2. 第二冲情况:转发数据流向

    来自外界的数据包到达防火墙后,首先被 PREROUTING 规则链处理,之后会进行路由选择,如果数据包的目标地址是其它外部地址(比如局域网用户通过网 关访问 QQ 站点的数据包),则内核将其传递给 FORWARD 链进行处理(是否转发或拦截),然后再交给 POSTROUTING 规则链(是否修改数据包的地 址等)进行处理。

  3. 第三种情况:出站数据流向

    防火墙本机向外部地址发送的数据包(比如在防火墙主机中测试公网 DNS 服务器时),首先被 OUTPUT 规则链处理,之后进行路由选择,然后传递给 POSTROUTING 规则链(是否修改数据包的地址等)进行处理。

Iptable 命令

iptables 的命令格式较为复杂,一般的格式如下:

  1. iptables [-t 表] - 命令 匹配 操作

说明

  1. -t 表

    表选项用于指定命令应用于哪个 iptables 内置表。

  2. 命令

    命令选项用于指定 iptables 的执行方式,包括插入规则,删除规则和添加规则,如下表所示

    1. -P --policy < 链名 > 定义默认策略
    2. -L --list < 链名 > 查看 iptables 规则列表
    3. -A --append < 链名 > 在规则列表的最后增加 1 条规则
    4. -I --insert < 链名 > 在指定的位置插入 1 条规则
    5. -D --delete < 链名 > 从规则列表中删除 1 条规则
    6. -R --replace < 链名 > 替换规则列表中的某条规则
    7. -F --flush < 链名 > 删除表中所有规则
    8. -Z --zero < 链名 > 将表中数据包计数器和流量计数器归零
    9. -X --delete-chain < 链名 > 删除自定义链
    10. -v --verbose < 链名 > - L 他命令一起使用显示更多更详细的信息
  3. 匹配规则

    匹配选项指定数据包与规则匹配所具有的特征,包括源地址,目的地址,传输协议和端口号,如下表所示

    1. -i --in-interface 网络接口名 > 指定数据包从哪个网络接口进入,
    2. -o --out-interface 网络接口名 > 指定数据包从哪个网络接口输出
    3. -p ---proto 协议类型 指定数据包匹配的协议,如 TCPUDP ICMP
    4. -s --source 源地址或子网 > 指定数据包匹配的源地址
    5. --sport 源端口号 > 指定数据包匹配的源端口号
    6. --dport 目的端口号 > 指定数据包匹配的目的端口号
    7. -m --match 匹配的模块 指定数据包规则所使用的过滤模块
  4. 动作

    前面我们说过 iptables 处理动作除了 ACCEPT、REJECT、DROP、REDIRECT 、MASQUERADE 以外,还多出 LOG、ULOG、DNAT、RETURN、TOS、SNAT、MIRROR、QUEUE、TTL、MARK 等。我们只说明其中最常用的动作:

    • REJECT 拦阻该数据包,并返回数据包通知对方,可以返回的数据包有几个选择:ICMP port-unreachable、ICMP echo-reply 或是 tcp-reset(这个数据包包会要求对方关闭联机),进行完此处理动作后,将不再比对其它规则,直接中断过滤程序。 范例如下:

      1. iptables -A INPUT -p TCP --dport 22 -j REJECT --reject-with ICMP echo-reply
    • DROP 丢弃数据包不予处理,进行完此处理动作后,将不再比对其它规则,直接中断过滤程序。

    • REDIRECT 将封包重新导向到另一个端口(PNAT),进行完此处理动作后,将会继续比对其它规则。这个功能可以用来实作透明代理 或用来保护 web 服务器。例如:

      1. iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT--to-ports 8081
    • MASQUERADE 改写封包来源 IP 为防火墙的 IP,可以指定 port 对应的范围,进行完此处理动作后,直接跳往下一个规则链(mangle:postrouting)。这个功能与 SNAT 略有不同,当进行 IP 伪装时,不需指定要伪装成哪个 IP,IP 会从网卡直接读取,当使用拨接连线时,IP 通常是由 ISP 公司的 DHCP 服务器指派的,这个时候 MASQUERADE 特别有用。范例如下:

      1. iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 21000-31000
    • LOG 将数据包相关信息纪录在 /var/log 中,详细位置请查阅 /etc/syslog.conf 配置文件,进行完此处理动作后,将会继续比对其它规则。例如:

      1. iptables -A INPUT -p tcp -j LOG --log-prefix "input packet"
    • SNAT 改写封包来源 IP 为某特定 IP 或 IP 范围,可以指定 port 对应的范围,进行完此处理动作后,将直接跳往下一个规则链(mangle:postrouting)。范例如下:

      1. iptables -t nat -A POSTROUTING -p tcp-o eth0 -j SNAT --to-source 192.168.10.15-192.168.10.160:2100-3200
    • DNAT 改写数据包包目的地 IP 为某特定 IP 或 IP 范围,可以指定 port 对应的范围,进行完此处理动作后,将会直接跳往下一个规则链(filter:input 或 filter:forward)。范例如下:

      1. iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.10.1-192.168.10.10:80-100
    • MIRROR 镜像数据包,也就是将来源 IP 与目的地 IP 对调后,将数据包返回,进行完此处理动作后,将会中断过滤程序。

    • QUEUE 中断过滤程序,将封包放入队列,交给其它程序处理。透过自行开发的处理程序,可以进行其它应用,例如:计算联机费用……. 等。

    • RETURN 结束在目前规则链中的过滤程序,返回主规则链继续过滤,如果把自订规则炼看成是一个子程序,那么这个动作,就相当于提早结束子程序并返回到主程序中。

    • MARK 将封包标上某个代号,以便提供作为后续过滤的条件判断依据,进行完此处理动作后,将会继续比对其它规则。范例如下:

      1. iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 22

常用的 iptables 命令

  1. 查看防火墙的状态

    1. [root@liqiang.io]# iptables -L -n -v --line-numbers
  2. 启动 / 停止 / 重启防火墙

    1. [root@liqiang.io]# service iptables stop
    2. [root@liqiang.io]# service iptables start
    3. [root@liqiang.io]# service iptables restart
  3. 删除一条规则

    1. [root@liqiang.io]# iptables -L INPUT -n --line-numbers
    2. [root@liqiang.io]# iptables -L OUTPUT -n --line-numbers
    3. [root@liqiang.io]# iptables -L OUTPUT -n --line-numbers | less
    4. [root@liqiang.io]# iptables -L OUTPUT -n --line-numbers | grep 202.54.1.1
  4. 插入一条规则

    1. [root@liqiang.io]# iptables -I INPUT 2 -s 202.54.1.2 -j DROP
  5. 保存防火墙规则

    1. [root@liqiang.io]# service iptables save
  6. 加载防火墙规则

    1. [root@liqiang.io]# iptables-restore < /root/my.active.firewall.rules
  7. 删除公共接口上的私有地址

    1. [root@liqiang.io]# iptables -A INPUT -i eth1 -s 192.168.0.0/24 -j DROP
    2. [root@liqiang.io]# iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
  8. 屏蔽 ip 地址

    1. [root@liqiang.io]# iptables -A INPUT -s 1.2.3.4 -j DROP
    2. [root@liqiang.io]# iptables -A INPUT -s 192.168.0.0/24 -j DROP
  9. 屏蔽入站端口

    1. [root@liqiang.io]# iptables -A INPUT -p tcp -s 1.2.3.4 --dport 80 -j DROP
    2. [root@liqiang.io]# iptables -A INPUT -i eth1 -p tcp -s 192.168.1.0/24 --dport 80 -j DROP
  10. 屏蔽出站 ip

    1. [root@liqiang.io]# iptables -A OUTPUT -d 192.168.1.0/24 -j DROP
    2. [root@liqiang.io]# iptables -A OUTPUT -o eth1 -d 192.168.1.0/24 -j DROP
  11. 记录并删除包

    1. [root@liqiang.io]# iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j LOG --log-prefix "IP_SPOOF A:"
    2. [root@liqiang.io]# iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
  12. 通过 mac 地址过滤数据

    1. [root@liqiang.io]# iptables -A INPUT -m mac --mac-source 00\:0F\:EA\:91\:04\:08 -j DROP
    2. ## *only accept traffic for TCP port # 8080 from mac 00\:0F\:EA\:91\:04\:07 * ##
    3. [root@liqiang.io]# iptables -A INPUT -p tcp --destination-port 22 -m mac --mac-source 00\:0F\:EA\:91\:04\:07 -j ACCEPT
  13. 过滤 ICMP ping 请求

    1. [root@liqiang.io]# iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
    2. [root@liqiang.io]# iptables -A INPUT -i eth1 -p icmp --icmp-type echo-request -j DROP
  14. 开启范围端口

    1. [root@liqiang.io]# iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 7000:7010 -j ACCEPT
  15. 开启范围 ip

    1. [root@liqiang.io]# iptables -A INPUT -p tcp --destination-port 80 -m iprange --src-range 192.168.1.100-192.168.1.200 -j ACCEPT
  16. 删除规则

    如果想要删除一条规则,那么可以直接使用序号,例如 INPUT 的第 4 条可以直接这么删除

    1. [root@liqiang.io]# iptables -D INPUT 4

Reference