V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
ac169
V2EX  ›  Linux

iptables 的 redirect 动作,对 IP 包到底做了什么?

  •  
  •   ac169 · 299 天前 · 1230 次点击
    这是一个创建于 299 天前的主题,其中的信息可能已经有所发展或是发生改变。

    以前常用 iptables 的 redirect 动作做端口转发,那个时候我的理解就是对 IP 包的目标端口做了修改然后转发;最近看了一些透明代理的实现,发现规则里也用到了 iptables 的 redirect 动作来转到某些代理协议的服务端口(比如:dokodemo door )。

    如果按照以前的理解 redirect 动作修改了目标端口,那么代理程序的出口如何知道这个 IP 包要转发到的原始端口?如果 redirect 动作仅仅是把匹配的数据包转发 到指定端口什么都不修改,那么 IP 报文的目标端口都和实际服务的端口不一样,这个数据包怎么被服务收到? 官方文档我看过,没有看到详细过程的说明。

    12 条回复    2023-07-04 11:41:51 +08:00
    billlee
        1
    billlee  
       299 天前 via Android
    内核会记住原来的目标地址,getsockopt 有个参数可以获取。
    bao3
        2
    bao3  
       299 天前
    内核帮你划分了一个用来做 mapping 的区域,所以叫透明代理,对你的应用是透明的。
    RobberPhex
        3
    RobberPhex  
       299 天前
    tproxy 部分:
    1. 先用 setsockopt 函数为套接字设置 IP_TRANSPARENT 标识
    2. accept 后,对 socket 进行 getsockopt(SO_ORIGINAL_DST)操作,获取原始的 ip 端口
    3. 但 udp 没有 socket 对象,所以如下:
    4. 通过 setsockopt(fd, SOL_IP, IP_RECVORIGDSTADDR, ...)给 socket 设置 IP_RECVORIGDST
    5. 用 recvmsg 函数替代 recvfrom/recv 来接收数据包,返回的结果里有 msghdr 结构体,并遍历(cmsghdr*)msg_control ,找到 level 为 SOL_IP 的结构体,它就包含了 sockaddr_in 原始 IP 和端口。


    其中 1 、2 是 redirect ,其他事 tproxy 扩展的。

    另外,配置的时候要额外注意下 iptables 的配置,防止出现网络问题。比如我有一次就是 drop 了 tcp 握手中的 ack+syn 包,google 封禁了 IP (直接无法搜索)。https://github.com/robberphex/luci-app-v2ray/blob/v2.2.4/root/etc/init.d/luci_v2ray#L583
    ac169
        4
    ac169  
    OP
       299 天前
    @billlee
    @bao3
    @RobberPhex

    谢谢,也就是说 redirect 会修改 IP 包 目的端口 等信息,但代理程序通过其他方式可以获取到原始的目的等信息,所以能完成代理功能!
    hankai17
        5
    hankai17  
       299 天前
    透明代理
    一般情况下本机监听的就是 realServer 的 ip 跟端口 不存在修改
    hankai17
        6
    hankai17  
       299 天前
    @RobberPhex 咨询一下 1 、2 对应的代码在哪个文件里?
    mikewang
        7
    mikewang  
       299 天前 via iPhone   ❤️ 1
    参考 https://www.netfilter.org/documentation/HOWTO/NAT-HOWTO-6.html#ss6.2

    There is a specialized case of Destination NAT called redirection: it is a simple convenience which is exactly equivalent to doing DNAT to the address of the incoming interface.
    alexapollo
        8
    alexapollo  
       299 天前
    我印象里十年前这个模块叫做 conntrack ?
    julyclyde
        9
    julyclyde  
       298 天前
    @alexapollo 和 conntrack 根本两码事
    alexapollo
        10
    alexapollo  
       298 天前
    @julyclyde 楼上的 DNAT 让我触发了回忆,那时候 DNAT 不是默认 conntrack 吗
    julyclyde
        11
    julyclyde  
       298 天前
    @alexapollo “带有”conntrack ,和“是”conntrack 两码事
    alexapollo
        12
    alexapollo  
       298 天前
    @julyclyde Sounds reasonable
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   910 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 20:04 · PVG 04:04 · LAX 13:04 · JFK 16:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.