A forwarder/redirector server inspired in WinRelay
npm install noderelay







Author: Ivan Garavito
This is an app that forwards/redirects data as-is to the servers defined. This helps you to:
* Hide your real server address for security reasons.
* Separate networks between clients and services.
* Serve data from an isolated network by redirecting only the services you need.
1. Install Node.js. Optionally, you can use node-install
2. Install [NodeRelay][] with NPM:
`` bash`
ૐ » ~ λ npm install -g NodeRelay`
or if you need root permissions: bash`
ૐ » ~ λ sudo npm install -g NodeRelay
Let's say you have a fixed HTTP service at 127.0.0.1:3000, and you want to access using port 80. All you need to doconfig/local.json5
is create the file and write the following lines:
` json5`
{
localHost: '0.0.0.0',
pool: [
{
localPort: 80
rdirHost: '127.0.0.1',
rdirPort: 3000
}
]
}
After [NodeRelay][] configuration is ready, simply run the app:
` bash`
$ cd /path/to/NodeRelay
$ node .
First of all, let's define the terminology used into this app.
* service, is the server where you want to redirect.local
* , is here, where [NodeRelay][] is installed and redirecting.client
* , is the host connecting to local and redirected to service.localserver
* or server, is the server needed at local to get client connection and redirect it to service.
Well documented, the default options are stored inside config/default.json5 file, and the user defined configurationconfig/local.json5
is inside the file, which can be reduced to something like the following:
` json5`
{
localHost: '127.0.0.1',
pool: [
{
localPort:
serverHost: '
serverPort:
}
]
}
localHost defines the IP address where [NodeRelay][] is going to be listening to.
pool is the port list where is defined for each local port to which server to redirect to:
* localPort is the port at the local host to listen to new connections.serverHost
* is the server's address to redirect to.serverPort
* is the port at the server to redirect to.
Let's say you have two servers within a LAN network isolated from your Internet connection. These servers have a HTTP
service for UI purposes, then the UI connects to a fixed port 3000 (and you cannot change it) for polling data.
How you can make [NodeRelay][] connect dynamically to that fixed port at the proper server?
Well, it's as easy as defining a local port with no server connection params at the pool. Your local.json5 file should
look like this:
` json5``
{
localHost: 'my_isp_assing_ip',
pool: [
{ //DEVICE 1
localPort: 81,
serverHost: '192.168.1.101',
serverPort: 80
},
{ //DEVICE 2
localPort: 82,
serverHost: '192.168.1.102',
serverPort: 80
},
{ //FIXED PORT FOR DYNAMIC FORWARDING/REDIRECTION
localPort: 3000
}
]
}
* NodeRelay
* ~LocalServer ⇐ external:EventEmitter
* new LocalServer(options)
* _instance_
* .close()
* ._connectService(clientSocket, options)
* .getDynamicServiceHost(Client) ⇒ string
* .init(options)
* ._onConnection(client)
* .start()
* "event:close"
* "event:error" (err)
* "event:listening" (server)
* "event:client-close" (had_error, client)
* "event:client-connection" (had_error, localPort, clientAddress)
* "event:service-close" (had_error, service)
* "event:service-error" (err)
* "event:service-redirection" (localPort, client, service)
* "event:service-redirection-dynamic" (localPort, client, service)
* "event:service-redirection-fixed" (localPort, client, service)
* _static_
* .errors : enum
* .getSocketRemoteParams(socket) ⇒ Object
Kind: inner class of NodeRelay
Extends: external:EventEmitter
Emits: event:close, event:error, event:listening, event:client-close, event:client-connection, event:service-close, event:service-error, event:service-redirection, event:service-redirection-dynamic, event:service-redirection-fixed
* ~LocalServer ⇐ external:EventEmitter
* new LocalServer(options)
* _instance_
* .close()
* ._connectService(clientSocket, options)
* .getDynamicServiceHost(Client) ⇒ string
* .init(options)
* ._onConnection(client)
* .start()
* "event:close"
* "event:error" (err)
* "event:listening" (server)
* "event:client-close" (had_error, client)
* "event:client-connection" (had_error, localPort, clientAddress)
* "event:service-close" (had_error, service)
* "event:service-error" (err)
* "event:service-redirection" (localPort, client, service)
* "event:service-redirection-dynamic" (localPort, client, service)
* "event:service-redirection-fixed" (localPort, client, service)
* _static_
* .errors : enum
* .getSocketRemoteParams(socket) ⇒ Object
#### new LocalServer(options)
| Param | Type | Description |
| --- | --- | --- |
| options | Object | local and service options |
#### localServer.close()
Stop local server from accepting new connections
Kind: instance method of LocalServer
#### localServer._connectService(clientSocket, options)
Connect to service and make client-service redirection
Kind: instance method of LocalServer
| Param | Type | Description |
| --- | --- | --- |
| clientSocket | Socket | Client socket |
| options | Object | Connection options to service |
| options.host | string | Address where is the service |
| options.port | string | TCP port at options.host where is the service |
#### localServer.getDynamicServiceHost(Client) ⇒ string
Initializes the LocalServer instance
Kind: instance method of LocalServer
Returns: string - Service address when this is a local server for a dynamic redirection
Throws:
- UserError The app instancing this class must override this method
| Param | Type | Description |
| --- | --- | --- |
| Client | string | IP address |
#### localServer.init(options)
Initializes the LocalServer instance
Kind: instance method of LocalServer
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| options | Object | | local and service options |
| [options.localHost] | string | "localhost" | IP address to listen to at local |
| options.localPort | string | | TCP port to listen to at localHost |
| [options.serviceHost] | string | "options.localHost" | Address where is the service |
| [options.servicePort] | string | "options.localPort" | TCP port at serviceHost where is the service |
| [options.listenRetryTimes] | number | 1 | Retry times to get the local server up |
| [options.listenRetryTimeout] | number | 500 | Time in milliseconds to wait before next listen try |
| [options.connRetryTimes] | number | 1 | Retry times to connect to service |
| [options.connRetryTimeout] | number | 500 | Time in milliseconds to wait before next connection try |
#### localServer._onConnection(client)
Client connection handler
Kind: instance method of LocalServer
| Param | Type | Description |
| --- | --- | --- |
| client | Socket | Client connection socket |
#### localServer.start()
Start local server listening
Kind: instance method of LocalServer
#### "event:close"
Server close event
Kind: event emitted by LocalServer
#### "event:error" (err)
Server error event
Kind: event emitted by LocalServer
| Param | Type | Description |
| --- | --- | --- |
| err | Error | The error from local server |
#### "event:listening" (server)
Server listening event
Kind: event emitted by LocalServer
| Param | Type | Description |
| --- | --- | --- |
| server | LocalServer | Server listening |
#### "event:client-close" (had_error, client)
Client close event
Kind: event emitted by LocalServer
| Param | Type | Description |
| --- | --- | --- |
| had_error | boolean | |
| client | Object | Details of client connection |
| client.port | number | Client port |
| client.family | string | Client socket family |
| client.address | string | Client address |
#### "event:client-connection" (had_error, localPort, clientAddress)
Client connection event
Kind: event emitted by LocalServer
| Param | Type | Description |
| --- | --- | --- |
| had_error | boolean | |
| localPort | number | Server port at local |
| clientAddress | string | Client IP address |
#### "event:service-close" (had_error, service)
Service connection closed event
Kind: event emitted by LocalServer
| Param | Type | Description |
| --- | --- | --- |
| had_error | boolean | |
| service | Object | Details of service connection |
| service.port | number | Service port |
| service.family | string | Service socket family |
| service.address | string | Service address |
#### "event:service-error" (err)
Connection to service failed event
Kind: event emitted by LocalServer
| Param | Type |
| --- | --- |
| err | Error |
#### "event:service-redirection" (localPort, client, service)
Client redirected to service event
Kind: event emitted by LocalServer
| Param | Type | Description |
| --- | --- | --- |
| localPort | number | Server port at local |
| client | Socket | Client connection socket |
| service | Socket | Service connection socket |
#### "event:service-redirection-dynamic" (localPort, client, service)
Client redirected to a dynamic service event
Kind: event emitted by LocalServer
| Param | Type | Description |
| --- | --- | --- |
| localPort | number | Server port at local |
| client | Socket | Client connection socket |
| service | Socket | Service connection socket |
#### "event:service-redirection-fixed" (localPort, client, service)
Client redirected to a fixed service event
Kind: event emitted by LocalServer
| Param | Type | Description |
| --- | --- | --- |
| localPort | number | Server port at local |
| client | Socket | Client connection socket |
| service | Socket | Service connection socket |
#### LocalServer.errors : enum
LocalServer error definitions
Kind: static enum property of LocalServer
Read only: true
Properties
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| ENOLOCALPORT | UserError | | No local port defined |
| ENOSERVICEPORT | UserError | | No service port defined |
| ESAMESERVICEANDLOCAL | UserError | | Service and local are the same |
| EUNTRACKEDCLIENT | UserError | | Untracked client |
| EDYNAMICSERVICE | UserError | | getDynamicServiceHost must be implemented by the app |
#### LocalServer.getSocketRemoteParams(socket) ⇒ Object
Returns and object with remote port, family and address
Kind: static method of LocalServer
Returns: Object - Object with remote port, family and address
| Param | Type |
| --- | --- |
| socket | Socket |
* log
* _static_
* .levels : enum
* _inner_
* ~info(...args)
* ~error(...args)
* ~debug(...args)
* ~connection(...args)
Kind: static enum property of log
Read only: true
Properties
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| Info | number | 1 | Info messages |
| Error | number | 2 | Error messages |
| Debug | number | 4 | Debug messages |
| Connection | number | 16 | Connection messages |
| DataEvent | number | 32 | DataEvent messages. |
| IncomingData | number | 64 | IncomingData messages |
| OutcomingData | number | 128 | OutcomingData messages |
log | Param | Type | Description |
| --- | --- | --- |
| ...args | \* | The arguments to log |
log | Param | Type | Description |
| --- | --- | --- |
| ...args | \* | The arguments to log |
log | Param | Type | Description |
| --- | --- | --- |
| ...args | \* | The arguments to log |
log | Param | Type | Description |
| --- | --- | --- |
| ...args | \* | The arguments to log |
* tracker
* ~getDynamicServiceHost(clientAddress) ⇒ string | undefined
* ~getRedirections() ⇒ Object
* ~getServers() ⇒ Object
* ~trackClient(localPort, clientAddress)
* ~trackRedirection(localPort, clientSocket, serviceSocket)
* ~trackServer(server) ⇒ LocalServer
* ~untrackRedirection(id)
tracker string | undefined - Service address to redirect to or undefined when it's an untracked client | Param | Type | Description |
| --- | --- | --- |
| clientAddress | string | The client IP address |
Kind: inner method of tracker
Returns: Object - The redirection collection
Kind: inner method of tracker
Returns: Object - The server collection
Kind: inner method of tracker
| Param | Type | Description |
| --- | --- | --- |
| localPort | number | The local server port |
| clientAddress | string | The client IP address |
tracker | Param | Type | Description |
| --- | --- | --- |
| localPort | number | The local server port |
| clientSocket | Socket | The client socket connection |
| serviceSocket | Socket | The service socket connection |
Kind: inner method of tracker
Returns: LocalServer - The server param
| Param | Type | Description |
| --- | --- | --- |
| server | LocalServer | The local server |
tracker | Param | Type | Description |
| --- | --- | --- |
| id | string | The redirection id to remove |
(The MIT License)
Copyright (c) 2016 Ivan Garavito <ivangaravito@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
[NodeRelay]: https://github.com/IvanGaravito/NodeRelay