Clash: 1.9通过TPROXY转发UDP好像不成功

Created on 2 Apr 2020  ·  19Comments  ·  Source: Dreamacro/clash

config里设置了
Proxy:
Proxy:

  • {,"type":"vmess",,"udp":true}

iptables:
ip route add local 0.0.0.i0/0 dev lo table 100
ip rule add fwmark 1 table 100
iptables -t mangle -N CLSUDP
iptables -t mangle -A CLSUDP -d 0.0.0.0/8 -j RETURN
iptables -t mangle -A CLSUDP -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A CLSUDP -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A CLSUDP -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A CLSUDP -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A CLSUDP -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A CLSUDP -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A CLSUDP -d 240.0.0.0/4 -j RETURN
iptables -t mangle -A CLSUDP -p udp -j TPROXY --on-port 7892 --tproxy-mark 0x01/0x01

在其他机器上运行
dig @8.8.8.8 google.com 显示timeout

在log里只有一条
[info] [UDP] 192.168.2.252:46020 --> 8.8.8.8 match IPCIDR using HKProxy[中港IPLC(01)]

Most helpful comment

[warning] [UDP] handleUDPToLocal error: address already in use

有程序(比如 clash 自己)bind 到 0.0.0.0:53 或者 :::53 且没有设置 SO_REUSEADDR,导致 WriteBack 的时候无法 bind 到 8.8.8.8:53

https://github.com/v2ray/v2ray-core/issues/1971 相似

All 19 comments

我测试可以的。
你ip route add local 0.0.0.i0/0 dev lo table 100这句有点点错误。

我测试可以的。
你ip route add local 0.0.0.i0/0 dev lo table 100这句有点点错误。

那个i是打错了,实际没有的,你可以共享下你的iptables的设置吗,谢谢

似乎也是一样的问题

配置如下:

proxies:

  • name: HK
    type: trojan
    server: ----.com
    port: 443
    password: -------
    udp: true

ip route add local default dev lo table 100
ip rule add fwmark 1 lookup 100
iptables -t mangle -N CLASH
iptables -t mangle -A CLASH -d 0.0.0.0/8 -j RETURN
iptables -t mangle -A CLASH -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A CLASH -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A CLASH -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A CLASH -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A CLASH -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A CLASH -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A CLASH -d 240.0.0.0/4 -j RETURN
iptables -t mangle -A CLASH -p udp -j TPROXY --on-port 7892 --tproxy-mark 0x01/0x01
iptables -t mangle -A PREROUTING -p udp -j CLASH

现象:

dig @1.1.1.1 google.com

; <<>> DiG 9.10.6 <<>> @1.1.1.1 google.com
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached

clash使用root运行或者给CAP_NET_BIND_SERVICE权限

同样测试了tproxy,最新clash会看到能建立一个udp连接,但测试支持udp的游戏,游戏会直接报错连接失败,然后只将iptables udp tproxy 规则改为ss-redir运行的端口,则游戏无任何问题

在笔记本和 openwrt 路由器上均无法复现

日志中出现了 UDP 说明 clash 收到了包,TPROXY 的配置应该没问题。有条件的话可以打个 patch:

