iptables 速描

  • iptables 速描,一些长期更新的内容.

  • 资料来源:

    https://www.zsythink.net/

  • 更新

    1
    2
    19.01.08 初始化
    19.01.16 是个大坑😥

导语

  • 投入了不少时间重新啃一遍 iptables ,勉强理解下来了.

  • 这是一篇记录,并非完全的讲解.

  • 内容几乎来自于 朱双印的blog,非常感谢如此深入浅出的讲解.

  • 引用了 朱双印的blog 的图片,需要授权,在blog留言申请,但不知道为什么关闭了评论…😂…

  • 一些关键词翻译参考维基.

综述

  • iptables 其实是一个用户空间控制 linux 内核 netfilter 的接口.其前身是 ipchains (大概),实际上 iptables 也在linux 3.13 以后被 nftables 取代了,现在还在使用的实际上是 nftables 的兼容接口.

  • nftables是取代 {ip,ip6,arp,eb}tables框架.比较好的资料是 Nftables HOWTO 中文翻译 ,有机会再写吧.

  • 凡是关于 iptables 先记住这张图.
    021217_0051_6.png

  • 一切对 iptables 的调整都是根据这张图标明的数据流向进行的.

    • PREROUTING : 路由前链.数据包在处理路由规则前通过此链.通常用于目的地址转换(DNAT)
    • INPUT: 输入链.所有达到本机的数据包都有通过输入链.
    • OUTPUT: 输出链.本机向外的的数据包都经过输出链输出,但是 注意 从本机到本机的数据包不经过输出链,直接回到本机.
    • FORWARD: 转发链.经过路由判断,所有不流向本机的数据包全部经过转化链.默认情况下转发并没有开启.
    • POSTROUTING: 路由后链.所有流出本机的完成路由规则后通过此链,通常用于源地址转换(SNAT).
  • 例子

    • 仅本机,例如打开网页.
      • 首先是查询 DNS 获得网站 ip 地址.
        • 出向: OUTPUT->POSTROUTING
        • 入向: PREROUTING->INPUT.
      • 请求网页与上面相同.
    • 路由器,除了处理本机流量还有转发局域网的其他流量到公网.通常路由器都有两个以上的网卡,一个有局域网地址,一个有公网的地址.这个时候就设计到路由判断了.还是上面的过程,在路由器的处理.
      • 查询 DNS
        • 出向: 本机 OUTPUT->POSTROUTING 到路由器 PREROUTING(DNAT)->路由判断->FORWARD->POSTROUTING(SNAT) 到公网.
        • 入向: 公网 到 路由器 PREROUTING(DNAT)->路由判断->FORWARD->POSTROUTING(SNAT) 到本机 PREROUTING->INPUT.
  • 对应不同链上,都要设置一些规则实现对数据包的过滤转发, iptables 将这些相同功能的规则归到了一起,称为一个表.

    • filter: 通常用于过滤数据包.
    • nat: 用于处理地址转换nat.
    • mangle: 用于处理数据包,例如拆包重装,修改报文的某个标志位什么的.
    • raw: 与连接追踪机制有关,待后续细察.
  • 链上并不是全部的4种规则表都有.具体见那张图.

  • 数据包依次经过不同的链,这样不同的链就有有优先级.相同的链上,数据包按照上图的顺序,依次经过不同的表,这样相同链上不同表的优先级也不同.所以每次调整 iptables 都要依照实际的优先级调整不同的链和表.

  • 在上文描述中,看似是 表寄生在链上.但恰恰相反,在 iptables 的实际使用中,我们直接操作的是表,然后修改表挂着的链上的某个规则.链是寄生在表上.

  • 一个典型的 iptables 命令(具体的命令在下一节).

    1
    2
    # 在            nat表 添加 路由前链     wlan1流出  数据包进行nat  的规则
    sudo iptables -t nat -A POSTROUTING -o wlan1 -j MASQUERADE
  • 我们可以通过 iptables 对任何来源去向的数据包可以做任何事,丢弃,重定向,修改内容等等,这是 iptables 功能强大也是如此复杂的原因.

  • iptables 典型的应用是防火墙(预防ddos也是一种),端口映射,服务器的负载均衡等.

iptables 命令

  • 警告不要轻易在服务器上实验,最好开个虚拟机,一旦远程服务器的 iptables 配置错误,需要进入 vnc 等抢救.不建议新手实验.

  • iptables 命令模式上是非常相似的.

    • -t 指定对那个表操作,没有-t默认是 filter 表.
    • 具体的动作 A/I/D/F/R/L 头部添加/尾部添加/删除/全部删除/修改/查询
    • POSTROUTING 等是指定对那个链操作.
    • 后面是匹配的条件 -o -i 是数据包从那里来,到哪里去,ip地址,网卡都可以作为条件.还可以通过 iptables 的模块实现基于数据包内容的过滤.
    • -j 匹配后的操作,基本的有 ACCEPT /DROP/REJECT /SNAT /MASQUERADEDNAT /REDIRECT 等.具体后面会说.
  • 选定表/链无需多言.当没有指定 -t 时默认为 filter 表.

  • 下面是其他的详述.

