【kubernetes/k8s概念】calico iptables 规则分析

  • Post author:
  • Post category:其他


本文为 calico 3.7 版本

名词解释

endpoint:  接入到calico网络中的网卡称为endpoint

AS:           网络自治系统,通过BGP协议与其它AS网络交换路由信息

ibgp:         AS内部的BGP Speaker,与同一个AS内部的ibgp、ebgp交换路由信息。

ebgp:        AS边界的BGP Speaker,与同一个AS内部的ibgp、其它AS的ebgp交换路由信息。

workloadEndpoint:  虚拟机、容器使用的 endpoint

hostEndpoints:        物理机(node)的地址

引用网上图片

基本步骤如下:

1. 数据包到达网络接口比 eth0

2. 进入 raw 表的 PREROUTING 链,这个链的作用是在连接跟踪之前处理数据包

3. 如果进行了连接跟踪,则进行处理

4. 进入 mangle 表的 PREROUTING 链,可以修改数据包,比如 TOS 等

5. 进入 nat 表的 PREROUTING 链,可以在此做 DNAT

6.


决定路由,看是交给本地主机


还是


转发给其它主机



一种情况就是数据包要

转发给其它主机


  • 进入 mangle 表的 FORWARD 链,这里也比较特殊,这是在第一次路由决定之后,在进行最后的路由决定之前,仍然可以对数据包进行某些修改
  • 进入 filter 表的 FORWARD 链,可以对所有转发的数据包进行过滤。需要注意的是:经过这里的数据包是转发的,方向是双向的。
  • 进入 mangle 表的 POSTROUTING 链,到这里已经做完了所有的路由决定,但数据包仍然在本地主机,还可以进行某些修改。
  • 进入 nat 表的 POSTROUTING 链,在这里一般都

    是用来做 SNAT
  • 进入出去的网络接口。完毕。



另一种情况是,数据包就是

发给本地主机的


  • 7. 进入 mangle 表的 INPUT 链,这里是在路由之后,交由本地主机之前,也可以进行一些相应的修改

  • 8. 进入 filter 表的 INPUT 链,在这里可以对流入的所有数据包进行过滤,无论它来自哪个网络接口

  • 9. 交给本地主机的应用程序进行处理

  • 10. 处理完毕后进行路由决定,看该发往哪里

  • 11. 进入 raw 表的


    OUTPUT 链


    ,这里是在连接跟踪处理本地的数据包之前

  • 12. 连接跟踪对本地的数据包进行处理。

  • 13. 进入 mangle 表的 OUTPUT 链,在这里我们可以修改数据包

  • 14. 进入 nat 表的 OUTPUT 链,可以对防火墙自己发出的数据做 NAT

  • 15. 再次进行路由决定

  • 16. 进入 filter 表的 OUTPUT 链,可以对本地出去的数据包进行过滤

  • 17. 进入 mangle 表的 POSTROUTING 链,同上一种情况的第9步。注意,这里不光对经过防火墙的数据包进行处理,还对防火墙自己产生的数据包进行处理。

  • 18. 进入 nat 表的 POSTROUTING 链

  • 19. 进入出去的网络接口。完毕

node的报文处理过程

报文处理过程中使用的标记位:使用了3个标记位,0xf0000 对应的标记位

  • 0x10000:  报文的处理动作,置1表示放行,默认0表示拒绝
  • 0x20000:  是否已经经过了policy规则检测,置1表示已经过
  • 0x40000:  报文来源,置1,表示来自 host-endpoint

流入的报文在路由决策之前的处理过程相同的,路由决策之后,分别进入


INPUT规则链和FORWARD链

  • raw.PREROUTING -> mangle.PREROUTING -> nat.PREROUTING -> mangle.INPUT -> filter.INPUT
  • raw.PREROUTING -> mangle.PREROUTING -> nat.PREROUTING -> mangle.FORWARD -> filter.FORWARD -> mangle.POSTROUTING -> nat.POSTROUTING

一. 路由决策之前:流入node的报文的处理

1. raw PREROUTING

*raw

:PREROUTING ACCEPT [18225340:4127986808]

:OUTPUT ACCEPT [18262870:4463777302]

:OUTPUT_direct – [0:0]

:PREROUTING_ZONES – [0:0]

:PREROUTING_ZONES_SOURCE – [0:0]

