zfl9 / ipt2socks

将 iptables/nftables 传入的透明代理流量转为 socks5 流量的实用工具
GNU Affero General Public License v3.0
411 stars 94 forks source link

failed to bind address for udp4 socket: (98) address already in use #14

Closed XenMe closed 4 years ago

XenMe commented 4 years ago

环境信息

主要是为了代理路由器本身chinadns的upstream dns请求 路由器IP: 172.16.10.40 Chinadns-ng向8.8.8.8发出的请求经过TPROXY转发到ipt2socks 从Log发现,chinadns发出了UDP请求,TPROXY成功redirect到ipt2socks ipt2socks收到请求,但出现如题的错误

Log

2020-03-02 17:19:21 INF: [main] server address: 127.0.0.1#8087 2020-03-02 17:19:21 INF: [main] listen address: 0.0.0.0#1051 2020-03-02 17:19:21 INF: [main] number of worker threads: 1 2020-03-02 17:19:21 INF: [main] udp socket idle timeout: 300 2020-03-02 17:19:21 INF: [main] udp cache maximum size: 256 2020-03-02 17:19:21 INF: [main] tcp socket buffer size: 8192 2020-03-02 17:19:21 INF: [main] enable udp transparent proxy 2020-03-02 17:19:21 INF: [main] verbose mode (affect performance) 2020-03-02 17:19:36 INF: [udp_socket_listen_cb] recv 37 bytes data from 172.16.10.40#42285 2020-03-02 17:19:36 INF: [udp_socket_listen_cb] try to connect to socks5 server: 127.0.0.1#8087 2020-03-02 17:19:36 INF: [udp_socks5_tcp_connect_cb] connected to socks5 server: 127.0.0.1#8087 2020-03-02 17:19:36 INF: [udp_socks5_tcp_connect_cb] send authreq to socks5 server: 127.0.0.1#8087 2020-03-02 17:19:36 INF: [udp_socks5_auth_read_cb] send proxyreq to socks5 server: 127.0.0.1#8087 2020-03-02 17:19:36 INF: [udp_socks5_resp_read_cb] udp tunnel is open, try to send packet via socks5 2020-03-02 17:19:36 INF: [udp_socks5_resp_read_cb] send 37 bytes data to 8.8.8.8#53 via socks5 2020-03-02 17:19:37 INF: [udp_client_recv_cb] recv 112 bytes data from 8.8.8.8#53 via socks5 2020-03-02 17:19:37 ERR: [udp_client_recv_cb] failed to bind address for udp4 socket: (98) address already in use

iptables

ip rule add fwmark 1 table 100 ip route add local 0.0.0.0/0 dev lo table 100 iptables -t mangle -A PREROUTING -p udp -d 8.8.8.8 --dport 53 -j TPROXY --on-port 1051 --tproxy-mark 0x01/0x01 iptables -t mangle -A OUTPUT -p udp -d 8.8.8.8 --dport 53 -j MARK --set-mark 1

zfl9 commented 4 years ago

路由器上,53端口被占用了。

zfl9 commented 4 years ago

这个是无解的,除非占用这个53端口的进程设置 SO_REUSEADDR。ipt2socks 本身是默认设置了 SO_REUSEADDR,但是这个选项必须要双方都设置才有效: https://github.com/zfl9/ipt2socks/blob/3bc9cef302a5c2e466652bfbdab5f4d1f8990888/netutils.c#L223

zfl9 commented 4 years ago

如果你无法为这个占用53端口的程序设置SO_REUSEADDR,那么可尝试另外一种方式避免:比如使用非53端口的dns-server。

XenMe commented 4 years ago

主要是配合chinadns-ng使用,chinadns监听在53

这样的话,得这样用? chinadns用非标,chinadns到GoogleDNS的请求走ipt2socks?

折腾了一周,有点疑问的是为何ipt2socks会需要使用53端口?

zfl9 commented 4 years ago

有点疑问的是为何ipt2socks会需要使用53端口?

因为tproxy透明代理就是这样,ipt2socks在收到8888:53回复包后将创建一个socket,然后绑定到8888:53地址,“假装”是8.8.8.8:53对chinadns进行回复。这就是透明代理的核心所在。

zfl9 commented 4 years ago

但是你现在遇到的问题是,在绑定到8.8.8.8:53/udp地址的时候,这个地址被其它进程占用了。

zfl9 commented 4 years ago

稍等,我发现问题所在了,你说的是chinadns还是chinadns-ng?

zfl9 commented 4 years ago

如果是chinadns-ng的话,我可以加个选项,启用SO_REUSEADDR的。

XenMe commented 4 years ago

chinadns-ng

zfl9 commented 4 years ago

ok,那我修改一下chinadns-ng,默认开启so_reuseaddr。

XenMe commented 4 years ago

如果是chinadns-ng的话,我可以加个选项,启用SO_REUSEADDR的。

感谢,一路从ss-tproxy折腾过来的。

题外话,ss-tproxy里面看到介绍了ipt2socks,但好像里面没有使用到。所以,无从参考,折腾了很久

zfl9 commented 4 years ago

是的,因为目前ipt2socks有个小问题,会导致进程意外退出。不过我已经开始打算重构了。

好像里面没有使用到。所以,无从参考,折腾了很久

其实用到了,只是不是必用的那种,因为可以直接ss-redir/v2ray之类的提供透明代理。ipt2socks主要是配合socks5代理,以提供tproxy透明代理端口支持的。说白了就是类似 redsocks2

XenMe commented 4 years ago

目前上层协议太多,最近换了Trojan, UDP不支持TPROXY,所有只能用ipt2socks转换一下。

期待重构,再次感谢!

zfl9 commented 4 years ago

更新chinadns-ng,重新编译一下,应该就不会提示端口被占用了

XenMe commented 4 years ago

马上试,感谢!

XenMe commented 4 years ago

替换chinadns-ng之后,其余不需要任何修改就可以了。 意外退出确实较频繁,只能等您重构了。

zfl9 commented 4 years ago

嗯,我尽力。