在阅读了一些关于TPROXY的内容后(例如https://www.kernel.org/doc/html/latest/networking/tproxy.html)我现在的问题比答案还多。我实际上甚至不知道 TPROXY 应该做什么……
关于我应该做什么以及内部会发生什么的一些假设。
你能纠正以下假设吗?
据我了解,这些是您应该运行的命令(虽然我不知道为什么):
iptables -t mangle -N DIVERT
:- 一个名为的链
DIVERT
已创建。 - 您可以选择名称。(只要在所有命令中都相同)。
- 它必须是其中的一部分,
mangle
因为您将要做的事情比重定向、阻止和 NAT 更为复杂。
- 一个名为的链
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
:- 该
PREROUTING
链确保一旦 TCP 数据包从网络设备传递到内核,首先发生的事情就是它被发送到链DIVERT
。 -p tcp
确保非 TCP 流量不会出现这种情况。-m socket
确保创建和关闭连接的数据包不会出现这种情况(例如SYN/ACK
)- 删除
-p tcp -m socket
TPROXY 将影响所有 IP(v4) 数据包。这将是一个不同但有效的设置。
- 该
iptables -t mangle -A DIVERT -j MARK --set-mark 1
:- 内核会用数字 来标记这些数据包
1
。你可以选择其他数字。 - 也可以为数据包添加多个标记。例如:通过添加命令,
iptables -t mangle -A DIVERT -i eth0 -j MARK --set-mark 2
您可以确保所有 TCP 数据包都获得标记1
,并且来自 的所有 TCP 数据包都eth0
获得标记1
和2
。 - “用数字标记
X
”只是意味着“归类为类别成员,X
但实际上并不改变数据包中的任何内容”。 - 内核和用户空间的程序都可以读取数据包的标记
- 只有内核可以标记数据包
- 内核会用数字 来标记这些数据包
iptables -t mangle -A DIVERT -j ACCEPT
:默认情况下,内核会丢弃数据包,因此您现在要确保它不会这样做。ip rule add fwmark 1 lookup 100
:1
所有带有标记的数据包现在都使用名为 的表,而不是使用默认路由表100
。- 你可以选择其他号码,只要确保在其他地方使用相同的号码即可
ip route add local 0.0.0.0/0 dev lo table 100
:100
如果表不存在则创建表- 添加路由规则,确保所有来自我们系统 (
local
) 的包都保持本地状态,方法是将它们发送回lo
- 对于具有任何目的地的包裹都是这种情况
0.0.0.0/0
(每个 IPv4 地址都是此子网的成员) - 但对于没有标记的包裹则不是这种情况
1
(否则它们就不会出现在100
)
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 50080
:- 所有发送的数据包都会
tcp/80
收到标记1
并最终到达tcp/50080
- 对于某些我不清楚的原因,它们被标记了。(在我看来,它们
DIVERT
无论如何都会经过,然后再次被标记) - 对于一些人来说,对我来说,未知原因
0x1
写了两次
- 所有发送的数据包都会
我对 TPROXY 用途的假设是:重新路由数据包而不改变它们
答案1
“重新路由而不改变”在技术上基本上是正确的,但要理解它的用途,最好将其视为“拦截”——通常,您只是“重新路由”到您编写的程序,该程序在同一台机器上运行(该机器应该是客户端的 wifi 接入点,或位于它们与世界其他地方之间的类似位置)。这是一种在 C/C++/任何代码中获取看起来像普通 TCP 套接字的方法,您可以在该套接字上发送 () 和接收 (),但实际上可以让您模拟它们的预期目的地。
一种用途是通过一些非常奇特的设置透明地代理流量,甚至精心配置的 Wireguard 也无法处理它,而是需要编写自己的实际程序才能使其工作。
看看这个:https://github.com/FarFetchd/simple_tproxy_example
这是您可以用它做的最简单、最有趣的事情的一个最小工作示例,它可能会让您更好地理解“为什么”。
至于这些ip rule fwmark
东西,我建议你找一个适合你的例子,然后把它当作黑魔法咒语,除非你试图在 Linux 网络堆栈本身上进行严肃的开发工作。我的意思是,我认为自己基本上精通 iptables,并且用 TPROXY 做了一些真正有用的工作,但我仍然觉得这些ip rule fwmark
东西完全神秘,哈哈。
答案2
对于您的第一个“未知原因”,DIVERT 匹配的数据包被接受,这意味着它们不会经过剩余的规则,也不会前往第二个标记位置。
对于第二个“未知原因”,两个 0x1 是值和掩码。
您可能会发现 iptables 和 iptables-extensions 的手册页很有帮助。