:PREROUTING_direct – [0:0]

:cali-from-host-endpoint – [0:0]

:cali-to-host-endpoint – [0:0]




-A PREROUTING -m comment –comment “cali:6gwbT8clXdHdC1b1” -j cali-PREROUTING


  1. -A cali-PREROUTING -m comment –comment “cali:XFX5xbM8B9qR10JG” -j MARK –set-xmark 0x0/0xf0000
  2. -A cali-PREROUTING -i cali+ -m comment –comment “cali:EWMPb0zVROM-woQp” -j MARK –set-xmark 0x40000/0x40000
  3. -A cali-PREROUTING -m comment –comment “cali:Ek_rsNpunyDlK3sH” -m mark –mark 0x0/0x40000 -j cali-from-host-endpoint
  4. -A cali-PREROUTING -m comment –comment “cali:nM-DzTFPwQbQvtRj” -m mark –mark 0x10000/0x10000 -j ACCEPT

规则1. 清除所有规则

规则2. 从网卡 cali+ 进入的数据包,设置 mark 0x40000/0x40000

规则3. 从非 cali+ 网卡进入的数据包,mark 为 0x0/0x40000 流转至 cali-from-host-endpoint 规则链

规则4. 从非 cali+ 网卡进入的数据包,mark 为 0x10000/0x10000 则允许数据包通过

2. nat PREROUTING

*nat

:PREROUTING ACCEPT [0:0]

:INPUT ACCEPT [0:0]

:OUTPUT ACCEPT [1:60]

:POSTROUTING ACCEPT [1:60]



-A PREROUTING -m comment –comment “cali:6gwbT8clXdHdC1b1” -j cali-PREROUTING

跳转至规则链 cali-PREROUTING

-A cali-POSTROUTING -m comment –comment “cali:Z-c7XtVd2Bq7s_hA” -j cali-fip-snat

-A cali-POSTROUTING -m comment –comment “cali:nYKhEzDlr11Jccal” -j cali-nat-outgoing

-A cali-PREROUTING -m comment –comment “cali:r6XmIziWUJsdOK6Z” -j cali-fip-dnat

-A cali-nat-outgoing -m comment –comment “cali:Dw4T8UWPnCLxRJiI” -m set –match-set cali40masq-ipam-pools src -m set ! –match-set cali40all-ipam-pools dst -j MASQUERADE

经过nat表之后,会进行路由决策:

二. 路由决策之后:发送到本机的 host endpoint 或 workload endpoint

3. INPUT filter

*filter

:INPUT ACCEPT [494:126858]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [493:130161]



-A INPUT -m comment –comment “cali:Cz_u1IQiXIMmKD4c” -j cali-INPUT

filter 表中 INPUT 规则链跳转至规则链 cali-INPUT

  1. -A cali-INPUT -m comment –comment “cali:d4znnv6_6rx6sE6M” -j MARK –set-xmark 0x0/0xfff00000
  2. -A cali-INPUT -m comment –comment “cali:YHXh2XvaasL3jbTp” -j



    cali-forward-check


  3. -A cali-INPUT -m comment –comment “cali:eL3eAQBTXQrID5PB” -m mark ! –mark 0x0/0xfff00000 -j RETURN
  4. -A cali-INPUT -i cali+ -m comment –comment “cali:hwvMPJWpIRFo77b4” -g



    cali-wl-to-host


  5. -A cali-INPUT -m comment –comment “cali:c3dtuPGUL9TVsB6Y” -m mark –mark 0x10000/0x10000 -j ACCEPT
  6. -A cali-INPUT -m comment –comment “cali:czgL26xl8reOnh13” -j MARK –set-xmark 0x0/0xf0000
  7. -A cali-INPUT -m comment –comment “cali:EylNwA1nPRRCgK9T” -j



    cali-from-host-endpoint


  8. -A cali-INPUT -m comment –comment “cali:JEbIi4mUTjL17qKC” -m comment –comment “Host endpoint policy accepted packet.” -m mark –mark 0x10000/0x10000 -j ACCEPT

-A

cali-forward-check

-m comment –comment “cali:Pbldlb4FaULvpdD8” -m conntrack –ctstate RELATED,ESTABLISHED -j RETURN

-A

cali-forward-check