规则增删改查

  • -L: 即列出规则,实际上与之配合的还有其他命令.

    • -n: 表示不解析IP地址
    • -v: 显示计数器信息
    • -x: 显示计数器的精确值
    • –line: 这个命令比较特殊,需要跟在 iptables 之后.相似规则的编号,在修改某条规则时有用.
  • 这些命令可以合并为 iptables --line |xxx| -nvxL 查询规则时常用.

    • 查询 nat 表

      1
      iptables --line -t nat -nvxL
  • -A: 在对应链的末尾添加规则

    • 在 nat表 INPUT链 末尾插入一条允许流向 192.168.0.1 的规则

      1
      iptbles -t nat -A INPUT -s 192.168.0.1 -j ACCEPT
  • -I: 在对应链的头部添加规则,还可以通过-I 实现在在某个具体位置插入规则.

    • 在 nat表 INPUT链 头部插入一条允许流向 192.168.0.2 的规则

      1
      iptbles -t nat -I INPUT -s 192.168.0.2 -j ACCEPT
  • -D: 删除规则,可以是按照某条规则的编号,也可以按照规则具体的匹配条件与动作删除.

    • 删除 nat表 INPUT链 的编号为 1 的规则

      1
      iptables -t nat -D INPUT 1
    • 删除 nat表 INPUT链 允许流向 192.168.0.2 的规则

      1
      iptbles -t nat -D INPUT -s 192.168.0.2 -j ACCEPT
  • -F: 清空指定表链的规则,类似rm -rf 需要慎用.没有指定表时,清空 filter 表.当没有指定链时,清空整个表.

  • -R: 更改规则的动作.需要指定对应的表->链->序号和匹配的条件.要更改一个规则另一个更为通用的做法是先删除此规则,再在原位置插入一个新的规则.

    • 把 nat表 INPUT链 允许流向 192.168.0.2 的规则改为丢弃

      1
      iptbles -t nat -R INPUT -s 192.168.0.2 -j DROP
  • -P: 指定链的默认动作.在一个数据包经过对应的链依次匹配,但最后没有任何规则与之匹配时的默认动作.默认情况下都是 ACCEPT 允许通过.不需要 -j

    • 修改 nat表 INPUT链 默认动作为 DROP

      1
      iptbles -t nat -P INPUT DROP

规则的匹配

  • 在进入规则的具体匹配之前,我们先来看看 iptables 的规则可以对数据包进行的基本动作,方便接下来的讲解.

  • ACCEPT: 允许数据包通过.是 iptables -F后的所有表和链的默认动作.

  • DROP: 丢弃数据包,在发送方看来数据包石沉大海,没有任何回应.一个例子是把发向本机的 icmp 直接丢弃.这样从发送 ping 的一方看来是目标主机无回应.!!

  • 回到规则的匹配,规则的匹配有两种,一是最基本的基于地址的基本匹配.另一种是基于模块的匹配,可以提供更加丰富的匹配规则,需要通过 -m 应用具体额模块.

基本匹配条件

  • 基于 ip 地址

    • -s: 数据包的源地址,从 iptables 看来数据包的来源 ip 地址.

    • -d: 数据包的目的地址,从 iptables 看来是数据包的目的地的 ip 地址.

    • 可以匹配多个 ip 地址,在 -s -d 后面以 , 号隔开.

    • 还可以匹配一个 ip 段,例如 -s 192.168.0.0/8.

    • 要注意这两种方式不能混合使用.

    • 还可以进行取反操作,即表示除指定 ip 或 ip 段以外的 ip 地址怎样.可以实现只允许特定 ip 访问.

    • 如果没有指定源地址或者目的地址,即为 0.0.0.0,表示全部 ip .

    • 例:

      1
      2
      3
      4
      5
      6
      7
      8
      #丢弃 192.168.0.1 来的数据包
      iptbles -t nat -A INPUT -s 192.168.0.1 -j DROP
      #丢弃除 192.168.0.1 外其他来源的数据包
      iptbles -t nat -A INPUT ! -s 192.168.0.1 -j DROP
      #丢弃 192.168.0.1 192.168.0.2 来的数据包
      iptbles -t nat -A INPUT -s 192.168.0.1,192.168.0.2 -j DROP
      #丢弃 192.168.0.0/8 段来源的数据包
      iptbles -t nat -A INPUT -s 192.168.0.0/8 -j DROP
  • 基于协议类型

    • 可以通过 -p 选项指定匹配的数据包类型.

    • 包括不限于 tcp,udp,udplite,icmp,esp,ah,sctp等.(当然常用就 tcp,udp,icmp)

    • 可用取反,只允许某种协议通过.

    • 当不指定 -p 时默认等同于 -p all.即所有协议.

    • 例:

      1
      2
      3
      4
      # 接受192.168.0.1 来的 tcp 数据包.
      iptbles -t nat -A INPUT -p tcp -s 192.168.0.1 -j ACCEPT
      # 丢弃192.168.0.1 除 tcp 以外的其他流量
      iptbles -t nat -A INPUT ! -p tcp -s 192.168.0.1 -j DROP
  • 基于网卡

    • -i: 数据包流入的网卡.

    • -o: 数据包流出的网卡.

    • 一个计算机可能有多个网卡,而且结合第一节的图应该会想到一个问题,有的链并不能使用 -i 和 -o.

    • -i : PREROUTING链 INPUT链 FORWARD链

    • -o : FORWARD链 OUTPUT链 POSTROUTING链

    • 可以取反

    • 注意: 本机的数据包并不通过 iptables ,过滤本机数据包无意义.

    • 例:

      1
      2
      3
      4
      5
      6
      # 允许 wlan0 向外 ping(icmp)
      iptbles -t nat -A OUTPUT -p icmp -o wlan0 -j ACCEPT
      # 丢弃流入 eth0 的 icmp
      iptbles -t nat -A INPUT -p icmp -i eth0 -j DROP
      # 只允许 wlan1 响应 ping(丢弃其他流入的icmp数据包)
      iptbles -t nat -A INPUT -p icmp !-i wlan1 -j DROP
  • 特别注意 同一个表上的链的规则之间是逻辑与的关系,符合才处理,不符合进入下一条规则,最后进入默认的动作.