diff --git a/tunnel/connection.go b/tunnel/connection.go
index 9553ed7..370cdab 100644
--- a/tunnel/connection.go
+++ b/tunnel/connection.go
@@ -12,6 +12,7 @@ import (
        C "github.com/Dreamacro/clash/constant"

        "github.com/Dreamacro/clash/common/pool"
+       "github.com/Dreamacro/clash/log"
 )

 func handleHTTP(request *adapters.HTTPAdapter, outbound net.Conn) {
@@ -83,6 +84,7 @@ func handleHTTP(request *adapters.HTTPAdapter, outbound net.Conn) {

 func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata) {
        if _, err := pc.WriteWithMetadata(packet.Data(), metadata); err != nil {
+               log.Warnln("[UDP] handleUDPToRemote error: %s", err.Error())
                return
        }
        DefaultManager.Upload() <- int64(len(packet.Data()))
@@ -107,6 +109,7 @@ func handleUDPToLocal(packet C.UDPPacket, pc net.PacketConn, key string, fAddr n

                n, err = packet.WriteBack(buf[:n], from)
                if err != nil {
+                       log.Warnln("[UDP] handleUDPToLocal error: %s", err.Error())
                        return
                }
                DefaultManager.Download() <- int64(n)

编译运行,dig 之后看看日志中有没有 warning

在笔记本和 openwrt 路由器上均无法复现

日志中出现了 UDP 说明 clash 收到了包,TPROXY 的配置应该没问题。有条件的话可以打个 patch:

diff --git a/tunnel/connection.go b/tunnel/connection.go
index 9553ed7..370cdab 100644
--- a/tunnel/connection.go
+++ b/tunnel/connection.go
@@ -12,6 +12,7 @@ import (
        C "github.com/Dreamacro/clash/constant"

        "github.com/Dreamacro/clash/common/pool"
+       "github.com/Dreamacro/clash/log"
 )

 func handleHTTP(request *adapters.HTTPAdapter, outbound net.Conn) {
@@ -83,6 +84,7 @@ func handleHTTP(request *adapters.HTTPAdapter, outbound net.Conn) {

 func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata) {
        if _, err := pc.WriteWithMetadata(packet.Data(), metadata); err != nil {
+               log.Warnln("[UDP] handleUDPToRemote error: %s", err.Error())
                return
        }
        DefaultManager.Upload() <- int64(len(packet.Data()))
@@ -107,6 +109,7 @@ func handleUDPToLocal(packet C.UDPPacket, pc net.PacketConn, key string, fAddr n

                n, err = packet.WriteBack(buf[:n], from)
                if err != nil {
+                       log.Warnln("[UDP] handleUDPToLocal error: %s", err.Error())
                        return
                }
                DefaultManager.Download() <- int64(n)

编译运行,dig 之后看看日志中有没有 warning

可以通过以下方法复现
使用非root账户启动clash,给CAP_NET_ADMIN权限,但是不给CAP_NET_BIND_SERVICE权限
在其他机器上将网关设置为clash的ip,然后dig 一个域名
此时clash的日志中会出现一条UDP请求,但是connect里面不会有,如果远端是v2的话会看到提示客户端关闭了连接。

愿意帮忙 debug 的话,可以用 https://github.com/duament/clash/releases/tag/debug ,dig 之后看看日志中有没有 warning

@CyberKoo 必须要有 CAP_NET_BIND_SERVICE 或者 root,否则 clash WriteBack 的时候无法 bind 低于 1024 的端口。
dig @208.67.222.222 www.google.com -p 5353 不需要这个权限。

愿意帮忙 debug 的话,可以用 https://github.com/duament/clash/releases/tag/debug ,dig 之后看看日志中有没有 warning

有warning,显示的是
[warning] [UDP] handleUDPToLocal error: address already in use

[warning] [UDP] handleUDPToLocal error: address already in use

有程序(比如 clash 自己)bind 到 0.0.0.0:53 或者 :::53 且没有设置 SO_REUSEADDR,导致 WriteBack 的时候无法 bind 到 8.8.8.8:53

https://github.com/v2ray/v2ray-core/issues/1971 相似

[warning] [UDP] handleUDPToLocal error: address already in use

有程序(比如 clash 自己)bind 到 0.0.0.0:53 或者 :::53 且没有设置 SO_REUSEADDR,导致 WriteBack 的时候无法 bind 到 8.8.8.8:53

v2ray/v2ray-core#1971 相似

本身clash的DNS服务是bind到0.0.0.0:53的,想请问下,如何设置SO_REUSEADDR

@trott90 要改代码,等一等

@trott90 试试 https://github.com/duament/clash/releases/tag/udp-reuseaddr

dig bing.com @1.1.1.1 返回正常了!

@trott90 试试 https://github.com/duament/clash/releases/tag/udp-reuseaddr

我这里也测试成功了, 非常感谢

fix in #630

请问是否支持使用TPROXY转发TCP呢,我采用与UDP相同的做法,在日志却看不见任何TCP信息

请问是否支持使用TPROXY转发TCP呢,我采用与UDP相同的做法,在日志却看不见任何TCP信息

https://lancellc.gitbook.io/clash/start-clash/clash-udp-tproxy-support#step-2-add-rules-in-iptable-linux-only

前半段就是iptables设置TCP转发的

Was this page helpful?
0 / 5 - 0 ratings