-p tcp -m comment –comment “cali:ZD-6UxuUtGW-xtzg” -m comment –comment “To kubernetes NodePort service”



-m multiport –dports 30000:32767



-m set –match-set cali40this-host dst -g cali-set-endpoint-mark

-A

cali-forward-check

-p udp -m comment –comment “cali:CbPfUajQ2bFVnDq4” -m comment –comment “To kubernetes NodePort service”



-m multiport –dports 30000:32767



-m set –match-set cali40this-host dst -g cali-set-endpoint-mark

-A cali-forward-check -m comment –comment “cali:jmhU0ODogX-Zfe5g” -m comment –comment “To kubernetes service” -m set ! –match-set cali40this-host dst -j cali-set-endpoint-mark

三. 路由决策之后:需要转发的报文



fiter FORWARD

-A FORWARD -m comment –comment “cali:wUHhoiAYhphO9Mso” -j cali-FORWARD



nat POSTROUTING

-A cali-POSTROUTING -m comment –comment “cali:Z-c7XtVd2Bq7s_hA” -j cali-fip-snat

-A cali-POSTROUTING -m comment –comment “cali:nYKhEzDlr11Jccal” -j cali-nat-outgoing

-A cali-nat-outgoing -m comment –comment “cali:Dw4T8UWPnCLxRJiI” -m set –match-set



cali40masq-ipam-pools



src -m set ! –match-set



cali40all-ipam-pools



dst -j MASQUERADE

Name:



cali40masq-ipam-pools




Type: hash:net

Revision: 3

Header: family inet hashsize 1024 maxelem 1048576

Size in memory: 16816

References: 1

Members:

192.170.0.0/16

Name:



cali40all-ipam-pools




Type: hash:net

Revision: 3

Header: family inet hashsize 1024 maxelem 1048576

Size in memory: 16816

References: 1

Members:

192.170.0.0/16

四. node本地发出的报文



nat OUTPUT

-A OUTPUT -m comment –comment “cali:tVnHkvAo15HuiPy0” -j cali-OUTPUT

-A OUTPUT ! -d 127.0.0.0/8 -m addrtype –dst-type LOCAL -j DOCKER

-A cali-OUTPUT -m comment –comment “cali:GBTAv2p5CwevEyJm” -j cali-fip-dnat



filter OUTPUT

-A OUTPUT -m comment –comment “cali:tVnHkvAo15HuiPy0” -j cali-OUTPUT

-A cali-OUTPUT -m comment –comment “cali:Mq1_rAdXXH3YkrzW” -m mark –mark 0x10000/0x10000 -j ACCEPT

-A cali-OUTPUT -m comment –comment “cali:5Z67OUUpTOM7Xa1a” -m mark ! –mark 0x0/0xfff00000 -g cali-forward-endpoint-mark

-A cali-OUTPUT -o cali+ -m comment –comment “cali:M2Wf0OehNdig8MHR” -j RETURN

-A cali-OUTPUT -m comment –comment “cali:qO3aVIhjZ5EawFCC” -j MARK –set-xmark 0x0/0xf0000

-A cali-OUTPUT -m comment –comment “cali:3KrxsMf75t8rkLZn” -j cali-to-host-endpoint

-A cali-OUTPUT -m comment –comment “cali:fc01z4huRzkD5TWj” -m comment –comment “Host endpoint policy accepted packet.” -m mark –mark 0x10000/0x10000 -j ACCEPT



nat POSTROUTING

-A POSTROUTING -m comment –comment “cali:O3lYWMrLQYEMJtB5” -j cali-POSTROUTING

-A POSTROUTING -s 192.170.80.0/24 ! -o docker0 -j MASQUERADE

-A cali-POSTROUTING -m comment –comment “cali:Z-c7XtVd2Bq7s_hA” -j cali-fip-snat

-A cali-POSTROUTING -m comment –comment “cali:nYKhEzDlr11Jccal” -j cali-nat-outgoing

-A cali-nat-outgoing -m comment –comment “cali:Dw4T8UWPnCLxRJiI” -m set –match-set cali40masq-ipam-pools src -m set ! –match-set cali40all-ipam-pools dst -j MASQUERADE

iptables 规则

