mscdex / socksv5

SOCKS protocol version 5 server and client implementations for node.js
MIT License
400 stars 121 forks source link

Is there any way to choose which public IP of the VPS to use as an outgoing address? #53

Closed erickythierry closed 5 months ago

erickythierry commented 5 months ago

I have some public IPs on my VPS, and I would like to use all of them randomly as outgoing addresses with this socks proxy. Is there any way to do this with this project?

mscdex commented 5 months ago

Either configure your OS to do so or explicitly handle all incoming new connections by creating a new outbound connection, connecting using whatever local address you want to bind to, and then pipe between the incoming connection and the outbound connection.

erickythierry commented 5 months ago

sorry to reopen the issue. but I found another lib that can do this at the code level, but the proxy is http.

With this code example I can define which VPS IP I want to use as an output, and it worked.

import * as http from 'http';
import { createProxy } from 'proxy';

const server = http.createServer();
const proxyServer = createProxy(server);

proxyServer.localAddress = '127.0.0.1'; // here I put one of the vps public IPs

proxyServer.listen(8080, () => {
  const port = proxyServer.address().port;
  console.log('Servidor proxy HTTP(s) ouvindo na porta %d', port);
});

this is the lib: https://www.npmjs.com/package/proxy

I analyzed it a little and saw that it works by modifying the localAddress when it receives the request

Could you at least give me a direction to follow to be able to adapt this same operation in your socks5 lib?

I need a rotating socks5 proxy in my project that I'm developing and this one would serve me very well if it had this capability.

I can try to add this function to your project if you tell me where I could try, and if I succeed, I'll send you the PR.

thank you for your attention

mscdex commented 5 months ago

Like I said, you have at least two options:

  1. Handle it at the OS level
  2. For every incoming SOCKS connection, manually handle the request and create an outbound TCP connection using whatever local address you want and then pipe between the two. There is an example of intercepting connections and manually handling them in the README.
erickythierry commented 5 months ago

Like I said, you have at least two options:

  1. Handle it at the OS level
  2. For every incoming SOCKS connection, manually handle the request and create an outbound TCP connection using whatever local address you want and then pipe between the two. There is an example of intercepting connections and manually handling them in the README.

Thank you for the tip, I tried to make a code using your tip and reading the readme.

I came to this:

import socks from 'socksv5';
import net from 'net'

const ips = ['2603:c021:xxxxxxx', '2603:c021xxxxxxxx1']

var srv = socks.createServer(function (info, accept, deny) {

   console.log(info)

   const randomIPv6 = ips[Math.floor(Math.random() * ips.length)];
   const outboundOptions = {
     host: info.dstAddr,
     port: info.dstPort,
     localAddress: randomIPv6, 
   };
   const outboundSocket = net.connect(outboundOptions);

   outboundSocket.on('connect', function () {
     accept(outboundSocket);
   });

   outboundSocket.on('error', function (err) {
     console.error('Error on outgoing connection:', err);
     deny();
   });

});

srv.listen(1080, '::', function () {
   console.log('SOCKS server listening on port 1080');
});

srv.useAuth(socks.auth.None());

However, the proxy does not respond, but it appears that the request hits the proxy.

Could you tell me how to complete this code? 😅

mscdex commented 5 months ago

You have to pipe between the streams. accept(outboundSocket) is not valid.