《Kubernetes网络权威指南》读书笔记 | iptables

Posted COCOgsta

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Kubernetes网络权威指南》读书笔记 | iptables相关的知识,希望对你有一定的参考价值。

书籍来源:《Kubernetes网络权威指南:基础、原理与实践》

一边学习一边整理读书笔记,并与大家分享,侵权即删,谢谢支持!

附上汇总贴:《Kubernetes网络权威指南》读书笔记 | 汇总_COCOgsta的博客-CSDN博客


iptables在Docker和Kubernetes网络中应用甚广。例如,Docker容器和宿主机的端口映射、Kubernetes Service的默认模式、CNI的portmap插件、Kubernetes网络策略等都是通过iptables实现的。

1.5.1 祖师爷netfilter

iptables的底层实现是netfilter。netfilter的架构就是在整个网络流程的若干位置放置一些钩子,并在每个钩子上挂载一些处理函数进行处理。

IP层的5个钩子点的位置,对应iptables就是5条内置链,分别是PREROUTING、POSTROUTING、INPUT、OUTPUT和FORWARD。netfilter原理图如图1-13所示。

图1-13 netfilter原理图

当网卡上收到一个包送达协议栈时,最先经过的钩子是PREROUTING,可在这里对数据包进行目的地址转换(DNAT)。

如果是发送给其他机器,就会经过FORWARD钩子,可设置包过滤钩子函数,例如reject函数。

发到协议栈外的包都会经过POSTROUTING钩子,可在这里进行源地址转换(SNAT)或源地址伪装(Masquerade,简称Masq)。

如果是发给本地进程,就会经过INPUT钩子。

本地进程收到数据包后,回程报文会先经过OUTPUT钩子,然后经过一次路由决策,最后同样会经过POSTROUTING钩子。

netfilter是Linux内核网络模块的一个经典框架,如图1-14所示。

图1-14 netfilter在Linux网络中的地位

Kubernetes网络之间用到的工具就有ebtables、iptables/ip6tables和conntrack,其中iptables是核心。

1.5.2 iptables的三板斧:tablechainrule

iptables是用户空间的一个程序,通过netlink和内核的netfilter框架打交道,负责往钩子上配置回调函数。一般情况下用于构建Linux内核防火墙,特殊情况下也做服务负载均衡。iptables的工作原理如图1-15所示。

图1-15 iptables的工作原理

我们常说的iptables 5X5,即5张表(table)和5条链(chain)。5条链即iptables的5条内置链,对应上文介绍的netfilter的5个钩子。这5条链分别是:

  • INPUT链:处理输入本地进程的数据包;
  • OUTPUT链:处理本地进程的输出数据包;
  • FORWARD链:处理转发到其他机器/network namespace的数据包;
  • PREROUTING链:进行DNAT;
  • POSTROUTING链:进行SNAT。

5张表如下所示。

  • filter表:控制数据包是放行、丢弃(drop)或拒绝(reject);
  • nat表:修改数据包的源和目的地址;
  • mangle表:修改数据包的IP头信息;
  • raw表:iptables对数据包有连接追踪(connection tracking)机制,而raw是用来去除这种追踪机制的;
  • security表:不常用。

这5张表的优先级从高到低是:raw、mangle、nat、filter、security。

如果我们扩充图1-13,给它加上iptables的5张表,那么一个网络包经过iptables的处理路径如图1-16所示。

图1-16 一个网络包经过iptables的处理路径

iptables的规则是用户真正要书写的规则。一般包含两部分信息:匹配条件和动作。匹配条件即匹配数据包的“捕获”条件,例如协议类型、源IP、目的IP、源端口、目的端口、连接状态等。

数据包匹配后常见的动作有下面几个:

  • DROP:直接丢弃。可以用来模拟宕机;
  • REJECT:给客户端返回一个connection refused或destination unreachable报文,这里没有你要的服务内容;
  • QUEUE:将数据包放入用户空间的队列,供用户空间的程序处理;
  • RETURN:跳出当前链,该链里后续的规则不再执行;
  • ACCEPT:同意数据包通过,继续执行后续的规则;
  • JUMP:跳转到其他用户自定义的链继续执行。

1.5.3 iptables的常规武器

接下来以iptables在Kubernetes网络中的使用为背景,简单介绍iptables的常见用法。

  1. 查看所有iptables规则

