[流量劫持] 求问如何本地进程 A 发给本地进程 B 的数据包转发给其他机器呢?

22 天前
 Charlie17Li

背景

在某个节点上,容器进程 A 默认是将数据包发给容器进程 B ,考虑到进程 B 升级,需要将流量转到其他机器上。

尝试

使用 ebpf 劫持 connect 系统调用可以做,以及使用 tc-ebpf 实现 nat ,但是被否了!理由是不够安全,存在影响其他容器的风险。

有大佬说可以使用 tc mirror 将流量镜像到 tun ,走隧道,发给本地进程 B 的就 drop 掉(暂时还没弄明白,可不可行,有无大佬解答)

iptables contrack 被禁止使用,导致无法使用其 nat 能力。

求问实现如上功能的方式

1270 次点击
所在节点    程序员
10 条回复
FishBear
22 天前
haproxy
Charlie17Li
22 天前
@FishBear 感谢,不过事实上进程 A 和 B 是在同一个 Pod 中,如果引入另外一个
proxy 需要添加一个容器 C ,可能不太符合需求。
leconio
22 天前
感觉原理很像透明代理和分流。看看 tproxy?
Charlie17Li
22 天前
@leconio tproxy 会将流量发到机器的某个端口,然后透明代理进程监听这个端口并实现转发,这个实际上还是引入了一个 proxy 。

引入另外一个 proxy 的有两个风险:proxy 稳定性和资源占用;数据包从 app 发到内核后,又从内核发到 proxy ,接着 proxy 又将数据包发给内核,最终才转发出去,性能可能有一定影响,不过核心还是第一个风险。
zhangeric
21 天前
这个是端口转发吧
Charlie17Li
21 天前
@zhangeric 数据包需要转到另外一个机器上,端口转发是将数据包转到当前机器,不太一样?
bingfengfeifei
21 天前
感觉像是同时做 DNAT+SNAT ,然后转发到其他机器上。
本机:192.168.1.1
其他机器:192.168.1.2
两进程 localhost 通信
127.0.0.1:12345->127.0.0.1:8080
入站先使用 DNAT 变成 127.0.0.1:12345->192.168.1.2:80
出站使用 SNAT 变成 192.168.1.1:12345->192.168.1.2:80
这样其他机器的响应报文也可以发回来。

主要问题就是 localhost 好像和物理网卡的入站流量不太一样,iptables 拦截不太清楚能不能走到 PREROUTING 和 POSTROUTING 链,可能要开个 route_localnet 的选项
muziyu58
21 天前
@Charlie17Li A 机器端口数据包,转发到 B 机器端口上,看起来行得通呀
Charlie17Li
21 天前
@bingfengfeifei 是的,可以视作 FNAT(full nat)(疑似)

"""
入站先使用 DNAT 变成 127.0.0.1:12345->192.168.1.2:80
出站使用 SNAT 变成 192.168.1.1:12345->192.168.1.2:80
"""
这个入站是指其他机器发给本机的包吗?

如果是,实际上入站需要 SNAT ,将其他机器的 IP 改成 127.0.0.1 ;因为从本机的 client 看来,他是与本机(127.0.0.1)的进程通信,如果收到的包 src_ip 不是 127.0.0.1 就会发 RST 。这个我通过 epbf 做 NAT 时遇到过这个问题。

出站需要 DNAT ,将本地 server 从 127.0.0.1:80 改成 192.168.1.2:80



"""
iptables 拦截不太清楚能不能走到 PREROUTING 和 POSTROUTING 链
"""
lo 和 eth0 的出入流量均需要经过协议栈,理论上应该会经过,不过我没弄明白经过这两个链时可以做啥处理吗?


"""
可能要开个 route_localnet 的选项
"""
目前,我正在使用 tc-nat 尝试,目前我的思路是:

当前本地通信的数据包流转是这样子的:

client -> netfilter -> lo -> tc(egress) -> ... -> tc(ingress) -> netfilter -> server

我在 netfilter 的(OUTPUT)链中给流量打标记,然后在 ingress 处执行 DNAT ,试图通过 forward 链后发到 eth0 。

不过目前 ingress 处执行 DNAT 后,数据包并没有进入 eth0 ,而是被奇怪的丢掉了

route_localnet 这个参数大佬可以详细讲讲使用场景吗?
Charlie17Li
21 天前
@muziyu58 很多实践是基于 Iptables nat 做的,我的场景里无法使用 Iptables-nat

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1068265

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX