iptables -j REDIRECT *实际上*对数据包标头做了什么?

iptables -j REDIRECT *实际上*对数据包标头做了什么?

出于好奇,我正在阅读一些有关透明 TOR 代理的教程,因为从网络角度来看,这是一个非常有趣的主题。与仅使用tun/tap接口并且我完全清楚的VPN 网关相反,TOR 代理使用单个端口。所有教程都重复神奇的线条:

iptables -t nat -A PREROUTING -i eth0 -p tcp --syn -j REDIRECT --to-ports 9040

其中eth0是输入 (LAN) 接口,9040是某个 TOR 端口。问题是,我完全不明白为什么从网络的角度来看这样的事情有意义。

根据我对redirect/dst-nat链的理解以及它在物理路由器中的工作方式,dst-nat链需要dst-portdst-addr 做出路由决策并将其更改为其他内容。例如:

  • dst-nat192.168.1.2:46364 -> 88.88.88.88:80
  • dst-nat192.168.1.2:46364 -> 99.99.99.99:8080

99.99.99.99:8080是 IP 数据包流通道中的进一步链所看到的内容(例如filter表),这就是数据包从现在开始离开设备后的样子。

现在互联网上的许多人(包括在这个 stackexchange 上)声称这与设置为接口的本地地址redirect基本相同。鉴于此,该规则:dst-natdst-addr

iptables -t nat -A PREROUTING -i eth0 -p tcp --syn -j REDIRECT --to-ports 9040

显然没有意义。如果这就是它的工作原理,那么 TOR 将得到全部目的地为 的数据包127.0.0.1:9040。对于应用程序获取数据包并以某种方式响应它的典型应用程序(例如 Web 服务器),这是完全有意义的,因为毕竟,这样的服务器进程无论如何都是数据包的最终目的地,因此目标地址是 localhost 是可以的。但 TOR 路由器是一个很好的路由器,因此它必须知道数据包的原始目的地。我错过了什么吗?不DNAT影响本地应用程序接收什么?还是REDIRECT指令的具体行为?

答案1

看看这个答案:透明 SOCKS 代理如何知道要使用哪个目标 IP?

引述:

iptables 会覆盖原始目标地址,但它会记住旧的地址。然后,应用程序代码可以通过请求特殊的套接字选项 来获取它SO_ORIGINAL_DST

答案2

实际上你对 TOR 的看法是对的,收到的每个 tcp 数据包都会重定向到 localhost:9040。

目标 REDIRECT 是 DNAT 目标的特殊类型,它将更改本地接口的 IP 地址并映射到您指定的端口。

假设有一个路由器,其 lan 接口为eth0(网络192.168.1.0/24和 IP 地址:)192.168.1.1,并且该路由器的 iptables 规则为:

iptables -t nat -A PREROUTING -i eth0 -p tcp --syn -j REDIRECT --to-ports 9040

那么来自 lan 内客户端的所有 tcp 数据包都会重定向到192.168.1.1:9040.

192.168.1.2假设局域网内的客户端(带有 ip 地址)到 google.com(假设 ip: )有 tcp 连接,8.8.1.1那么,

原始请求: 192.168.1.2:12345 -> 8.8.1.1:80

在路由器的预路由链之后:192.168.1.2:12345->192.168.1.1:9040

相关内容