Iptables
31 May 2023 - joy717
iptables
两张表
iptables --> 网络层(上图的绿色的Network level)
ebtables --> 数据链路层(上图的蓝色的Bridge level)
ebtables
与iptables
作用类似,只不过是基于数据链路层的处理,处于iptables
的外层。入方向,先经过ebtables
再进入iptables
,出方向,则先经过iptables
,再进入ebtables
iptable 包在各个4表5链上的执行顺序
https://www.linuxtopia.org/Linux_Firewall_iptables/c951.html
不知道这个文档描述是否与比较新的内核一致。
iptables set-xmark 解释
https://stackoverflow.com/questions/22003409/some-questions-about-set-xmark-in-iptables https://blog.csdn.net/qq_31977125/article/details/124208384
命令格式:--set-xmark value/mask
实际计算公式为:ctmark = (ctmark AND NOT mask) XOR value (ctmark为数据包在--set-mark之前的数据包mark值,即原始值)
即,Zero out the bits given by mask and XOR value into the ctmark
(将mask给的位抹零,再将 原始值 XOR value
)
iptables -j(jump) -g(goto)区别
https://serverfault.com/questions/675559/iptables-using-goto-jump-what-is-the-return-behaviour
https://stackoverflow.com/questions/31606411/iptables-j-vs-g-parameters
-j 返回到调用-j的下一条记录继续执行
-g 不是返回到调用-g的下一条记录继续执行,而是返回到最近的调用-j的下一条记录继续执行
# 例子
-A CHAIN-A -j CHAIN-SUB
-A CHAIN-A -m comment 'chain-a'
-A CHAIN-SUB -m comment 'hello'
# -j 由`CHAIN-A`到 `CHAIN-SUB`, 当`CHAIN-SUB`执行到底或者RETURN后,回到调用jump的位置执行下一条规则,即:`-A CHAIN-A -m comment 'chain-a'`
-A CHAIN-PART -j CHAIN-XXX
-A CHAIN-PART -j CHAIN-A
-A CHAIN-PART -m comment 'chain-part'
-A CHAIN-A -g CHAIN-SUB
-A CHAIN-A -m comment 'chain-a'
-A CHAIN-SUB -m comment 'hello'
# -g 由`CHAIN-PART`jump到`CHAIN-A`,再goto到`CHAIN-SUB`,当`CHAIN-SUB`执行到底或者RETURN后,不是回到调用goto的位置执行下一条(`-A CHAIN-A -m comment 'chain-a'`),
# 而是返回最近的一个调用jump的位置,继续往下执行,即`-A CHAIN-PART -m comment 'chain-part'`
各种JUMP的执行顺序
https://www.jianshu.com/p/15bd803e3bb8
https://www.flftuu.com/2021/07/12/iptables%E7%94%A8%E6%B3%95/
kube-proxy iptable/ipvs 详解
https://zhuanlan.zhihu.com/p/94418251
https://www.digihunch.com/2020/11/ipvs-iptables-and-kube-proxy/
iptables链路表
iptables 扩展组件
https://ipset.netfilter.org/iptables-extensions.man.html
iptables查看某个module的帮助
iptables -m addrtype --help
路由表与netfilter交互
Linux路由表其实有2个主要概念:
- 路由策略(rule)
- 路由表(table)
Linux可以配置很多很多策略,数据包将依次通过各个策略,一旦匹配某个策略则进一步应用策略对应的路由表,如果当前路由表无法匹配到路由则继续执行后续策略匹配。
MASQ的选择src ip的逻辑
Masq会导致多执行一次路由选择,确定出口网卡上与目标地址的路由结果匹配的ip地址。
如果不匹配,查找出口网卡的master设备。
如果不匹配,则遍历所有设备,只关心master设备
路由之后再修改src IP
https://elixir.bootlin.com/linux/latest/source/net/netfilter/nf_nat_masquerade.c#L44
https://cloud.tencent.com/developer/article/2144773
允许iptables的trace
# 添加TRACE的规则
iptables -t raw -I PREROUTING -s 172.31.1.136 -m comment --comment "prerouting start" -j TRACE -w 10
# 正常在/var/log/message 里面会输出`kernel: TRACE:`字眼的日志,如果没有,可以执行下面命令,开启日志
# 添加规则的时候,有可能报没有target的错误,需要加载一下nf_log_ipv4的模块
modprobe nf_log_ipv4
sysctl net.netfilter.nf_log.2=nf_log_ipv4
# 如果发现有些包没有被log记录下来,可能是log系统的限流导致,比如
# `imjournal: begin to drop messages due to rate-limiting`
# 修改/etc/rsyslog.conf, 设置:(需包含最前面的$)
$imjournalRatelimitInterval 0
$imjournalRatelimitBurst 0
# 重启rsyslog服务
systemctl restart rsyslog
ipvs
经典架构
____________
| |192.168.1.254 (eth1)
| client |----------------------
|____________| |
CIP=192.168.2.254 (eth0) |
| |
| |
VIP=192.168.2.110 (eth0) |
____________ |
| | |
| director | |
|____________| |
DIP=192.168.1.9 (eth1, arps) |
| |
(switch)------------------------
|
RIP=192.168.1.2 (eth0)
VIP=192.168.2.110 (for LVS-DR, lo:0, no_arp)
_____________
| |
| realserver |
|_____________|
词汇
| IP | 描述 | |-----|-----------------------------------------------------------------------------------| | CIP | Client IP | | VIP | Virtual IP (即LB的ip) | | DIP | Director IP (更普遍的情况是,lvs是一个网关,隔离了外部网络-Client 跟内部网络)-RealServerDIP为内部网络这一侧的IP | | RIP | RealServer IP (实际服务的IP) |
ipvs原理实现
https://github.com/liexusong/linux-source-code-analyze/blob/master/lvs-principle-and-source-analysis-part2.md
官方文档:http://www.linuxvirtualserver.org/Documents.html
ipvs与netfilter交互
http://www.austintek.com/LVS/LVS-HOWTO/HOWTO/LVS-HOWTO.filter_rules.html
ipvs与iptables优先级
Modules register with a priority, the lowest priority getting to look at the packets first. LVS registers itself with a higher priority than iptables rules, and thus iptables will get the packet first and then LVS
所以,ipvs转发时:PREROUTING->路由表->INPUT(iptables)->INPUT(lvs)->POSTROUTING
ipvsadm显示的masq
ipvs的转发模式包含:
- DR(direct routing,也叫gateway模式)
- IPIP 隧道模式
- MASQ 实际为DNAT,并没有MASQ(SNAT)
使用ipvs以及相关的配置
https://medium.com/google-cloud/load-balancing-with-ipvs-1c0a48476c4d
http://www.linuxvirtualserver.org/VS-NAT.html
ipvs-nat限制条件
client->lvs->realServer
ipvs只在lvs这边设置dnat,并没有针对src ip做修改,因此realServer收到的包src ip为client的ip,dst ip为realServer的ip。
当realServer发响应包回去的时候,目的地址为client的ip,就无法回到lvs这边来。
ip地址变化情况:
| 包当前所在位置 | src ip | dst ip | |------------|--------|--------| | client | CIP | VIP | | lvs | CIP | RIP | | RealServer | CIP | RIP |
一种最直接的方式,就是将realServer的默认网关配置为lvs (DIP,Director IP)。
另外一种方式是,在realServer这边配置路由,将来自realServer服务ip的包,转到lvs这边,比如:
realserver# echo 80 lvs >> /etc/iproute2/rt_tables
realserver# ip route add default <address on director, eg DIP> table lvs
realserver# ip rule add from <RIP> table lvs
iptables例子解释
addrtype 为LOCAL
-A KUBE-SERVICES -m addrtype --dst-type LOCAL -j KUBE-NODEPORTS
如果目标地址是LOCAL的,则jump到KUBE-NODEPORTS。 什么是LOCAL?本地所有网卡上的IP地址,都属于LOCAL。换言之,如果是发往本机器(ip与网卡上任一匹配),则jump
ip route show table local type local
可显示所有的本地ip
calico规则
-A cali-POSTROUTING -o vxlan.calico -m comment --comment "cali:e9dnSgSVNmIcpVhP" -m addrtype ! --src-type LOCAL --limit-iface-out -m addrtype --src-type LOCAL -j MASQUERADE
ADDRTYPE match src-type LOCAL:LOCAL 表示主机上分配的任何 IP 地址,包括 127.0.0.1 和 其他 IP,规则含义是源地址是本地 IP
ADDRTYPE match src-type !LOCAL limit-out: limit-iface-out 限制了 LOCAL 表示的 IP 内容,此时的 LOCAL 只包括 Package 发出设备上的 IP,即 src-type !LOCAL limit-out 的含义是源地址 IP 是 除 Package 发出设备以外的本地 IP
综上 cali-POSTROUTING 进行 MASQUERADE 的条件是:src 是本地地址,并且 src 地址 ip 不能是 out-interface 的 ip。
iptables 空链表
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [37616:23606638]
:cali-PREROUTING - [0:0]
-A PREROUTING -m comment --comment "cali:6gwbT8clXdHdC1b1" -j cali-PREROUTING
这边可以看到,-A PREROUTING -m comment --comment "cali:6gwbT8clXdHdC1b1" -j cali-PREROUTING
,jump到cali-PREROUTING
,但cali-PREROUTING
实际为空链表。
估计是拿来预定义占坑用的。
bridge 配置
-m physdev
此module配置,是给bridge使用的。
iptables与bridge配合使用,可参考:
https://opengers.github.io/openstack/openstack-base-virtual-network-devices-bridge-and-vlan/ 与bridge
k8s ipvs使用
https://zhuanlan.zhihu.com/p/110860643
https://kubernetes.io/blog/2018/07/09/ipvs-based-in-cluster-load-balancing-deep-dive/
k8s nodeport svc + hostNetwork
NodePort类型的svc,如果后端的pod使用的是hostNetwork,则svc的nodeport无法正常访问。
https://stackoverflow.com/questions/42480525/kubenetes-pod-hostnetwork-cause-nodeport-does-not-work