netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防火墙
① 当一个数据包进入网卡时,它首先进入PREROUTING链,内核根据数据包目的IP判断是否需要转送出去。
② 如果数据包就是进入本机的,它就会沿着图向下移动,到达INPUT链。数据包到了INPUT链后,任何进程都会收到它。本机上运行的程序可以发送数据包,这些数据包会经过OUTPUT链,然后到达POSTROUTING链输出。
③ 如果数据包是要转发出去的,且内核允许转发,数据包就会如图所示向右移动,经过FORWARD链,然后到达POSTROUTING链输出。

iptables - 图2

iptables的规则表和链:iptables - 图3

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

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

1.INPUT——进来的数据包应用此规则链中的策略
2.OUTPUT——外出的数据包应用此规则链中的策略
3.FORWARD——转发数据包时应用此规则链中的策略
4.PREROUTING——对数据包作路由选择前应用此链中的规则
(记住!所有的数据包进来的时侯都先由这个链处理)
5.POSTROUTING——对数据包作路由选择后应用此链中的规则
(所有的数据包出来的时侯都先由这个链处理)

到本机某进程的报文:PREROUTING —> INPUT
由本机转发的报文:PREROUTING —> FORWARD —> POSTROUTING
由本机的某进程发出报文(通常为响应报文):OUTPUT —> POSTROUTING

命令

iptables [-t 表名] 命令选项 [链名] [条件匹配] [-j 目标动作或跳转]

iptables - 图4
表名、链名用于指定 iptables命令所操作的表和链,

命令选项

用于指定管理iptables规则的方式(比如:插入、增加、删除、查看等;条件匹配用于指定对符合什么样 条件的数据包进行处理
-A 在指定链的末尾添加(append)一条新的规则
-D 删除(delete)指定链中的某一条规则,可以按规则序号和内容删除
-I 在指定链中插入(insert)一条新的规则,默认在第一行添加
-R 修改、替换(replace)指定链中的某一条规则,可以按规则序号和内容替换
-L 列出(list)指定链中所有的规则进行查看
-E 重命名用户定义的链,不改变链本身
-F 清空(flush)
-N 新建(new-chain)一条用户自己定义的规则链
-X 删除指定表中用户自定义的规则链(delete-chain)
-P 设置指定链的默认策略(policy)
-Z 将所有表的所有链的字节和数据包计数器清零
-n 使用数字形式(numeric)显示输出结果
-v 查看规则表详细信息(verbose)的信息
-V 查看版本(version)
-h 获取帮助(help)

条件匹配

-p 可以使用 -p 来指定规则协议,比如 tcp,udp, icmp 等等,使用 all 来指定所有协议。
-s 使用 -s 来指定数据包的源地址,参数可以使用 IP 地址,网络地址,主机名

  • -s 192.168.1.101 指定 IP
  • -s 192.168.1.10/24 网络地址
  • 如果不指定 -s 表示所有地址

-d -d 来指定目的地址,参数和 -s 相同
-i 输入接口 ,-i 指定了要处理来自哪个接口的数据包

  • -i eth0 指定了要处理通过 eth0 进入的数据包,如果不指定 -i 参数那么将处理所有接口的数据包。
  • ! -i eth0 处理所有经由 eth0 以外的接口进入的数据包
  • -i eth+ 将处理所有经由 eth 开头的接口进入的数据包

-o 代表输出接口, -o 制定了数据包由哪个接口输出,与-i类似
-–sport 源端口针对 -p tcp 或者 -p udp 缺省情况下,将匹配所有端口。可以指定端口号或者端口名,比如

  • --sport 22
  • --sport ssh
  • --sport 22:100 # 使用冒号匹配端口范围

—dport 是指定目的端口。

目标动作或跳转

用于指定数据包的处理方式(比如允许通过、拒绝、丢弃、跳转(Jump)给其它链处理。

  • ACCEPT 接收数据包
  • DROP 直接丢弃数据包,不给任何回应信息
  • REJECT 拒绝数据包通过,必要时会给数据发送端一个响应的信息。
  • REDIRECT 将数据包重新转向到本机或另一台主机的某一个端口,通常功能实现透明代理或对外开放内网的某些服务
  • SNAT 源地址转换
  • DNAT 目的地址转换
  • MASQUERADE IP伪装
  • LOG 在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则

保存和恢复配置规则

保存生效的配置,让系统重启的时候自动加载有效配置(iptables 提供了保存当前运行的规则功能)

  1. iptables-save > /etc/iptables.rules

恢复规则可以使用:

iptables-restore < /etc/iptables.rules

但是系统并不会在启动时自动执行该规则,所以需要在 /etc/network/if-pre-up.d/ 目录中添加脚本

#!/bin/bash
iptables-restore < /etc/iptables.rules

让系统在开机时自动加载规则

常用命令

查看规则

iptables -L -n --line-numbers

image.png

  • num 指定链中规则编号
  • target 前文中提及的 target 指定值
  • prot 协议 tcp, udp,icmp 等
  • source 数据包源 IP 地址
  • destination 数据包目标 IP 地址

添加规则

允许本地回环接口(即运行本机访问本机):

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT

允许所有本机向外的访问:

iptables -A OUTPUT -j ACCEPT

允许访问 22 端口,允许某 IP 访问指定端口,以 22 端口为例命令是:

iptables -A INPUT -p tcp --dport 22 -j ACCEPT                         # 允许所有的 IP 访问 22 端口
iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT                        # 允许 22 端口发送数据
iptables -I INPUT -s 123.45.6.7 -p tcp --dport 22 -j ACCEPT           # 允许某个 IP 访问
iptables -I INPUT -s 123.45.6.7 -p tcp --dport 22 -j DROP             # 禁止某个 IP 访问
iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT       # 允许 IP 段访问

允许已建立的或相关连的通行

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

禁止访问

屏蔽单个 IP 的命令是

iptables -I INPUT -s 123.45.6.7 -j DROP

封整个段即从 123.0.0.1 到 123.255.255.254 的命令

iptables -I INPUT -s 123.0.0.0/8 -j DROP

封 IP 段即从 123.45.0.1 到 123.45.255.254 的命令

iptables -I INPUT -s 124.45.0.0/16 -j DROP

封 IP 段即从 123.45.6.1 到 123.45.6.254 的命令是

iptables -I INPUT -s 123.45.6.0/24 -j DROP

屏蔽某 IP 访问指定端口,以 22 端口为例命令是

iptables -I INPUT -s 123.45.6.7 -p tcp --dport 22 -j DROP

删除规则

首先要查看规则 sudo iptables -L -n --line-numbers
比如要删除 INPUT 里序号为 8 的规则,执行:

iptables -D INPUT 8

防止 DDos

iptables -A INPUT -p tcp --dport 80 -m limit --limit 30/minute --limit-burst 100 -j ACCEPT

解释:

  • -limit 30/minute: 最大每个分钟 30 个连接
  • limit-burst 100: 用来表示只有达到这个连接数量之后才会触发 limit/minute 限制

端口转发

下面的例子,将 422 端口的流量转发到 22 端口,意味着 incoming ssh 连接可以从 22 端口或者 422 端口:

iptables -t nat -A PREROUTING -p tcp -d 192.168.2.104 --dport 422 -j DNAT --to 192.168.2.104:22

另外也要显示的让 422 流量通过

iptables -A INPUT -i eth0 -p tcp --dport 422 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 422 -m state --state ESTABLISHED -j ACCEPT