Detalhes do pacote

simple-socks

brozeph10.1kMIT3.1.0

proxies requests

socks, socks5, socksv5, rfc 1928

readme (leia-me)

Simple Socks Server

Creates a simple SOCKS5 server and exposes additional SOCKS5 proxy events.

Build Status

Installation

npm install simple-socks

Example Usage

In the examples folder exists two examples, one that requires no authentication and one that requires username/password authentication. Below is an example with no authentication:

import socks5 from 'simple-socks'

const server = socks5.createServer().listen(1080);

// When a reqest arrives for a remote destination
server.on('proxyConnect', (info, destination) => {
  console.log('connected to remote server at %s:%d', info.address, info.port);

  destination.on('data', (data) => {
    console.log(data.length);
  });
});

// When data arrives from the remote connection
server.on('proxyData', (data) => {
  console.log(data.length);
});

// When an error occurs connecting to remote destination
server.on('proxyError', (err) => {
  console.error('unable to connect to remote server');
  console.error(err);
});

// When a request for a remote destination ends
server.on('proxyDisconnect', (originInfo, destinationInfo, hadError) => {
  console.log(
    'client %s:%d request has disconnected from remote server at %s:%d with %serror',
    originInfo.address,
    originInfo.port,
    destinationInfo.address,
    destinationInfo.port,
    hadError ? '' : 'no ');
});

// When a proxy connection ends
server.on('proxyEnd', (response, args) => {
  console.log('socket closed with code %d', response);
  console.log(args);
});

Running The Examples

No Authentication

For a SOCKS5 server that does not require authentication, look at examples/createServer.js:

node examples/createServer

In a separate terminal window:

curl http://www.google.com --socks5 127.0.0.1:1080

Username/Password Authentication

For a SOCKS5 server that requires username/password authentication, look at examples/createServerWithAuthentication.js:

node examples/createServerWithAuthentication

In a separate terminal window:

curl http://www.google.com --socks5 127.0.0.1:1080 --proxy-user foo:bar

Connection Filter

For a SOCKS5 server that can perform either origin or destination (or both!) address filtering, look at examples/createServerConnectionFilter.js:

node examples/createServerConnectionFilter

In a separate terminal window:

curl http://www.github.com --socks5 127.0.0.1:1080 # allowed
curl http://www.google.com --socks5 127.0.0.1:1080 # denied

Methods

createServer

Factory method that creates an instance of a SOCKS5 proxy server:

import socks5 from 'simple-socks';

const server = socks5.createServer();

server.listen(1080, '0.0.0.0', function () {
  console.log('SOCKS5 proxy server started on 0.0.0.0:1080');
});

This method accepts an optional options argument:

  • options.authentication - A callback for authentication
  • options.connectionFilter - A callback for connection filtering

authentication

To make the socks5 server require username/password authentication, supply a function callback in the options as follows:

import socks5 from 'simple-socks';

const options = {
  authenticate : function (username, password, socket, callback) {
    if (username === 'foo' && password === 'bar') {
      return setImmediate(callback);
    }

    return setImmediate(callback, new Error('incorrect username and password'));
  }
};

const server = socks5.createServer(options);

// begin listening and require user/pass authentication
server.listen(1080);

The authenticate callback accepts three arguments:

  • username - username of the proxy user
  • password - password of the proxy user
  • socket - the socket for the client connection
  • callback - callback for authentication... if authentication is successful, the callback should be called with no arguments

connectionFilter

Allows you to filter incoming connections, based on either origin and/or destination, return false to disallow:

import socks5 from 'simple-socks';

const server = socks5.createServer({
  connectionFilter : function (destination, origin, callback) {
    if (origin.address === '127.0.0.1') {
      console.log('denying access from %s:%s', origin.address, origin.port);

      return setImmediate(callback, new Error('access from specified origin is denied'));
    }

    if (destination.address === '10.0.0.1') {
      console.log('denying access to %s:%s', remote.address, remote.port);

      return setImmediate(callback, new Error('access to specified destination is denied'));
    }

    return setImmediate(callback);
  }
});

The connectionFilter callback accepts three arguments:

  • destination - an information object containing details for destination connection
    • address - the TCP address of the remote server
    • port - the TCP port of the remote server
  • origin - an information object containing details for origin connection
    • address - the TCP address of the origin (client) connection
    • port - the TCP port of the origin (client) connection
  • callback - callback for destination and/or origin address validation... if connections are allowed to the destination address, the callback should be called with no arguments

