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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/zhonglinzhang/article/details/97894806

    本文为 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. 决定路由,看是交给本地主机还是转发给其它主机


     两种不同的情况进行讨论了,一种情况就是数据包要转发给其它主机
7. 进入 mangle 表的 FORWARD 链,这里也比较特殊,这是在第一次路由决定之后,在进行最后的路由决定之前,我们仍然可以对数据包进行某些修改。  
8. 进入 filter 表的 FORWARD 链,可以对所有转发的数据包进行过滤。需要注意的是:经过这里的数据包是转发的,方向是双向的。  
9. 进入 mangle 表的 POSTROUTING 链,到这里已经做完了所有的路由决定,但数据包仍然在本地主机,还可以进行某些修改。  
10. 进入 nat 表的 POSTROUTING 链,在这里一般都是用来做 SNAT 
11. 进入出去的网络接口。完毕。  


     另一种情况是,数据包就是发给本地主机的
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值比较

猜你喜欢

转载自blog.csdn.net/zhonglinzhang/article/details/97894806