Kubernetes一个节点上的iptables规则输出如下。

使用iptables命令,默认针对filter表操作。因此,如果想输出nat表的所有iptables规则,可以使用如下命令:

使用-n选项将以数字形式列出信息,即将域名解析成IP地址。想输出更详细的信息,可以使用-v选项。

从上面的输出结果可以看出,filter表上挂了5条链,分别是INPUT、FORWARD和OUTPUT这三条系统内置链,以及KUBE-FIREWALL和KUBE-FORWARD这两条用户自定义链。

iptables的内置链都有默认规则,INPUT、FORWARD和OUTPUT的默认规则是ACCEPT,即全部放行。用户自己定义的链,KUBE-FIREWALL和KUBE-FORWARD,后面都有一个引用计数,它们分别在INPUT和FORWARD中被引用。

iptables的每条链下面的规则处理顺序是从上到下逐条遍历的。如果这条规则的动作是JUMP,则跳到这条链遍历其下的所有规则,然后跳回来遍历原来那条链后面的规则。以上过程如图1-17所示。

图1-17 iptables遍历规则

在我们的例子中,iptables规则的遍历顺序应该是rule 1,1→rule 1,2→rule 2,1→rule 2,2→rule 2,3→rule 1,3。

  1. 配置内置链的默认策略

可以配置内置链的默认策略,决定是放行还是丢弃,如下所示:

  1. 配置防火墙规则策略

防火墙默认策略是“全通”,例如上文的policy ACCEPT,就要定义一些策略来封堵;反之,就要定义一些策略来解封。如果是做访问控制列表(ACL),用解封策略更常用。我们将用几个实际的例子来说明。

1)配置允许SSH连接

这条iptables规则的意思是允许源地址是10.20.30.40/24这个网段的包发到本地TCP 22端口。

2)阻止来自某个IP/网段的所有连接

如果要阻止10.10.10.10上所有的包,则可以使用以下命令:

也可以使用-j REJECT,这样就会发一个连接拒绝的回程报文,客户端收到后立刻结束。

3)封锁端口

要阻止从本地进程对外部1234端口建立连接,可以使用以下命令:

如果要阻止外部连接访问本地1234端口,命令如下:

4)端口转发

以上命令的意思是匹配eth0网卡上接收到的包,发到TCP 80端口的流量转发(REDIRECT)给8080端口。

5)禁用PING

大部分的公有云默认都是屏蔽ICMP的,即禁止ping报文:

6)删除规则

最暴力地清除当前所有的规则命令(请慎用):

要清空特定的表可以使用-t参数进行指定:

删除规则使用iptables的-D参数:

当某条链上的规则被全部清除变成空链后,可以使用-X参数删除(只能删除用户自定义的空链):

7)自定义链

创建自定义链(filter表中创建):

  1. DNAT

DNAT根据指定条件修改数据包的目标IP地址和目标端口:

  1. SNAT/ 网络地址欺骗

SNAT根据指定条件修改数据包的源IP地址:

网络地址伪装是一种特殊的源地址转换,报文从哪个网卡出就用该网卡上的IP地址替换该报文的源地址。下面这条规则的意思是:源地址是10.8.0.0/16的报文都做一次Masq。

  1. 保存与恢复

上述方法对iptables规则做出的改变是临时的,重启机器后就会丢失。如果想永久保存这些更改:

iptables-save在保存系统所有iptables规则的同时,可以将标准输出打印重定向到一个文件:

可以使用iptables-restore命令还原iptables-save命令备份的iptables配置:

以上是关于《Kubernetes网络权威指南》读书笔记 | iptables的主要内容,如果未能解决你的问题,请参考以下文章

《Kubernetes网络权威指南》读书笔记 | iptables

《Kubernetes网络权威指南》读书笔记 | 打通CNI与Kubernetes:Kubernetes网络驱动

《Kubernetes网络权威指南》读书笔记 | Kubernetes网络策略:为你的应用保驾护航

《Kubernetes网络权威指南》读书笔记 | 最常用的Docker网络技巧

《Kubernetes网络权威指南》读书笔记 | Linux隧道网络的代表:VXLAN

《Kubernetes网络权威指南》读书笔记 | 主角登场:Linux容器