拓展匹配条件

  • 简单的应用,基本匹配条件已足够应付,但是如果有过滤端口,或者基于报文内容的过滤,此时基本的匹配条件就很难满足.需要拓展的匹配条件.

  • 拓展的匹配条件需要安装对应的 iptables 模块,并通过 -m module 引用.

  • 可以与基本匹配条件连用.

  • tcp模块

    • 匹配 tcp 的端口.区分流入,流出.

    • 可以指定具体端口,或者端口范围,但不能同时使用.

    • 可取反

    • –sports: 源端口

    • –dports: 目的地端口

    • –tcp-flags: 与 tcp 的三次握手有关,详情见后.

    • -m tcp-p tcp 并不冲突,不要混淆,仅仅是模块名也是 tcp.当与-p tcp连用时可以省略 -m tcp.

    • 例:

      1
      2
      3
      4
      5
      6
      # 允许连接到 192.168.0.1 的 22端口
      iptbles -t nat -A OUTPUT -d 192.168.0.1 -p tcp -m tcp --sport 22 -j REJECT
      # 允许连接到 192.168.0.1 的 22端口(省略 -m tcp)
      iptbles -t nat -A OUTPUT -d 192.168.0.1 -p tcp --sport 22 -j REJECT
      # 允许连接到 192.168.0.1 的 22到50 端口
      iptbles -t nat -A OUTPUT -d 192.168.0.1 -p tcp -m tcp --sport 22:50 -j REJECT
  • multiport 模块

    • 作用与 tcp 模块相同,但可以指定离散的多个端口,一个端口范围且可以混合使用.中间用 , 隔开.

    • –sports: 源端口

    • –dports: 目的地端口

    • 可取反(觉得都没必要写了,基本都支持取反)

    • 例:

      1
      2
      # 不允许 tcp 连接到 192.168.0.2 的 22 25 80到443端口
      iptables -t nat -I OUTPUT -d 192.168.1.146 -p tcp -m multiport --sports 22,25,80:443 -j DROP
  • iprange

    • 可以指定连续的一段ip地址以 -连接.主要拓展 -s 与 -d.

    • –src-range: 源地址

    • –dst-range: 目标地址

    • 可取反

    • 例:

      1
      2
      # 丢弃192.168.0.1-192.168.0.5的所有入向数据包
      iptables -t nat -I INPUT -m iprange --src-range 192.168.0.1-192.168.0.5 -j DROP
  • string

    • 匹配报文的特定字符串(对https无效?)
    • –algo: 指定匹配的算法有 kmp 与 bm 两种
    • –string:指定需要匹配的字符串
  • time

    • 与时间有关的拓展,一般用于禁止孩子上网?😂?…而且拓展较多..

    • –timestart –timestop: 指定一个时间范围 不可取反

    • –datestart –datestop: 指定一个日期范围 不可取反

    • –weekdays: 指定星期几 可取反

    • –monthdays:指定几号 可取反

    • 可以组合使用,条件是 .

    • 例:

      1
      2
      3
      4
      5
      6
      # 丢弃 21点到23点 的数据包 断网..
      iptables -t nat -I OUTPUT -p tcp -m time --timestart 21:00:00 --timestop 23:00:00 -j DROP
      # 2020链1月1号到31号断网
      iptables -t nat -I OUTPUT -p tcp -m time --datestart 2020-01-01 --datestop 2020-01-31 -j DROP
      # 月末的星期六星期天的21到23点断网
      iptables -t nat -I OUTPUT -p tcp -m time --monthdays 28,29,30,31 --weekdays 6,7 --timestart 21:00:00 --timestop 23:00:00 -j DROP
  • connlimit

    • 限制单个 ip 的连接数量
    • 还没太尝试
  • limit

    • 限制连接的速度
    • 还没太尝试

iptables 模块

tcp
state

规则的动作

  • 待续

自定义链

  • 待续

其他

  • 待续

后记

  • 内容实在是太多了…