semigodking / redsocks

transparent redirector of any TCP/UDP connection to proxy
Apache License 2.0
1.16k stars 246 forks source link

TPROXY UDP relay doesn't work #196

Closed ge9 closed 6 months ago

ge9 commented 6 months ago

Hi,

I'm trying to send all UDP packet via socks5 proxy. As a socks5 proxy, I'm using https://www.inet.no/dante/. This supports UDP associate protocol. On Windows, with Proxifyre, I did succeed in proxying all UDP traffic (to arbitrary destination). So I'm expecting this is also possible in Linux, with redsocks. Since applying TPROXY to OUTPUT packet (generated in the computer where redsocks is running) seems to be another complex problem, I'm currently testing with a separate client computer. In my settings, redsocks is running at 192.168.1.212 and the client computer is 192.168.1.90. Socks5 server is running at 192.168.1.12:3129. First, I made a route table according to documents on TPROXY.

sudo ip rule add from 192.168.1.90 lookup 100 sudo ip route add local default dev lo table 100

iptables commands are following: sudo iptables -t mangle -A PREROUTING -p udp -s 192.168.1.90 --dport 3478:3479 -j TPROXY --on-ip 127.0.0.1 --on-port 22224 sudo iptables -t mangle -A PREROUTING -p tcp -s 192.168.1.90 --dport 3478:3479 -j TPROXY --on-ip 127.0.0.1 --on-port 22222

I limited dest port to 3478-3479 because I'm testing with STUN client (https://www.stunprotocol.org/).

My redsocks.conf:

base {
    log_info = on;
    log_debug = on;
    log = stderr;
    daemon = off;
    redirector = iptables;
}
redsocks {
    bind = "127.0.0.1:22222";

    relay = "192.168.1.12:3129";

    type = socks5;
}
redudp {
    bind = "127.0.0.1:22224";

    relay = "192.168.1.12:3129";
    type = socks5;
    udp_timeout = 2;
}

I specified 127.0.0.1 (not 0.0.0.0) because of https://github.com/semigodking/redsocks/issues/194, but the result is just the same as when I specified 0.0.0.0 .

ip_forward is enabled.

Then, things are working perfectly for TCP, but not for UDP. According to redsocks's debug log and tcpdump, redsocks detects the given UDP packet and sends some TCP packet to 192.168.1.12:3129 (socks5 server), but there are no UDP packets going between 192.168.1.212 and 192.168.1.12.

This is a example log output from redsocks.

1710515472.638047 debug socks5-udp.c:389 socks5_relay_connected(...) [192.168.1.90:44537->3.132.228.249:3478]: via 192.168.1.12:3129
1710515472.656912 debug socks5-udp.c:344 socks5_read_auth_methods(...) [192.168.1.90:44537->3.132.228.249:3478]: <trace>
1710515472.660098 debug socks5-udp.c:233 socks5_read_assoc_reply(...) [192.168.1.90:44537->3.132.228.249:3478]: <trace>
1710515472.660215 debug redudp.c:350 redudp_flush_queue(...) [192.168.1.90:44537->3.132.228.249:3478]: Starting UDP relay
1710515474.632908 debug redudp.c:363 redudp_timeout(...) [192.168.1.90:44537->3.132.228.249:3478]: Client timeout. First: 1710515472, last_client: 1710515472, last_relay: 0.
1710515474.632957 debug redudp.c:254 redudp_drop_client(...) [192.168.1.90:44537->3.132.228.249:3478]: Dropping client @ state: 0

It says Client timeout. (I set the timeout to 2 seconds).

Any helps are appreciated.

ge9 commented 6 months ago

Now I figured it out. In my settings, the socks5 server was available at 192.168.1.12 (with help of a DNAT rule), but it was not binded to 192.168.1.12. Socks5's UDP associate protocol seems to notify its local ip, and it was unavailable from 192.168.1.212. I changed the socks5 server-side configuration to make local ip and external ip match, and then everything worked perfectly.