For an example, see examples/createServerConnectionFilter.js.

Events

The socks5 server supports all events that exist on a native net.Server object. Additionally, the following events have been added that are specific to the SOCKS5 proxy:

  • handshake - The first event fired and it occurs when a new SOCKS5 client proxy negotiation occurs
  • authenticate - When username/password authentication is configured (see above), this event is fired when a successful authentication occurs
  • authenticateError - When username/password authentication is configured, this event is fired when authentication fails
  • connectionFilter - When a destination address is denied by the configured connection filter callback, this event is fired
  • proxyConnect - After handshake and optional authentication, this event is emitted upon successful connection with the remote destination
  • proxyError - If connection to the remote destination fails, this event is emitted
  • proxyDisconnect - If a successful proxyConnect occurs, this event is emitted when the remote destination ends the connection
  • proxyData - When data is recieved from the remote destination, this event is fired
  • proxyEnd - This event is emitted when the SOCKS5 client connection is closed for any reason

Note:

This module exports the above events as constants for convenience purposes via the property events:

console.log(socks5.events);

Outputs the following:

{ AUTHENTICATION: 'authenticate',
  AUTHENTICATION_ERROR: 'authenticateError',
  CONNECTION_FILTER: 'connectionFilter',
  HANDSHAKE: 'handshake',
  PROXY_CONNECT: 'proxyConnect',
  PROXY_DATA: 'proxyData',
  PROXY_DISCONNECT: 'proxyDisconnect',
  PROXY_END: 'proxyEnd',
  PROXY_ERROR: 'proxyError' }

handshake

This is event is emitted when a socks5 client connects to the server. The callback accepts a single argument:

// When a new request is initiated
server.on('handshake', function (socket) {
  console.log('new socks5 client from %s:%d', socket.remoteAddress, socket.remotePort);
});

authenticate

This event is emitted when successful authentication occurs. The callback accepts a single argument:

  • username - the username of the successfully authenticated SOCKS5 proxy user
// When authentication succeeds
server.on('authenticate', function (username) {
  console.log('user %s successfully authenticated!', username);
});

authenticateError

This event is emitted when authentication is not successful. The callback accepts the following arguments:

  • username - the username of the SOCKS5 proxy user
  • err - the error returned to the options.authenticate callback
// When authentication fails
server.on('authenticateError', function (username, err) {
  console.log('user %s failed to authenticate...', username);
  console.error(err);
});

connectionFilter

This event is emitted when a destination address and port is filtered by the connectionFilter callback. The callback accepts the following arguments:

  • destination - an information object containing details for destination connection
    • address - the TCP address of the remote server
    • port - the TCP port of the remote server
  • origin - an information object containing details for origin connection
    • address - the TCP address of the origin (client) connection
    • port - the TCP port of the origin (client) connection
  • err - the error returned to the options.connectionFilter callback
// When a destination connection is filtered
server.on('connectionFilter', function (port, address, err) {
  console.log('connection to %s:%s has been denied', address, port);
  console.error(err);
});

proxyConnect

This event is emitted each time a connection is requested to a remote destination. The callback accepts two arguments:

  • info - object with two fields
    • address - the TCP address of the remote (destination) server
    • port - the TCP port of the remote (destination) server
  • destination - the destination TCP net.Socket
// When a reqest arrives for a remote destination
server.on('proxyConnect', function (info, destination) {
  console.log('connected to remote server at %s:%d', info.address, info.port);
});

proxyData

This event is emitted each time a remote connection returns data:

// When a reqest arrives for a remote destination
server.on('proxyData', function (data) {
  console.log('data received from remote destination: %d', data.length);
});

Note: This can also be accomplished by listening to the data event on the destination connection received in the proxyConnect event:

// When a reqest arrives for a remote destination
server.on('proxyConnect', function (info, destination) {
  destination.on('data', function (data) {
    console.log('data received from remote destination: %d', data.length);
  });
});

proxyDisconnect

This event is emitted after a proxyConnect when a connection to a remote destination has ended. The callback accepts three arguments:

  • originInfo - object with two fields
    • address - the TCP address of the origin of the request
    • port - the TCP port of the origin of the request
  • destinationInfo - object with two fields
    • address - the TCP address of the remote (destination) server
    • port the TCP port of the remote (destination) server
  • hadError - a Boolean indicating if a transmission error occurred after connecting with the remote (destination) server
