UWNetworksLab / cordova-plugin-tun2socks

Cordova plugin to enable a system-wide VPN for Android devices.
Apache License 2.0
51 stars 25 forks source link

How to use TCP to communicate. Now most SOCKS use TCP instead of UDP. #21

Open etan96 opened 3 years ago

etan96 commented 3 years ago

How to use TCP to communicate. Now most SOCKS use TCP instead of UDP.

iMrDJAi commented 3 years ago

Same question ^^^ I use a socks proxy node.js library that doesn't seem to support UDP, unfortunately I couldn't find a solution for this.

IMG20210326224910

iMrDJAi commented 3 years ago

Well, I was wrong... Actually we're all wrong, and your question @77193404 is also incorrect. The device traffic itself goes over TCP as normal, the DNS queries are what go over UDP! as mentioned here https://github.com/UWNetworksLab/cordova-plugin-tun2socks/issues/18#issuecomment-299212622.
Since the DNS queries go through UDP and not TCP, you won't get a working internet unless your server can resolve them separately, and it likely cannot.
In this case, you may only connect to servers using IPs, that's why the internet worked in some apps on my device like Facebook lite, Instagram lite, Telegram.. All of these apps connect directly to their servers using IP addresses instead of domain names. By the way, what I'm trying to build is an SSH client, I'm using TUN2SOCKS to forward the device traffic through a SOCKS5 proxy running on localhost and connected to a remote SSH server, I'm using nodejs-mobile-cordova to run a good SOCKS5 library (@sansamour/node-sock) that actually supports UDP associate (see page 7). But, when @alalamav mentioned that the SOCKS proxy server has to support UDP, he didn't mean UDP associate, he meant Shadowsocks UDP relay (Also called UdpGw relay, which means "UDP Gateway". See this comment 5fe4a0c#r109713257 by @trevj), which is a way to resolve DNS queries! It won't be a part of your SOCKS5 proxy, it will be a separate UDP server running on the same port as your proxy (I didn't know that I may run 2 server on the same port before, I was surprised when I discovered that), and that also explains why they didn't gave us a way to specify a different port for it.
So I've created a simple UDP server in javascript to listen to DNS packets:

var udp = require('dgram')
var server = udp.createSocket('udp6')

server.on('error', err => {
  error('Error: ' + err)
  server.close()
})
server.on('message', (msg, info) => {
  log('UDP: ' + msg.toString('hex') + '\n(' + msg.toString() + ')')
})
server.bind(1080, () => {
  log(`UDP server started on port 1080!`)
})

/** output:
UDP: 0000000108080808003517b8010000010000000000000377777706676f6f676c6503636f6d0000010001
(5�wwwgooglecom)
**/

What I'm not sure about is how to handle these packets, I didn't find any resources that may help, hopefully the collaborators may provide me some info in order to parse the buffer and structuring the response to send it back to the client.

iMrDJAi commented 3 years ago

I ended up using the actual UDP associate feature of SOCKS v5, someone made a pull request (https://github.com/UWNetworksLab/cordova-plugin-tun2socks/pull/20) to add support for it.
I have published a working version here:
https://github.com/iMrDJAi/cordova-plugin-tun2socks-udp-associate