云原生容器化-1 Linux虚拟网络介绍2—netfilter/iptables框架

背景:

承接上文云原生容器化-1 Linux虚拟网络介绍,本文以netfilter/iptables框架内容为主题,介绍框架原理和实践操作;由于后续介绍的Docker网络原理不涉及MAC层,因此本文内容聚焦在netfilter/iptables框架的IP层。

1.iptables

iptables/netfilter是Linux的包过滤防火墙,iptables和netfilter是客户端与服务器的关系。netfilter为服务器端,工作在内核态,真正起到防火墙作用,数据包在Linux网络协议栈流动时会经过netfilter的包处理规则处理;iptables是netfilter的客户端,工作在用户态,用户可以通过iptables操作netfilter的包处理规则,且修改实时生效。本质是netfilter框架引入了很多钩子函数,iptables基于此进行个性化定制。

1.1 数据包处理流程图

Netfilter框架关于数据包的流向图如下所示:
云原生容器化-1 Linux虚拟网络介绍2—netfilter/iptables框架_第1张图片可以看到,netfilter框架跨越整个协议栈;红框内是本文关心的部分,可以表述为:
云原生容器化-1 Linux虚拟网络介绍2—netfilter/iptables框架_第2张图片
上图包括3条数据包传输路线,涉及路由和5个独立的数据处理模块(),数据传输路线整体流程可以表述为:

  1. 数据包流入网络协议栈且通过PREROUTING后,会进行路由check进行分流,如果数据包的目标IP是本机IP,通过INPUT向内核上层进行传输,最终到达用户空间;
  2. 路由check后发现目标IP不是本机,经过FORWARD转发流程, 并通过POSTROUTING将数据包发出;
  3. 数据包由内核向外发出时,走OUTPUT流程,并通过POSTROUTING将数据包发出;

当然,数据包经过各链时会进行数据包处理,包括:修改数据包内容、过滤以及修改IP和MAC地址等。另外,转发功能需要forward开启才能生效,开启后的机器相当于一个路由器,具有处理(转发)非本机IP的数据包的能力;否则,会直接丢弃该数据包。

1.2 链、表、规则的概念

至此,netfilter/iptables关于IP层的轮廓通过链概念的引入基本确定了,然后是设计和功能实现部分,这里有值得思考和借鉴的地方:
(1) 引入规则的概念:规则由匹配条件和处理动作两部分组成(匹配后执行),每条可以有多条规则,且规则分组按序排列,数据包经过各链时会按序依次执行;

(2) 引入的概念:将中功能相近的规则收集在一张中。链的数据处理能力因此能够以表为颗粒度进行承载(分组是一种有效的管理方式):
iptables按功能划分为四张表,按优先级顺序展示如下:

  • raw表:可以开启或关闭追踪机制;内核的ip_conntrack模块对数据包关联的连接会进⾏状态标记、跟踪以及保存;
  • mangle表:具备修改报文的能力,可用于给数据包打标记,在其他规则中可以根据标记匹配;
  • nat表:具备NAT功能,源/目标IP或端口的转换等;
  • filter表:具备过滤功能,可以根据IP、端口、网卡等匹配条件以白名单或者黑名单方式接受或过滤数据包;

说明:由于mangle表和raw表在实际工作和后续容器化中几乎用不到,后文直接忽略mangle表和raw表

链与表的承载关系可以表示如下:
云原生容器化-1 Linux虚拟网络介绍2—netfilter/iptables框架_第3张图片
上图可以这么记:(1)仅INPUT-FORWARD-OUTPUT有filter;(2)仅Forward链不存在nat(转发时NAT没啥意义);

说明:上图是Centos7的链表关系,Centos6的INPUT中不存在nat表

1.3 规则的执行逻辑

数据包流入/流出netfilter框架时,会按照确定顺序匹配与执行iptables规则:
(1) 数据包的整体路径按链顺序执行:
流入本机的数据包,按照 PRE-ROUTING -> INPUT的顺序执行;
转发的数据包,按照PRE-ROUTING -> FORWARD -> POST-ROUTING的顺序执行;
本机外发的数据包,按照 INPUT -> POST-ROUTING的顺序执行;
(2) 对于每个链按表的优先级顺序执行:
在同一条链中:按照 raw -> mangle -> nat -> filter的顺序执行;
比如:在执行output链时,先执行output链的nat规则,后执行filter规则;
如果遍历整个表没有匹配到规则,按表的默认规则处理(各表的默认规则可修改);
(3) 对于每个链表确定的规则队列,按顺序从上往下执行;
当确定了链和表后,会得到关联的规则集合,用规则队列表示;如:INPUT的filter表的规则队列,OUTPUT的filter规则队列,OUTPUT的nat规则队列…等;
如下表示INPUT链的filter表的规则队列:
云原生容器化-1 Linux虚拟网络介绍2—netfilter/iptables框架_第4张图片
因此,对于流入的数据包,规则的执行顺序是:
PREROUTING链中的nat规则1 -> PREROUTING的nat规则2 ->PREROUTING中的nat规则n
-> INPUT链的nat规则1 -> INPUT的nat规则2 -> INPUT的nat规则n
-> INPUT链的filter规则1 -> INPUT的filter规则1 -> 流入上层协议栈

