17

IPTABLES UDP 端口转发疑惑

 3 years ago
source link: https://www.v2ex.com/t/781982
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  Linux

IPTABLES UDP 端口转发疑惑

  caobug · 1 天前 · 586 次点击

在 centos7 拉取 github 源码编译经常连不上,找了许多资料发现透明代理比较合适。

一番折腾 TCP 终于正常转发,UDP 如果配置 PREROUTING 就没任何转发效果,配置成 OUTPUT 可以转发不过报文不对:

;; reply from unexpected source: 192.168.0.101#1080, expected 119.29.29.29#53

求大佬帮忙

#!/usr/bin/env bash

start() {
    stop

    iptables -t nat -A OUTPUT -p tcp -m mark --mark 0x255 -j ACCEPT
    iptables -t nat -A OUTPUT -p udp -m mark --mark 0x255 -j ACCEPT

    # tcp
    iptables -t nat -A OUTPUT -p tcp -j REDIRECT --to-ports 1080

    # udp
    # ip rule add fwmark 0x2333/0x2333 pref 100 table 100
    # ip route add local default dev lo table 100
    # iptables -t mangle -A PREROUTING -p udp --dport 53 -j TPROXY --tproxy-mark 0x2333/0x2333 --on-ip 127.0.0.1 --on-port 1080
    # --dport 53

    # iptables -t nat -A PREROUTING -p udp --dport 53 -j DNAT --to 192.168.6.10

    iptables -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to-ports 1080
}

stop() {
    iptables -t nat -F
    iptables -t mangle -F
    iptables -F
    iptables -X
    ip rule delete fwmark 0x2333/0x2333 pref 100 table 100 &>/dev/null
    ip route delete local default dev lo table 100 &>/dev/null
}

if [[ $1 == "start" ]]; then
    start
elif [[ $1 == "stop" ]]; then
    stop
fi
5 条回复    2021-06-08 08:53:29 +08:00

mikeguan

mikeguan   1 天前 via Android

iptables dnat 转发 udp 好像会丢失转发前的地址和端口

shadowsocks-libev 项目上有提供使用内核的 tproxy 来转发 udp 的方法

iBugOne

iBugOne   1 天前

把 DNAT 都换成 REDIRECT 吧,至少 REDIRECT 到本机后接收到包的进程可以获取 SO_ORIGINAL_DST 来帮你转发

caobug

caobug   1 天前

谢谢抽空解答 ^_^

@mikeguan ss 提供的 tproxy udp 解决方案似乎只能用于“路由器”或将 Linux 作为路由器使用,不适用于透明代理当前 Linux 对外发包,ss 代码倒没问题,就是防火墙没配对。

@iBugOne REDIRECT 可以成功重定向到本机端口,代理程序也可以收到数据包,但是回复后防火墙似乎没正确转换。
比如我查询:dig www.baidu.com ,会得到以下错误报告:预期收到来自 119.29.29.29:53 的 udp 答复,但收到了 192.168.0.101:1080 的
```
;; reply from unexpected source: 192.168.0.101#1080, expected 119.29.29.29#53
```

```
#!/bin/sh

start() {
stop

iptables -t nat -A OUTPUT -p tcp -m mark --mark 0x255 -j ACCEPT
iptables -t mangle -A OUTPUT -p udp -m mark --mark 0x255 -j ACCEPT

# tcp
iptables -t nat -A OUTPUT -p tcp -j REDIRECT --to-ports 1080

# udp
ip rule add fwmark 1 lookup 100
ip route add local default dev lo table 100
iptables -t mangle -A OUTPUT -p udp --dport 53 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -p udp --dport 53 -j TPROXY --on-ip 127.0.0.1 --on-port 1080 --tproxy-mark 0x01/0x01

iptables -t nat -L -nvx
iptables -t mangle -L -nvx
}

stop() {
iptables -t nat -F
iptables -t mangle -F
iptables -F
iptables -X
ip rule delete fwmark 1 lookup 100 &>/dev/null
ip route delete local default dev lo table 100 &>/dev/null
}

if [[ $1 == "start" ]]; then
start
elif [[ $1 == "stop" ]]; then
stop
fi

```

caobug

caobug   1 天前

有些眉目了:

当转发到本地代理程序之后,需要在程序中通过 recvmsg 接受 udp 数据,并传入结构体 msghdr 以填充具体信息。

然后再从 msghdr 中查找原始目的地信息,如 119.29.29.29 。

当要回复 udp 给客户端时,新建 socket 并 bind 到原始目的地( 119.29.29.29 ),然后再 send 给客户端。

据测试 macOS pf udp 转发不需要这样处理,直接 send 给 client 就好了。

zhangsanfeng2012

zhangsanfeng2012   1 天前

配置 http_proxy 和 https_proxy 就可以了吧

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK