edgemesh利用iptables劫持流量时遇到的问题分析

edgemesh利用iptables劫持流量时遇到的问题分析,第1张

kubeedge相比kubernetes,主要的提供了跨子网构建集群的方案;其最强大的特点就是让kubernetes不在局限于一个物理机房之内;集群中的主机节点可以在不同的私有局域网内。

不同私有网络之下的主机要进行相互通信,最主要的就是受限于防火墙NAT形态:

上面的各组网方案之中,依次安全性增强,在对称锥形的网络中,所有主机都在各自的防火墙背后,直接穿透访问就非常困难,所以直接edgemesh提供了两种穿透访问方案:

edgemesh-server: Deployment 云端

edgemesh-agent: DaemonSet 云端+边缘

对于全锥形NAT、受限性NAT、部分端口受限锥形NAT访问可以直接采用如下方案;

对于直接穿透访问不了的请求,edgemesh-agent就会将流量转发到edgemesh-server上进行中继,因为所有的edgemesh-agent在启动后,就会于云端的edgemesh-server建立一个隧道网络;

在kubernetes+kubeedge组成的边缘云集群上,无论云端or边缘主机,都部署了edgemesh-agent,其有两个主要功能:

环境:

mkedge3 10.136.77.2 北四环办公室边缘盒子 edgemesh-agent role : edgenode kernel : 5.2.14-1.el7.elrepo.x86_64

mkedge2 10.201.82.131 天坛机房 edgemesh-agent role : edgenode kernel : 4.15.6-1.el7.elrepo.x86_64

用例:

在mkedge2上启动tcp-echo-cloud容器,通过mkedge3上的busybox容器进行远程telnet tcp-echo-cloud 2701

说明:

从实际流量抓包看来看,从办公室机房能够直接访问到天坛机房主机,不需要中继;

mkedge3发起请求tcp抓包

mkedge2上接收载荷tcp抓包

环境:

mkmaster1 10.200.50.118 国贸机房 edgemesh-server, edgemesh-agent role : master kernel : 5.2.14-1.el7.elrepo.x86_64

mkworker3 10.202.42.112 亦庄机房 edgemesh-agent role : cloudnode kernel : 5.2.14-1.el7.elrepo.x86_64

mkedge3 10.136.77.2 北四环办公室边缘盒子 edgemesh-agent role : edgenode kernel: 3.10.0-514.el7.x86_64

用例:

在mkworker3 上启动tcp-echo-cloud容器,通过mkedge3上的busybox容器进行远程telnet tcp-echo-cloud 2701

说明:

从实际流量抓包看来看,从办公室机房不能直接访问到亦庄机房主机,需要国贸机房的edgemesh-server中继;

mkedge3发起请求tcp抓包

mkmaster1进行中继tcp抓包

mkworker3上接收载荷tcp抓包

先说结论,怀疑主机默认内核 4.15.6-1.el7.elrepo.x86_64 (centos7) 存在调用系统内核函数getsockopt的严重bug!!!

环境:

mkmaster1 10.200.50.118 国贸机房 edgemesh-server, edgemesh-agent role : master kernel : 5.2.14-1.el7.elrepo.x86_64

mkworker1 10.201.82.139 天坛机房 edgemesh-agent role : cloudnode kernel : 5.2.14-1.el7.elrepo.x86_64

mkworker2 10.201.83.74 天坛机房 edgemesh-agent role : cloudnode kernel : 5.2.14-1.el7.elrepo.x86_64

mkedge1 10.201.82.148 天坛机房 edgemesh-agent role : edgenode kernel : 4.15.6-1.el7.elrepo.x86_64

mkedge2 10.201.82.131 天坛机房 edgemesh-agent role : edgenode kernel : 4.15.6-1.el7.elrepo.x86_64

mkedge3 10.136.77.2 北四环办公室边缘盒子 edgemesh-agent role : edgenode kernel: 3.10.0-514.el7.x86_64

用例:

在mkworker1、mkworker2、mkedge1、mkedge2上启动同时启动tcp-echo-cloud容器,通过mkedge1上的busybox容器进行远程访问这些服务,发现一个都不通;

现状:

从实际流量抓包看来看,从业务容器发送请求给到edgemesh-agent:40001端口,之后流量就不见了踪影;

[图片上传失败...(image-2899d1-1641166544225)]

究竟是Go的版本不对?容器镜像问题?逐个进行了排查:

给edgemesh-agent:proxy.go的Run()函数中,realServerAddress(&conn)调用之前,增加了打印日志,同时在这个函数调用中,增加了一些日志输出标记位,重新制作容器进行测试,发现输出日志 555 ,但未输出 666 ,同时进程状态异常变为了 D :

然后就开始怀疑是这个内核调用出现了问题,先编写了一个go程序: https://gitee.com/Hu-Lyndon/gogetsockopt.git

如下是在mkedge3宿主机上, kernel: 3.10.0-514.el7.x86_64,一个终端上先将程序启动监听18011端口,然后在另外一个连接mkedge3终端上,直接telnet这个端口,程序能够正确通信,并输出打印日志 address: 192.168.127.1:18011

如下是在mkedge1上测试, kernel : 4.15.6-1.el7.elrepo.x86_64, 发现telnet之后,无法输出打印日志,并且程序在第三个终端窗口里也无法 kill -9 ,并且进程状态变为了 D ;

不死心 ,程序在mkedge2上依然如上;

不死心 ,找了台内核升级为 kernel : 4.19.12-1.el7.elrepo.x86_64的主机,结果是正确的;

不死心: 虽然严重怀疑了 kernel : 4.15.6-1.el7.elrepo.x86_64,那么就近是Go的问题,还是系统内核的问题呢?于是又写了一个C程序来测试: https://gitee.com/Hu-Lyndon/unix-network-programming ,在compile-on-kernel4.15.6分支的/sockopt/sockoptchk.c

依然出现了上面出现的问题,说明应该就是kernel的问题了,需要推荐运维以后不要安装这个版本的内核了,目前看4.19.12以上的版本或者干脆就是3.10的内核都是打过patch的。

https://go.dev/play/p/GMAaKucHOr

https://elixir.bootlin.com/linux/latest/C/ident/sys_getsockopt

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/socket.c

https://bugzilla.kernel.org/show_bug.cgi?id=198791

http://patchwork.ozlabs.org/project/netfilter-devel/patch/a4752d0887579496c5db267d9db7ff77719436d8.1518088560.git.pabeni@redhat.com/

https://github.com/cybozu-go/transocks/pull/14


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7151704.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-02
下一篇 2023-04-02

发表评论

登录后才能评论

评论列表(0条)

保存