// When a request for a remote destination ends
server.on('proxyDisconnect', function (err) {
  console.log(
    'client %s:%d request has disconnected from remote server at %s:%d with %serror',
    originInfo.address,
    originInfo.port,
    destinationInfo.address,
    destinationInfo.port,
    hadError ? '' : 'no ');
});

proxyError

In the event that a network error occurs attempting to create communication with the destination, this event is raised.

// When an error occurs connecting to remote destination
server.on('proxyError', function (err) {
  console.error('unable to connect to remote server');
  console.error(err);
});

proxyEnd

When a socket connection is closed by the server, the proxyEnd event is emitted. It returns two arguments in the callback:

  • response - the specific RFC 1928 documented response code
  • args - RFC 1928 fields for the proxy request including
    • ver
    • cmd
    • atype
    • dst.addr
    • dst.port
// When a proxy connection ends
server.on('proxyEnd', function (response, args) {
  console.log('socket closed with code %d', response);
  console.log(args);
});

changelog (log de mudanças)

v3.1.0 - 2022/08/08

  • Fixed RFC version constant (fix by @e9x)
  • Updated dependencies

v3.0.1 - 2022/07/18

  • Fixed bug where src folder was not properly referenced in package.json file

v3.0.0 - 2022/07/04

  • Removed Babel dependencies
  • Switched from Travis CI to Github Actions

v2.2.2 - 2022/01/29

  • Fixed issue with ipv6 (fix by @Lanius-collaris)
  • Updated dependencies
  • Realized we should have waited until Wednesday the 2nd to launch this release

v2.2.1 - 2021/04/05

  • Updated dependencies

    v2.2.0 - 2020/03/19

  • Updated dependencies and moved to corejs 3

v2.1.0 - 2020/09/28

  • Removed dependency on put
  • Added proxyDisconnect event
  • Updated dependencies

v2.0.1 - 2020/03/12

  • Removed put from package.json

v2.0.0 - 2020/03/11

  • Changed functionality for connectionFilter so that both the origin and the destination can be filtered
  • Moved to @babel/cli from babel-cli as a dev-dependency
  • Removed dependency on put and replaced with native Buffer

v1.0.4 - 2020/03/11

  • Updated dependencies

v1.0.3 - 2019/08/17

  • Updated dependencies

v1.0.2 - 2019/01/12

  • Fixed issue where IPv6 clients were failing

v1.0.1 - 2019/01/11

  • Tightened up the .eslintrc.yml file for a few additional tests

v1.0.0 - 2019/01/10

  • Added babel for transpile
  • Fixed (node:17070) [DEP0005] DeprecationWarning: Buffer() is deprecated warning at runtime
  • Moved to eslint instead of jshint
  • Refactored constants for cleaner code
  • Updated node.js dependencies for Travis-CI

v0.3.0 - 2018/04/25

  • Added connectionFilter option to provide ability to filter destination addresses (thanks to @slava-vishnyakov for implementation and @jfowl for review and advice)

v0.2.7 - 2017/06/16

  • Modifed the authentication callback to return a socket based on pull-request from @dgramop

v0.2.6 - 2017/03/06

  • Fixed issue in support for ipv6 (thanks to @fabiensk)

v0.2.5 - 2016/12/02

  • Added ability to run multiple instances of the server at once (thank you to @pronskiy)
  • Moved events to a constant that is exported via the module
  • Updated tested versions of Node in Travis configuration

v0.2.4 - 2015/04/09

  • Ensuring any errors that emit from the underlying socket are surfaced to the proxy server

v0.2.3 - 2015/04/05

  • Fixing issue where unhandled exception bubbles from authentication

v0.2.2 - 2015/01/15

  • Merge pull request to resolve error with active session tracking

v0.2.1 - 2015/01/15

  • Fixing bug present when tracking active sessions

v0.2.0 - 2015/01/13

  • Added support for USERNAME/PASSWORD authentication (RFC 1929)
  • Added event proxyData to TCP server object returned from createServer method
  • Modified interface for proxyConnect event to also return the remote socket connection
  • Updated documentation

v0.1.0 - 2015/01/12

  • Initial release of server