另外,进行处理规则时,存在跳过和断开的情况,这与规则处理的具体动作有关,存在以下四种情况:
(1)不间断:继续执行当前规则队列的下一条规则,比如执行filter的LOG后,继续执行filter的下一条规则;
(2)跳过当前规则队列,进入下一条链的第一个规则队列; 如执行filter表面的ACCEPT, nat表的MASQUERADE,SNAT,DNAT等动作;
(3)跳过后续所有链:忽略后续所有链的规则队列,类似于程序中断了, 如filter的REJECT和DROP动作;
(4)返回调用方,类似方法的调用与返回,如RETURN动作,如后续介绍的Docker链;

1.4 常见的动作:

nat表:

redirect:地址重定向
snat:源地址NAT
dnat:目标地址NAT
masquerade:特殊的源地址NAT(针对不确定的公网IP时,snat无能为力),外发数据包时使用;

其中,目标地址的NAT常发生在PREROUTING处,而源地址的NAT在POSTROUTING处。
下图是一条NAT处理规则:对发送给本机8080端口的数据包进行目标地址NAT, 转发给172.17.0.2的80端口;
在这里插入图片描述
filter表

accept:接受数据包;
reject:拒绝数据包,给拒绝响应;
drop:直接丢弃,不响应;

下图表示:该机器拒绝所有来自192.168.28.188的数据包
在这里插入图片描述

2.常用命令

对iptables规则的新增、删除、清空、查询等操作,未通过-t指定表名时,iptables默认使用filter表。

2.1 新增规则 iptables -I/A

iptables -I/A 链名 [-t 表名] 匹配条件 -j 动作

其中:
(1) -I表示插入(队首),-A表示追加(队尾),iptables规则匹配会按照队首至队尾的顺序进行。
(2) -j 后接具体操作,包括DROP,ACCEPT, LOG,NAT以及自定义链等;
(3) 匹配条件可以有多个,以空格分开,表示并且关系;

例如:在filter表-INPUT链中新增以下规则:

iptables -t filter -I INPUT -s 10.10.10.10 -d 10.10.10.20 -j DROP

表示: 丢弃源地址是10.10.10.10 且目的地址是10.10.10.20的数据包。

2.2 删除规则 iptables -D

有两种删除方式:
(1)按照序号删除

#先按照[链]表过滤条件查询出序号
iptables -t filter -vnL INPUT --line
#使用编号删除
iptables -t filter -D INPUT 序号

例如:删除iptables -t filter -I INPUT -s 10.10.10.10 -d 10.10.10.20 -j DROP对应的规则:
云原生容器化-1 Linux虚拟网络介绍2—netfilter/iptables框架_第5张图片
得到规则对应序号为1;
在这里插入图片描述
(2)按照匹配条件删除

#语句类似新增操作,仅将-I或-A改为-D
iptables -t 表名 -D 链 条件 -j 动作

有多条规则时,删除仅能删除第一个匹配项,如下所示:
连续新增3条iptables规则:
云原生容器化-1 Linux虚拟网络介绍2—netfilter/iptables框架_第6张图片
按照规则匹配进行删除时, 发现只有第一条规则被删除了:
在这里插入图片描述

2.3 清空规则 iptables -F

#用于清空所有链的filter表
iptables -F  [链名] [-t 表名]

#(1) 清空INPUT链的filter表
iptables -F INPUT
#(2) 清空INPUT链的nat表
iptables -F INPUT -t nat

例如: 清空nat表中的所有记录:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o60WICgA-1658759088590)(C:\Users\0216001379\AppData\Roaming\Typora\typora-user-images\1658746910472.png)]
再次查询,记录显示为空:
云原生容器化-1 Linux虚拟网络介绍2—netfilter/iptables框架_第7张图片

2.4 查询方式 iptables -L

#用于查询所有链的iptables规则;
iptables -L [链名] [-t 表名]

