xjasonlyu / tun2socks

tun2socks - powered by gVisor TCP/IP stack
https://github.com/xjasonlyu/tun2socks/wiki
GNU General Public License v3.0
3.13k stars 433 forks source link

[Bug] UDP response from the proxy server isn't processed properly #164

Closed Cherser-s closed 1 year ago

Cherser-s commented 2 years ago

Verify steps

Version

2.4.1

What OS are you seeing the problem on?

Linux

Description

UDP relay processes address incorrectly. When testing connection to Google DNS, the client generates the packet with source port 40689 and then relay uses src port 43123 to send the packet to the proxy server. Method ReadFrom within proxy/socks5.go returns the 192.168.100.72:40689 instead of 8.8.8.8:53. I used Microtik built-in socks5 proxy server to test the connection.

The DNS response did go through when I removed this branching snippet: https://github.com/xjasonlyu/tun2socks/blob/main/tunnel/udp.go#L124

CLI or Config

No response

Logs

time="2022-09-14T17:06:54+03:00" level=info msg="[UDP] 192.168.100.72:43123 <-> 8.8.8.8:53"
time="2022-09-14T17:06:54+03:00" level=warning msg="[UDP] symmetric NAT 192.168.100.72:43123->8.8.8.8:53: drop packet from 192.168.100.72:40689"
xjasonlyu commented 2 years ago

It’s expected in symmetric NAT, but I don’t understand why it received local udp packet instead of 8.8.8.8.

Did you try other proxy servers? Mine works fine with querying DNS.

Cherser-s commented 2 years ago

It doesn't receive local UDP packet, it does receive it from 8.8.8.8 (through proxy) The problem is that the IP address inside the encapsulated socks packet is the destination address and not the source one. That happens with any UDP use-case.

Cherser-s commented 2 years ago

Also doesn't RFC 1928 state that the DST address field in the reply from the proxy server should be the real destination which the relay should send the packet to?

xjasonlyu commented 2 years ago

Also doesn't RFC 1928 state that the DST address field in the reply from the proxy server should be the real destination which the relay should send the packet to?

Yes and that’s how it implemented.

Cherser-s commented 2 years ago

Yes and that’s how it implemented.

It isn't? The relay implementation here compares the relay client's src ip and src port (192.168.100.72:40689 for this case) with it's destination address (which then proxy sends the packet to), which will always fail.

Why the from variable here (which in my case was 192.168.100.72:40689) is compared with dst (which in my case is 8.8.8.8:53)?

xjasonlyu commented 2 years ago

Why the from variable here (which in my case was 192.168.100.72:40689) is compared with dst (which in my case is 8.8.8.8:53)?

To make sure that the address is NAT’s destination address.

And I think the code is probably ok because I have tested it many times and didn’t encounter these kind of issues.

Cherser-s commented 2 years ago

Shouldn't pc.src and pc.dst be associated with client's source and destination address in this case instead of client's dst address and the proxy server dst address?

github-actions[bot] commented 1 year ago

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days