格式:iptables [-t table] COMMAND chain CRETIRIA -j ACTION

  • COMMAND:定义如何对规则进行管理
  • chain:指定你接下来的规则到底是在哪个链上操作的,当定义策略的时候,是可以省略的
  • CRETIRIA:指定匹配标准
  • -j ACTION :指定如何进行处理

通用匹配:源地址目标地址的匹配

-s:指定作为源地址匹配,这里不能指定主机名称,必须是IP

-d:表示匹配目标地址

-p:用于匹配协议的(这里的协议通常有3种,TCP/UDP/ICMP)

-i eth0:从这块网卡流入的数据

-m multiport:表示启用多端口扩展

状态检测

TCP协议是一个有连接的协议,三次握手中,第一次握手,我们就叫



NEW



连接,第二次握手以后的,ack 都为1,这是正常的数据传输,和 tcp 的第二次第三次握手,叫做已建立的连接(



ESTABLISHED



),还有一种状态,比较诡异的,比如:SYN=1 ACK=1 RST=1,对于这种无法识别的,为



INVALID



无法识别的。还有第四种,FTP这种古老的拥有的特征,每个端口都是独立的,21号和20号端口都是一去一回,他们之间是有关系的,这种关系我们称之为



RELATED


  • NEW:主机连接目标主机,在目标主机上看到的第一个想要连接的包
  • ESTABLISHED: 主机已与目标主机进行通信,判断标准只要目标主机回应了第一个包,就进入该状态。
  • RELATED: 主机已与目标主机进行通信,目标主机发起新的链接方式,例如ftp
  • INVALID: 无效的封包,例如数据破损的封包状态

-m 模块

常用规则匹配器 说明
-p tcp/udp/icmp/all 匹配协议,all会匹配所有协议
-s addr[/mask] 匹配源地址
-d addr[/mask] 匹配目标地址
–sport port1[:port2] 匹配源端口(可指定连续的端口)
–dport port1[:port2] 匹配目的端口(可指定连续的端口)
-o interface 匹配出口网卡,只适用FORWARD、POSTROUTING、OUTPUT(例:iptables -A FORWARD -o eth0)
-i interface 匹配入口网卡,只使用PREROUTING、INPUT、FORWARD。
–icmp-type 匹配icmp类型(使用iptables -p icmp -h可查看可用的ICMP类型)
–tcp-flags mask comp 匹配TCP标记,mask表示检查范围,comp表示匹配mask中的哪些标记。(例:iptables -A FORWARD -p tcp –tcp-flags ALL SYN,ACK -j ACCEPT 表示匹配SYN和ACK标记的数据包)
目标动作 说明
ACCEPT 允许数据包通过
DROP 丢弃数据包
REJECT 丢弃数据包,并且将拒绝信息发送给发送方
SNAT 源地址转换(在nat表上)例:iptables -t nat -A POSTROUTING -d 192.168.0.102 -j SNAT –to 192.168.0.1
DNAT 目标地址转换(在nat表上)例:iptables -t nat -A PREROUTING -d 202.202.202.2 -j DNAT –to-destination 192.168.0.102
REDIRECT 目标端口转换(在nat表上)例:iptables -t nat -D PREROUTING -p tcp –dport 8080 -i eth2.2 -j REDIRECT –to 80
MARK 将数据包打上标记;例:iptables -t mangle -A PREROUTING -s 192.168.1.3 -j MARK –set-mark 60


[!] –match-set

setname flag [, flag ].. ,其中flag是用逗号分隔的src或dst规范的列表,其中最多只能有6个。


iptables -A FORWARD -m set --match-set test src,dst

mark值有何意义

mark字段的值是一个无符号的整数,在32位系统上最大可以是4294967296(就是2的32次方),这足够用的了。比如对一个流或从某台机子发出的所有的包设置了mark值,就可以利用高级路由功能来对它们进行流量控制等操作了。


mark值不是包本身的一部分,

而是在包穿越计算机的过程中由内核分配的

和它相关联的一个字段

。它可能被用来改变包的传输路径或过滤。



mark值只在本机有意义




在本机给包设置关联的mark值后,可通过该值对包后续的传输进行控制(排队,流量控制等)。



mark的格式是

–mark value[/mask]

,如上面的例子是没有掩码的,带掩码的例子如

–mark 1/1

。如果指定了掩码,就先把mark值和掩码取逻辑与,然后再和包的mark值比较



版权声明:本文为zhonglinzhang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。