Real transparent HTTP-Proxy-Server. Upstream your requests whatever you want!
transparent-proxy extends the native net.createServer and it acts as a real transparent http-proxy.
This module was built on top of TCP-level to avoid header-stripping problem of nodejs http(s)-modules.
It allows to upstream client-request dynamically to other proxies, or to certain iFace, to spoof requests and more...
It supports Basic Proxy-Authentication.
``bash`
npm i transparent-proxy
`javascript
const ProxyServer = require('transparent-proxy');
//init ProxyServer
const server = new ProxyServer();
//starting server on port 8080
server.listen(8080, '0.0.0.0', function () {
console.log('TCP-Proxy-Server started!', server.address());
});
`
| Param | Type | Description |
| ------ | ------------------- | ------------ |
|options | Object | The options object. |
|[options.auth] | Function | Activate/Handle Proxy-Authentication. Returns or solves to Boolean. |
|[options.upstream] | Function | The proxy to be used to upstreaming requests. Returns String. |
|[options.tcpOutgoingAddress] | Function | The localAddress to use while sending requests. Returns String |
|[options.injectData] | Function | The edited data to upstream. Returns Buffer or string |
|[options.injectResponse] | Function | The edited response to return to connected client. Returns Buffer or string |
|[options.keys] | Function | The keys to use while handshake. It will work only if intercept is true. Returns Object or false |
|[options.verbose] | Boolean | Activate verbose mode. |
|[options.intercept] | Boolean | Activate interception of encrypted communications. False as default. |
|[options.logger] | Logger | Must be an object implementing log(args[]) and error(args[]). Defaults to the inbuilt logger writing to the console if verbose is true.|
|[options.handleSni] | Function | Pass SNICallback to be added to the server. See SNICallback tls.createServer options |
, tcpOutgoingAddress, injectData & injectResponse OptionsThe options are functions having follow parameters:
| Param | Type | Description |
| ------ | ------------------- | ------------ |
|data | Buffer | The received data. |
|session | Session | Object 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.IP
- tcpOutgoingAddress-Function need to return a String with format -> .
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.
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.
`javascript
const ProxyServer = require('transparent-proxy');
const server = new ProxyServer({
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:
`javascript
const ProxyServer = require('transparent-proxy');
const server = new ProxyServer({
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());
});
`
FunctionThis activate basic authorization mechanism.
The Auth-function will be executed while handling Proxy-Authentications.
| Param | Type | Description |
| ------ | ------------------- | ------------ |
|username | String | The client username. |
|password | String | The client password |
|session | Session | Object containing info/data about Tunnel |
Note: It needs to return True/False or a Promise that resolves to boolean (isAuthenticated).
`javascript
const ProxyServer = require('transparent-proxy');
const server = new ProxyServer({
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());
});
`
The callbacks injectData & injectResponse could be used to intercept/spoof communication.data
These functions are executed with the 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.
`javascript
const switchWith = 'My Super Spoofed UA!';
const server = new ProxyServer({
intercept: true,
verbose: true,
injectData: (data, session) => {
if (session.isHttps) {
const modifiedData = data.toString()
.replace(session.request.headers['user-agent'], switchWith); //replacing UA-Header-Value
return Buffer.from(modifiedData);
}
return data;
}
});
`
`bash
curl -x localhost:8080 -k http://ifconfig.io/ua
curl/7.83.1
curl -x localhost:8080 -k https://ifconfig.me/ua
My Super Spoofed UA!
`
FunctionThis 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.
| Param | Type | Description |
| ------ | ------------------- | ------------ |
|session | Session | Object containing info/data about Tunnel |
Note: This function will be executed before TLS-Handshake.
FunctionIf passed a function, the proxy will call it to obtain the TLS secure context instead of using keys.
From tls.createServer
Two arguments will be passed when called: servername and callback. callback is an error-first callback that takes two optional arguments: error and ctx. ctx, if provided, is a SecureContext instance. tls.createSecureContext() can be used to get a proper SecureContext. If callback is called with a falsy ctx argument, the default secure context of the server will be used.
#### Session-Instance
The Session-Instance is an Object containing info/data about Tunnel.
It has following useful attributes and methods:
- isHttps - Is session encrypted.
- request - The Request-Object containing info about current request.
- response - The Response-Object containing info about current response.
- getTunnelStats() - Get Stats for this tunnel
- getId() - Get Own ID-Session
- isAuthenticated() - Is the session authenticated by user or not.
`javascript
const ProxyServer = require('transparent-proxy');
const server = new ProxyServer();
//starting server on port 8080
server.listen(8080, '0.0.0.0', function () {
console.log('Proxy-Server started!', server.address());
});
setInterval(function showOpenSockets() {
const bridgedConnections = server.getBridgedConnections();
console.log([new Date()], 'OPEN =>', Object.keys(bridgedConnections).length)
}, 2000);
`
This example upstreams only requests for ifconfig.me to another proxy, for all other requests will be used localhost.
`javascript
const ProxyServer = require('transparent-proxy');
const server = new ProxyServer({
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:
`bash`
curl -x 127.0.0.1:8080 https://ifconfig.me
x.x.x.x`bash``
curl -x 127.0.0.1:8080 https://ifconfig.co
y.y.y.y
For more examples look here.