twitchax / rusty_socks

A super basic SOCKS5 proxy.
MIT License
4 stars 1 forks source link

Support for UDP ASSOCIATE #2

Open martinvonwittich opened 3 years ago

martinvonwittich commented 3 years ago

I tried to use Deluge with nordvpn-proxy, but unfortunately I didn't get very far:

2020-12-01 23:42:20,558 ERROR [rusty_socks::connection] UDP ASSOCIATE requests not supported.

Apparently Deluge uses UDP for DHT and uTP. Would it be possible to implement this?

twitchax commented 3 years ago

Honestly, I had planned on adding UDP ASSOCIATE support at some point, but I didn't have any good test cases. Do you know of any test applications I could use other than Deluge?

martinvonwittich commented 3 years ago

Honestly, I had planned on adding UDP ASSOCIATE support at some point, but I didn't have any good test cases. Do you know of any test applications I could use other than Deluge?

Hm, I thought, "why not send a simple DNS query with netcat?". But it turns out that while netcat supports SOCKS5 proxying, it doesn't actually support SOCKS5 UDP proxying :D

echo -n -e "\x13\x37\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x13google-public-dns-a\x06google\x03com\x00\x00\x01\x00\x01" | nc -x localhost:1080 -X 5 -u -w1 8.8.8.8 53 | xxd                                
nc: no proxy support for UDP mode

A viable workaround might be to use socksify (provided by the package dante-client on Ubuntu):

martin@martin ~ % echo -n -e "\x13\x37\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x13google-public-dns-a\x06google\x03com\x00\x00\x01\x00\x01" | SOCKS_LOGOUTPUT=stdout SOCKS5_SERVER=localhost:1080 socksify nc -u -w1 8.8.8.8 53
Dec  2 14:14:48 (1606914888.896580) nc[24556]: info: Dante/client v1.4.2 running
Dec  2 14:14:48 (1606914888.896886) nc[24556]: info: Rconnect(): fd 3, address 8.8.8.8.53
Dec  2 14:14:48 (1606914888.896950) nc[24556]: info: socks_requestpolish(): searching for direct route for udpassociate, protocol udp, src 0.0.0.0.0, dst 8.8.8.8.53, authmethod -1
Dec  2 14:14:48 (1606914888.897068) nc[24556]: info: socks_connectroute(): have socks_v5 route (route #1) to 8.8.8.8.53 via localhost.1080
Dec  2 14:14:48 (1606914888.897092) nc[24556]: info: socks_connecthost(): connect to localhost.1080 on <N/A> side from 0.0.0.0.0, fd 4.  Timeout is -1
Dec  2 14:14:48 (1606914888.897203) nc[24556]: info: socks_connecthost(): connect to 127.0.0.1.1080 on <N/A> side from 0.0.0.0.0, fd 4.  Timeout is -1
Dec  2 14:14:48 (1606914888.897305) nc[24556]: info: socks_connecthost(): connect to 127.0.0.1.1080 from 127.0.0.1.47640 on fd 4 ok (no system error)
Dec  2 14:14:48 (1606914888.897378) nc[24556]: info: socks_negotiate(): initiating socks_v5 negotiation with control-fd 4 (laddr: 127.0.0.1.47640, raddr: 127.0.0.1.1080, protocol: tcp), data-fd 3 (laddr: 127.0.0.1.52845, raddr: N/A, protocol: udp), req.host = 127.0.0.1.52845
Dec  2 14:14:48 (1606914888.897397) nc[24556]: info: negotiate_method(): offering proxy server #2 methods: none, username
Dec  2 14:14:48 (1606914888.897796) nc[24556]: info: negotiate_method(): proxy server selected method none
Dec  2 14:14:48 (1606914888.897806) nc[24556]: info: negotiate_method(): established v5 connection using method 0
Dec  2 14:14:48 (1606914888.897815) nc[24556]: info: socks_sendrequest(): sending request to server: VER: 5 CMD: 3 FLAG: 0 ATYP: 1 address: 127.0.0.1.52845
Dec  2 14:14:48 (1606914888.897997) nc[24556]: info: socks_blacklist(): blacklisting route #1.  Reason: premature eof from proxy server while waiting for response
Dec  2 14:14:48 (1606914888.898101) nc[24556]: warning: udpsetup(): socks_negotiate() failed: premature eof from proxy server while waiting for response
Dec  2 14:14:48 (1606914888.898114) nc[24556]: info: Rconnect(): udpsetup() returned no route to 8.8.8.8.53 for fd 3: premature eof from proxy server while waiting for response

I'm getting UDP ASSOCIATE requests not supported. from rusty_socks, so far, so good.

To ensure that this actually would work when the proxy supports UDP ASSOCIATE, I tested it against danted (provided by the package dante-server on Ubuntu):

martin@martin ~ % echo -n -e "\x13\x37\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x13google-public-dns-a\x06google\x03com\x00\x00\x01\x00\x01" | SOCKS5_SERVER=localhost:1081 socksify nc -u -w1 8.8.8.8 53 | xxd
00000000: 1337 8180 0001 0001 0000 0000 1367 6f6f  .7...........goo
00000010: 676c 652d 7075 626c 6963 2d64 6e73 2d61  gle-public-dns-a
00000020: 0667 6f6f 676c 6503 636f 6d00 0001 0001  .google.com.....
00000030: c00c 0001 0001 0000 53c0 0004 0808 0808  ........S.......

It kinda works, but for some reason it hangs until nc is killed by the 1 second timeout of -w1 :/

danted was painful to get to work; if you want to reproduce this, this was the config that I came up with:

martin@martin ~ % grep -vE '^(#|$)' /etc/danted.conf
logoutput: stderr
debug: 1
internal: lo port = 1081
external: eno1
socksmethod: none
user.privileged: proxy
user.unprivileged: nobody
user.libwrap: nobody
client pass {
  from: 127.0.0.0/8 port 1-65535 to: 0.0.0.0/0
}
socks pass {
  from: 127.0.0.0/8 to: 0.0.0.0/0
  command: bind connect udpassociate
}
socks pass {
  from: 0.0.0.0/0 to: 127.0.0.0/8
  command: bindreply udpreply
}

Replace eno1 with the interface that points to your gateway.