1.8.13 • Published 2 years ago

socroxy v1.8.13

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

Socrates

A Secure Web Proxy. Fast, secure, and easy to use.

Socrates extends the native net.createServer, and it acts as a real transparent HTTPS-proxy built on top of TCP-level. It's an real HTTPS proxy, not HTTPS over HTTP. It allows upstream client-request dynamically to other proxies or works as a single layer encrypted proxy. It supports Basic Proxy-Authentication and Token-Baased-Authentication as default.

Try it out

$ npx socrates -h

Install

npm i socrates

Use

const Socrates = require('socrates');

//init Socrates
const server = new Socrates();

//starting server on port 8080
server.listen(8080, '0.0.0.0', function () {
    console.log('TCP-Proxy-Server started!', server.address());
});

Options Object

ParamTypeDescription
optionsObjectThe options object.
options.authFunctionActivate/Handle Proxy-Authentication. Returns or solves to Boolean.
options.upstreamFunctionThe proxy to be used to upstreaming requests. Returns String.
options.tcpOutgoingAddressFunctionThe localAddress to use while sending requests. Returns String
options.injectDataFunctionThe edited data to upstream. Returns Buffer or string
options.injectResponseFunctionThe edited response to return to connected client. Returns Buffer or string
options.keysFunctionThe keys to use while handshake. It will work only if intercept is true. Returns Object or false
options.logLevelNumberDefault 0 to log all messages.
options.interceptBooleanActivate interception of encrypted communications. False as default.

upstream, tcpOutgoingAddress, injectData & injectResponse Options

The options are functions having follow parameters:

ParamTypeDescription
dataBufferThe received data.
sessionSessionObject containing info/data about Tunnel
  • upstream-Function need to return/resolve a String with format -> IP:PORT or USER:PWD@IP:PORT of used http-proxy. If 'localhost' is returned/resolved, then the host-self will be used as proxy.
  • tcpOutgoingAddress-Function need to return a String with format -> IP.

Note: These functions will be executed before first tcp-socket-connection is established.

  • injectData-Function need to return a String or buffer for the new spoofed data. This will be upstreamed as request.
  • injectResponse-Function need to return a String or buffer for the new received data.

Upstream to other proxies

If you don't want to use the host of active instance self, then you need to upstream connections to another http-proxy. This can be done with upstream attribute.

const Socrates = require('socrates');

const server = new Socrates({
    upstream: function () {
          return 'x.x.x.x:3128'; // upstream to other proxy
    }
});

//starting server on port 8080
server.listen(8080, '0.0.0.0', function () {
    console.log('TCP-Proxy-Server started!', server.address());
});

You can also use an async function to upstream your requests:

const Socrates = require('socrates');

const server = new Socrates({
    upstream: async function () {
         //make some async task before
         return 'x.x.x.x:3128'; // upstream to other proxy
    }
});

//starting server on port 8080
server.listen(8080, '0.0.0.0', function () {
    console.log('TCP-Proxy-Server started!', server.address());
});

The auth Function

This activate basic authorization mechanism. The Auth-function will be executed while handling Proxy-Authentications.

ParamTypeDescription
usernameStringThe client username.
passwordStringThe client password
sessionSessionObject containing info/data about Tunnel

Note: It needs to return True/False or a Promise that resolves to boolean (isAuthenticated).

const Socrates = require('socrates');

const server = new Socrates({
    auth: function (username, password) {
        return username === 'bar' && password === 'foo';
    }
});

//starting server on port 8080
server.listen(8080, '0.0.0.0', function () {
    console.log('TCP-Proxy-Server started!', server.address());
});

Interception

The callbacks injectData & injectResponse could be used to intercept/spoof communication. These functions are executed with the data and session arguments.

Intercepting HTTPS

The boolean attribute intercept allows to break SSL-Communication between Source & Destination.

This will activate Security-Alarm by most used browsers.

const uaToSwitch = 'curl/7.55.1';
const switchWith = 'My Super Fucking Spoofed UA!';

const server = new Socrates({
    intercept: true,
    injectData: (data, session) => {
        if (session.isHttps) {
            if (data.toString().match(uaToSwitch)) {
                return Buffer.from(data.toString()
                    .replace(uaToSwitch, switchWith));
            }
        }
        return data;
    }
});
curl -x localhost:8080 -k http://ifconfig.io/ua
curl/7.55.1

curl -x localhost:8080 -k https://ifconfig.me/ua
My Super Fucking Spoofed UA!

The keys Function

This function will work only if intercept is set to true.

If activated needs to return an Object {key:'String', cert:'String'} like native tls_connect_options.key & tls_connect_options.cert or false statement.

If no object is returned, then default keys will be used to update communication.

ParamTypeDescription
sessionSessionObject containing info/data about Tunnel

Note: This function will be executed before TLS-Handshake.

Session-Instance

The Session-Instance is a Object containing info/data about Tunnel. It has following useful attributes/methods:

  • isHttps - Is session encrypted.
  • getTunnelStats() - Get Stats for this tunnel
  • getId() - Get Own ID-Session
  • isAuthenticated() - Is the session authenticated by user or not.

.getConnections()

const Socrates = require('socrates');
const server = new Socrates();

//starting server on port 8080
server.listen(8080, '0.0.0.0', function () {
    console.log('Proxy-Server started!', server.address());
});

setInterval(function showOpenSockets() {
    const connections = server.getConnections();
    console.log([new Date()], 'OPEN =>', Object.keys(connections).length)
}, 2000);

Examples

This example upstreams only requests for ifconfig.me to another proxy, for all other requests will be used localhost.

const Socrates = require('socrates');

const server = new Socrates({
    upstream: function (data, session) {
        if (~(data.toString().indexOf('ifconfig.me'))) {
            return 'x.x.x.x:3128'; // upstream to other proxy
        } else {
            return 'localhost'; //upstream to localhost
        }
    },
});

//starting server on port 8080
server.listen(8080, '0.0.0.0', function () {
    console.log('TCP-Proxy-Server started!', server.address());
});

Testing with curl:

curl -x 127.0.0.1:8080 https://ifconfig.me
x.x.x.x
curl -x 127.0.0.1:8080 https://ifconfig.co
y.y.y.y