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

    本文为 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)的地址

 

【kubernetes/k8s概念】calico iptables 规则分析_第1张图片

                                                           引用网上图片 

基本步骤如下:  

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值比较

你可能感兴趣的:(#,kubernetes,CNI,网络)