Iptables-概述
iptables
什么是iptables
iptables
其实只是一个简称,其真正代表的是netfilter/iptables
这个IP数据包过滤系统。为了简便,本文也将整套系统用iptables简称。iptables是3.5版本的Linux内核集成的IP数据包过滤系统。当系统接入网络时,该系统有利于在Linux系统上更好地控制IP信息包和防火墙配置。此外,iptables还可以进行NAT规则的管理。 上面有提到netfilter/iptables这个组合,这个组合中:
- netfilter位于内核空间,是内核的一部分,由一些数据包过滤表组成,这些表包含内核用来控制数据包过滤处理的规则集;而netfilter又是由内核中若干hook组成的,程序在执行到内核hook处时便会执行数据包过滤的相关逻辑。
- iptables位于用户空间,是一种工具。该工具可以很便捷地对netfilter所维护的表数据进行修改。从而可以很便捷地控制数据包的过滤规则
执行顺序
什么是包过滤防火墙
包过滤防火墙在网络层截取网络数据包的包头(header),针对数据包的包头,根据事先定义好的防火墙过滤规则进行对比,根据对比结果,再执行不同的动作。 包过滤防火墙一般工作在网络层,所以也称为“网络防火墙”,通过检查数据流中每一个数据包的源ip地址,目标ip地址,源端口,目标端口,协议类型(tcp,udp,icmp等),状态等信息来判断是否符合规则
什么是NAT
NAT(Network Address Translation)网络地址转换,常用于局域网主机想与互联网服务通信时做地址转换,因为公网IP有限,且局域网主机访问公网必须要使用公网IP才可以访问到,因此使用NAT方法对地址做转换是一个很高效的方法。根据NAT使用场景不同可以将NAT分为SNAT(Source Network Address Translation)和DNAT(Destination Network Address Translation)
- SNAT:用于局域网服务访问公网服务的场景。即将局域网发出的请求的原地址转换成NAT主机所拥有的公网IP地址,从而与公网服务进行通信
- DNAT:用于公网请求访问局域网服务的场景。即将从公网接收到的请求的目的地址通过NAT规则所配置的局域网网段进行目标服务器局域网地址的转换,从而与局域网内服务通信
Netfilter Hooks
etfilter其实是内核中若干个Hook点组成的。数据包经过内核协议栈处理程序时,处理程序会触发内核模块注册在相关Hook点上的数据包处理函数
。至于处理程序会触发哪个Hook函数,取决于当前数据包的方向(ingress/egress)
、数据包的目的地址
、数据包在上一个Hook点的状态
等等。 内核中有关数据过滤的Hook点有如下几个:
NF_IP_PRE_ROUTING
:接收到的数据包进行协议栈后立即触发此Hook,在进行任何路由判断之前;NF_IP_LOCAL_IN
:接收到的数据包经过了路由判断,如果目的地址是本机,将触发此Hook;NF_IP_FORWARD
:接收到的数据包经过了路由判断,如果目的地址是其他机器,将触发此Hook;NF_IP_LOCAL_OUT
:本机产生的准备发送的数据包,在进入协议栈之前立即执行该Hook;NF_IP_POST_ROUTING
:本机产生的准备发送的或者转发的数据包,在经过路由判断之后,将执行该Hook
注册处理函数时必须提供优先级,以便 hook 触发时能按照 优先级高低调用处理函数。这使得多个模块(或者同一内核模块的多个实例)可以在同一 hook 点注册,并且有确定的处理顺序。内核模块会依次被调用,每次返回一个结果给 netfilter 框架,提示该对这个包做什么操作
iptables 表和链(Tables and Chains)
iptables 使用 table 来组织规则,根据用来做什么类型的判断(the type of decisions they are used to make)标准,将规则分为不同 table。
在每个 table 内部,规则被进一步组织成 chain,内置的 chain 是由内置的 hook 触发 的。chain 基本上能决定(basically determin)规则何时被匹配。
下面可以看出,内置的 chain 名字和 netfilter hook 名字是一一对应的:
PREROUTING
: 由NF_IP_PRE_ROUTING
hook 触发INPUT
: 由NF_IP_LOCAL_IN
hook 触发FORWARD
: 由NF_IP_FORWARD
hook 触发OUTPUT
: 由NF_IP_LOCAL_OUT
hook 触发POSTROUTING
: 由NF_IP_POST_ROUTING
hook 触发
Table
一共有五种table类型:
filter table
: 过滤(放行/拒绝)nat table
:实现网络地址转换规则manle table
:修改IP头raw table
:conntrack 相关security table
:打SELinux标记
filter table
filter
table 是最常用的 table 之一,用于判断是否允许一个包通过。
在防火墙领域,这通常称作“过滤”包(”filtering” packets)。这个 table 提供了防火墙 的一些常见功能
filter表中有三条链:input、forward和output。
input:用来过滤进入主机的数据包;
forward:负责转发流经主机的数据包,起到转发的作用,和NAT关系很大。想要主机支持转发需要设置相关内核参数 / 将数据转发到本机的其他网卡设备上
net.ipv4.ip_forward=1
- output:用来处理从主机发出去的数据包。
### nat table
`nat` table 用于实现网络地址转换规则。
当包进入协议栈的时候,这些规则决定是否以及如何修改包的源/目的地址,以改变包被 路由时的行为。`nat` table 通常用于将包路由到无法直接访问的网络
> nat表中有三条链:prerouting,postrouting和output
- prerouting:在数据包到达netfilter系统时,在进行路由判断之前执行该链上的规则,作用是改变数据包的目的地址、目的端口等,起到DNAT的作用;
- postrouting:数据包发出时,当数据包经过了路由判断后执行该链上的规则,作用是改变数据包的源地址、源端口等,起到SNAT的作用;
- output:用来处理从主机发出去的数据包。
### mangle table
`mangle`(修正)table 用于**修改包的 IP 头**。
例如,可以修改包的 TTL,增加或减少包可以经过的跳数。
这个 table 还可以对包打**只在内核内有效的**“标记”(internal kernel “mark”),后 续的 table 或工具处理的时候可以用到这些标记。标记不会修改包本身,只是在包的内核 表示上做标记。
### raw table
**iptables 防火墙是有状态的**:对每个包进行判断的时候是**依赖已经判断过的包**。
建立在 netfilter 之上的连接跟踪(connection tracking)特性**使得 iptables 将包 看作已有的连接或会话的一部分**,而不是一个由独立、不相关的包组成的流。 数据包到达网络接口之后很快就会有连接跟踪逻辑判断。
### 链(chain)
filter表中有三条链:input、forward和output。
- input:用来过滤进入主机的数据包
- forward:负责转发流经主机的数据包,起到转发的作用,和NAT关系很大。想要主机支持转发需要设置相关内核参数
- output:用来处理从主机发出去的数据包
`raw` table 定义的功能非常有限,其**唯一目的就是提供一个让包绕过连接跟踪的框架**
### security table
`security` table 的作用是给包打上 SELinux 标记,以此影响 SELinux 或其他可以解读 SELinux 安全上下文的系统处理包的行为。这些标记可以基于单个包,也可以基于连接
## 每种 table 实现的 chain(链)
| Tables/Chains | PREROUTING | INPUT | FORWARD | OUTPUT | POSTROUTING |
| :------------- | :--------- | :---- | :------ | :----- | :---------- |
| (路由判断) | | | | Y | |
| **raw** | Y | | | Y | |
| (连接跟踪) | Y | | | Y | |
| **mangle** | Y | Y | Y | Y | Y |
| **nat (DNAT)** | Y | | | Y | |
| (路由判断) | Y | | | Y | |
| **filter** | | Y | Y | Y | |
| **security** | | Y | Y | Y | |
| **nat (SNAT)** | | Y | | Y | Y |
**当一个包触发 netfilter hook 时,处理过程将沿着列从上向下执行**。触发哪个 hook(列)和包的方向(ingress/egress)、路由判断、过滤条件等相关
## Chain 遍历优先级
假设服务器知道如何路由数据包,而且防火墙允许数据包传输,下面就是不同场景下包的游 走流程:
- 收到的、目的是本机的包:`PRETOUTING` -> `INPUT`
- 收到的、目的是其他主机的包:`PRETOUTING` -> `FORWARD` -> `POSTROUTING`
- 本地产生的包:`OUTPUT` -> `POSTROUTING`
## 规则
规则是最终影响数据包的地方,一条有效的规则必须由`匹配规则+动作目标`组成:
- 匹配规则:提供了需要执行对应动作的目标匹配机制。通常可以匹配协议类型、目的地址、源地址、目的端口、源端口、目的网段、源网段、接收数据包的网卡、发送数据包的网卡、协议头、连接状态等。
- 动作目标:又称为Target。是数据包满足匹配规则时触发的相应的动作。Target分为两种类型:终止目标和非终止目标
### 终止目标
Linux内核提供如下的终止目标动作:
| 动作 | 含义 |
| ---------- | ------------------------------------------------------------ |
| ACCEPT | 允许数据包通过 |
| DROP | 直接丢弃数据包,不给任何回应信息,这时候[客户端](https://zhida.zhihu.com/search?q=客户端&zhida_source=entity&is_preview=1)会感觉自己的请求没有响应,过了超时时间才会有反应。 |
| REJECT | 拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息 |
| SNAT | 源地址转换,解决内网用户用同一个公网地址上网的问题 |
| MASQUERADE | 是SNAT的一种特殊形式,适用于动态的、临时会变的ip上 |
| DNAT | 目标地址转换 |
| REDIRECT | 在本机做端口映射 |
| LOG | 在/var/log/messages文件中记录日志信息(其实就是写入系统日志,通过dmesg也可以看到),然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配 |
### 特殊的非终止目标 —— Jumping Target
那如果我想在不影响其他链的情况下使用自己定义的链,该如何操作呢?这时就可以在内置链上配置一个Jumping Target。实际上这里指定的就是我自定义的链的名字。例如下面的配置:
```text
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
KUBE-FIREWALL all -- anywhere anywhere
Chain KUBE-FIREWALL (2 references)
target prot opt source destination
DROP all -- anywhere anywhere /* kubernetes firewall for dropping marked packets */ mark match 0x8000/0x8000
上面的配置中,INPUT链的target为一条自定义的名为KUBE-FIREWALL的链,这样,从INPUT入口进入的数据包将会沿着链到达KUBE-FIREWALL链,然后将所有带有0x8000/0x8000
标记的包丢弃。
Linux命令操作Iptables
链操作
-N 新建链,自定义一条新的规则链 |
规则管理
-A 追加规则,在已有规则后追加规则 |
基础
查看Filter表中所有链以及规则 |
新增
|
删除
删除filter表的INPUT链中拒绝所有来自192.168.1.1的数据包的规则 |
修改
在filter表的INPUT链上对所有经过路由选择后判定为发给本机的数据包做跳转至KUBE-NODE-PORT链的操作 |
example
实现所有192.168.1.0/24的地址通过123.123.123.123公网地址访问公网 |
扩展模块选项
iptables可以使用带有-m或–match选项的扩展包匹配模块,后跟匹配模块名称;之后,根据特定的模块,可以使用各种额外的命令行选项。您可以在一行中指定多个扩展匹配模块,并且可以在指定模块以接收特定于该模块的帮助后使用-h或–help选项。扩展匹配模块按照规则中指定的顺序进行计算
隐式扩展:在使用-p选项指明了特定的协议时,无需再用-m选项指明扩展模块的扩展机制,不需要手动加载扩展模块,即
有的模块只需要指定协议名称,不需要指定模块名称,这样在定义协议时,间接的使用了模块,如TCP、UDP、icmp协议,因为协议名与模块名同名;显示扩展:必须使用-m选项指明要调用的扩展模块的扩展机制(手动指定引用的模块名称),要手动加载扩展模块
rpm -ql iptables #查看iptables所支持的模块
tcp模块
iptables -A INPUT -s 192.168.39.6 -p tcp --dport 80 -j ACCEPT |
icmp模块
filter表input链添加规则,允许客户端ping的响应报文;icmp协议中,type为0的表示为响应报文,为8的表示为请求报文;间接引用了icmp模块 |
multiport模块
filter表input链添加规则,允许客户端通过TCP协议访问3306和80端口;multiport模块的作用是指定多个不连续的端口,并且只会生成一条规则,不会生成多余的规则;离散端口最多能指定15个 |
string模块
iptables虽然不是应用层防火墙,但是也可以通过string模块分析数据报文中的特定关键字 |
time模块
通过time模块定义具体时间的访问策略 |
connlimit模块
根据每个客户端IP做并发连接数数量匹配限制,可防止Dos(Denial of Service,拒绝服务)攻击 |
limit模块
limit模块可以限制报文收发速率 |
state模块
通过state状态跟踪模块,判断新旧用户发起的请求,从而进行访问控制; |
state
state模块允许访问此数据包的连接跟踪状态。
- NEW: 新连接请求;
- ESTABLISHED:已建立的连接;
- INVALID:无法识别的连接;
- RELATED:相关联的连接,当前连接是一个新请求,但附属于某个已存在的连接;
- UNTRACKED:未追踪的连接;
state内核模块装载:
nf_conntrack |
手动装载
nf_conntrack_ftp |
追踪到的连接
/proc/net/nf_conntrack |
调整可记录的连接数量最大值
/proc/sys/net/nf_conntrack_max |
超时时长
/proc/sys/net/netfilter/timeout |
保存、重载
保存:iptables-save > /PATH/TO/SOME_RULE_FILE
重载:iptabls-restore < /PATH/FROM/SOME_RULE_FILE
-n, --noflush
:不清除原有规则-t, --test
:仅分析生成规则集,但不提交