-L:默认查询所有链,后面可直接加上链名过滤查询范围;
iptables -L INPUT #查询INPUT链的filter表
iptables -L INPUT -t filter #查询INPUT链的filter表
iptables -L INPUT -t nat #查询INPUT链的nat表
-v: 显示详细信息
-n: 不按域名进行翻译,直接显示IP;
–line等价于–line-number,显示行号
在这里插入图片描述
**其中:**在新增、删除时涉及的匹配条件可按照协议、端口、IP和网卡等进行指定:
(1)-s 用于匹配源IP地址(source); -s 10.10.10.10 或者 10.1.1.1,10.2.2.2,10.3,3,3或 -s 10.10.10.0/24
(2)-d 表示目标IP;对-s和-d 而言取反操作与同时指定多个IP的操作不能同时使用。
(3)-p 匹配协议;-p tcp/udp/icmp等
(4)匹配网卡: -i docker0 表示由docker0网卡流入网络协议栈; -o docker0 表示数据包由网络协议栈流入 docker0网卡;
(5)端口匹配: --dport 22 指定目标端口, -dport 22:25 端口号范围;–sport 1000 指定源端,–sport 80: 端口号范围为80~65535
使用dport和sport时,需要同时使用-p指定使用协议;指定不连续端口时,需要使用multiport扩展模块的dports或sports:-m multiport --dports=22,25,28

可通过 “!条件” 对上述的匹配条件取反;另外,可使用扩展模块按消息内容进行过滤、进行时间段、数据包数量限制,以及实现黑白名单机制等;功能较为强大,感兴趣的同学可参考:iptables动作总结之二

3.自定义链

3.1 常见操作

创建自定义链

#示例:在filter表中创建TEST自定义链
iptables -t filter -N TEST

引用自定义链

#示例:在INPUT链中引用刚才创建的自定义链
iptables -t filter -I INPUT -s 10.10.10.10 -j TEST

删除自定义链

#示例:删除引用计数为0并且不包含任何规则的WEB链(规则为空且没有被默认链引用才可删除)
iptables -X TEST

3.2 案例介绍:

case 1: 正常场景

#在filter表中创建TEST链
iptables -t filter -N TEST
#给TEST链添加iptables规则
iptables -t filter -I TEST -s 10.10.10.10 -j DROP
#在INPUT链中引用TEST链
iptables -t filter -I INPUT -d 10.20.20.20 -j TEST 

表示在INPUT执行filter表中规则时,如果满足匹配条件(-d 10.20.20.20), 调用TEST链(类似函数调用);

上述过程等价于:

iptables -t filter -I INPUT -s 10.10.10.10 -d 10.20.20.20 -j DROP

case 2: 异常场景

#在filter表中创建TEST链
iptables -t filter -N TEST

#在INPUT-nat表中引用filter的TEST
iptables -t nat -I INPUT -d 10.20.20.20 -j TEST 

云原生容器化-1 Linux虚拟网络介绍2—netfilter/iptables框架_第8张图片
报错:在nat表中并没有定义TEST链;
注意:
【1】自定义链名在不同表中可重复;
【2】创建自定义链时会指定表名,未指定使用filter表;
【3】默认链引用自定义链时,会指定表名,未指定使用filter表;
【4】自定义链被默认链引用才会生效, 否则等价于定义了函数却没有调用;

4.案例介绍

现有两台处于192.168.28.1/24网段的机器,IP分别为:192.168.28.205 [用seong205表示] 和 192.168.28.188[用seong188表示];
case 1:在seong205主机添加拒绝规则, 拒绝所有来自seong188主机的数据包
[1] 初始状态:通过seong188去ping seong205
云原生容器化-1 Linux虚拟网络介绍2—netfilter/iptables框架_第9张图片
[2] 在seong205上添加拒绝规则
云原生容器化-1 Linux虚拟网络介绍2—netfilter/iptables框架_第10张图片
[3] 再次通过seong188去ping seong205
在这里插入图片描述

case 2:在seong205主机添加拒绝规则, 拒绝所有来自seong188主机且目标端口是8080的数据包
[1] 清除case 1中的DROP规则
在这里插入图片描述
[2] 在seong205机器上启动一个监听端口
在这里插入图片描述
[3] 在seong205和seong188上分别访问seong205的8080端口
在这里插入图片描述
case 3:在seong205主机添加LOG, 记录所有来自seong149主机的ICMP包

#在seong205上执行:
iptables -t filter -I INPUT -p icmp -s 192.168.31.149 -j LOG

#在seong205上查看
tail -f /var/log/messages

#在seong149上向seong205发送ICMP请求
ping 192.168.31.205

结果如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vOS5nngd-1658759088581)(C:\Users\0216001379\AppData\Roaming\Typora\typora-user-images\1658740588483.png)]
总之,netfilter/iptables框架在网络通讯上提供了强大的包处理能力以及扩展能力;后续在云原生容器化-2 Docker网络原理文中会详细介绍iptables在Docker中使用。

你可能感兴趣的:(Linux系列,容器化,linux,网络,云原生)