在 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
1
mikeguan 2021-06-07 22:08:16 +08:00 via Android
iptables dnat 转发 udp 好像会丢失转发前的地址和端口
shadowsocks-libev 项目上有提供使用内核的 tproxy 来转发 udp 的方法 |
2
iBugOne 2021-06-07 22:49:06 +08:00
把 DNAT 都换成 REDIRECT 吧,至少 REDIRECT 到本机后接收到包的进程可以获取 SO_ORIGINAL_DST 来帮你转发
|
3
caobug OP 谢谢抽空解答 ^_^
@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 ``` |
4
caobug OP 有些眉目了:
当转发到本地代理程序之后,需要在程序中通过 recvmsg 接受 udp 数据,并传入结构体 msghdr 以填充具体信息。 然后再从 msghdr 中查找原始目的地信息,如 119.29.29.29 。 当要回复 udp 给客户端时,新建 socket 并 bind 到原始目的地( 119.29.29.29 ),然后再 send 给客户端。 据测试 macOS pf udp 转发不需要这样处理,直接 send 给 client 就好了。 |
5
zhangsanfeng2012 2021-06-08 08:53:29 +08:00
配置 http_proxy 和 https_proxy 就可以了吧
|