-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d3e819a
commit 7d68c53
Showing
13 changed files
with
905 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.DS_Store | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
FROM node:8 | ||
|
||
# Create app directory | ||
RUN mkdir -p /usr/src/app | ||
WORKDIR /usr/src/app | ||
|
||
# Install app dependencies | ||
COPY package.json /usr/src/app/ | ||
RUN npm install | ||
|
||
# Bundle app source | ||
COPY . /usr/src/app | ||
|
||
EXPOSE 3000 | ||
CMD [ "node", "bin/server" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The MIT License | ||
|
||
Copyright (c) 2016 Noop Labs LLC http://nooplabs.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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,56 @@ | ||
# nport | ||
# **NPort** | ||
|
||
NPort is a **Node.js-based tool** that tunnels HTTP connections through **Socket.IO** streams, enabling you to expose local servers via public URLs easily and securely. It is particularly useful for **development environments**, testing webhooks, and sharing projects on local servers. | ||
|
||
--- | ||
|
||
## **Features** | ||
|
||
- **HTTP Tunneling**: Expose your local HTTP server to the internet using Socket.IO-based tunnels. | ||
- **Secure and Lightweight**: A minimal, fast, and secure way to share your server without requiring complicated infrastructure. | ||
- **Custom Subdomains**: Access your local server using easy-to-read public URLs. | ||
- **WebSocket Support**: Handles WebSocket connections seamlessly. | ||
- **Cross-Platform**: Works on Linux, macOS, and Windows systems. | ||
|
||
--- | ||
|
||
## **Install** | ||
|
||
```sh | ||
# install nport from npm | ||
|
||
npm i nport # local install | ||
|
||
npm i -g nport # global install | ||
|
||
# alternative: install from github | ||
|
||
npm install git+https://github.com/tuanngocptn/nport.git # local install | ||
|
||
npm install -g git+https://github.com/tuanngocptn/nport.git # global install | ||
``` | ||
|
||
--- | ||
|
||
## **How to use** | ||
|
||
```sh | ||
npx nport -s xxx -p 3000 # https://xxx.nport.link (local install) | ||
|
||
nport -s xxx -p 3000 # https://xxx.nport.link (global install) | ||
``` | ||
**OR** | ||
|
||
```sh | ||
npx nport --server https://nport.link --subdomain xxx --hostname 127.0.0.1 --port 3000 # https://xxx.nport.link (local install) | ||
|
||
nport --server https://nport.link --subdomain xxx --hostname 127.0.0.1 --port 3000 # https://xxx.nport.link (global install) | ||
``` | ||
|
||
# Source from socket-tunnel | ||
|
||
Tunnel HTTP connections via socket.io streams. Inspired by [localtunnel](https://github.com/localtunnel/localtunnel). | ||
|
||
## Blog Post | ||
|
||
[Read all about it](https://ericbarch.com/post/sockettunnel/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#!/usr/bin/env node | ||
const optimist = require('optimist'); | ||
|
||
let argv = optimist | ||
.usage('Usage: $0 --server [string] --subdomain [string] --hostname [string] --port [number]') | ||
.options('se', { | ||
alias: 'server', | ||
default: 'https://nport.link', | ||
describe: 'Tunnel server endpoint' | ||
}) | ||
.options('s', { | ||
alias: 'subdomain', | ||
describe: '(Required) Public URL the tunnel server is forwarding to us' | ||
}) | ||
.options('h', { | ||
alias: 'hostname', | ||
default: '127.0.0.1', | ||
describe: 'Address of local server for forwarding over socket-tunnel' | ||
}) | ||
.options('p', { | ||
alias: 'port', | ||
describe: '(Required) Port of local server for forwarding over socket-tunnel' | ||
}) | ||
.argv; | ||
|
||
if (argv.help) { | ||
optimist.showHelp(); | ||
process.exit(); | ||
} | ||
|
||
if (!argv['server'] || !argv['subdomain'] || !argv['port']) { | ||
for (var key in ['server', 'subdomain', 'port']) { | ||
if (argv[key]) continue; | ||
|
||
console.log('Error: Required option, but nothing found'); | ||
|
||
optimist.showHelp(); | ||
|
||
process.exit(); | ||
} | ||
} | ||
|
||
require('../client.js')(argv); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#!/usr/bin/env node | ||
var optimist = require('optimist'); | ||
|
||
var argv = optimist | ||
.usage('Usage: $0 --hostname [string] --port [number] --subdomain [string]') | ||
.options('h', { | ||
alias: 'hostname', | ||
default: '0.0.0.0', | ||
describe: 'Accept connections on this hostname' | ||
}) | ||
.options('p', { | ||
alias: 'port', | ||
default: 3000, | ||
describe: 'Server daemon port' | ||
}) | ||
.options('s', { | ||
alias: 'subdomain', | ||
default: '', | ||
describe: 'Name of subdomain used. Required when server listens on a subdomain (leave blank otherwise)' | ||
}) | ||
.argv; | ||
|
||
if (argv.help) { | ||
optimist.showHelp(); | ||
process.exit(); | ||
} | ||
|
||
require('../server.js')(argv); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
'use strict'; | ||
|
||
const IDLE_SOCKET_TIMEOUT_MILLISECONDS = 1000 * 30; | ||
|
||
module.exports = (options) => { | ||
return new Promise((resolve, reject) => { | ||
// require the things we need | ||
const net = require('net'); | ||
const ss = require('socket.io-stream'); | ||
let socket = require('socket.io-client')(options['server']); | ||
|
||
socket.on('connect', () => { | ||
console.log(new Date() + ': connected'); | ||
console.log(new Date() + ': requesting subdomain ' + options['subdomain'] + ' via ' + options['server']); | ||
|
||
socket.emit('createTunnel', options['subdomain'], (err) => { | ||
if (err) { | ||
console.log(new Date() + ': [error] ' + err); | ||
|
||
reject(err); | ||
} else { | ||
console.log(new Date() + ': registered with server successfully'); | ||
console.log(new Date() + ': your domain is: https://' + options['subdomain'] + '.nport.link'); | ||
|
||
// clean and concat requested url | ||
let url; | ||
let subdomain = options['subdomain'].toString(); | ||
let server = options['server'].toString(); | ||
|
||
if (server.includes('https://')) { | ||
url = `https://${subdomain}.${server.slice(8)}`; | ||
} else if (server.includes('http://')) { | ||
url = `http://${subdomain}.${server.slice(7)}`; | ||
} else { | ||
url = `https://${subdomain}.${server}`; | ||
} | ||
|
||
// resolve promise with requested URL | ||
resolve(url); | ||
} | ||
}); | ||
}); | ||
|
||
socket.on('incomingClient', (clientId) => { | ||
let client = net.connect(options['port'], options['hostname'], () => { | ||
let s = ss.createStream(); | ||
s.pipe(client).pipe(s); | ||
|
||
s.on('end', () => { | ||
client.destroy(); | ||
}); | ||
|
||
ss(socket).emit(clientId, s); | ||
}); | ||
|
||
client.setTimeout(IDLE_SOCKET_TIMEOUT_MILLISECONDS); | ||
client.on('timeout', () => { | ||
client.end(); | ||
}); | ||
|
||
client.on('error', () => { | ||
// handle connection refusal (create a stream and immediately close it) | ||
let s = ss.createStream(); | ||
ss(socket).emit(clientId, s); | ||
s.end(); | ||
}); | ||
}); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
const socketTunnel = require('../lib/api'); | ||
|
||
socketTunnel.connect('https://domain.example', 'deviceSubdomain', '2222') | ||
.then((url) => { | ||
console.log(url); | ||
}) | ||
.catch((err) => { | ||
console.error(err); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// client api | ||
const client = require('../client'); | ||
|
||
let api = { | ||
connect: (server, subdomain, port, hostname = '127.0.0.1') => { | ||
if (!server || !subdomain || !port || !hostname) { | ||
return Promise.reject(new Error('One or more options were not provided')); | ||
} | ||
|
||
let options = { | ||
server: server, | ||
subdomain: subdomain.toString(), | ||
port: port.toString(), | ||
hostname: hostname | ||
}; | ||
|
||
// client returns a promise | ||
return client(options); | ||
} | ||
}; | ||
|
||
module.exports = api; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Example of nginx config for proxying requests to socket-tunnel server | ||
|
||
server { | ||
listen *:80; | ||
server_name subdomain.example.com *.subdomain.example.com; | ||
rewrite ^ https://$host$request_uri? permanent; | ||
} | ||
|
||
server { | ||
listen *:443; | ||
|
||
server_name subdomain.example.com *.subdomain.example.com; | ||
|
||
ssl on; | ||
ssl_certificate /path/to/certificate/file.crt; | ||
ssl_certificate_key /path/to/key/file.key; | ||
ssl_prefer_server_ciphers on; | ||
|
||
location / { | ||
proxy_pass http://127.0.0.1:3000/; | ||
|
||
proxy_set_header X-Real-IP $remote_addr; | ||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
proxy_set_header Host $http_host; | ||
proxy_http_version 1.1; | ||
proxy_set_header X-Forwarded-Proto https; | ||
proxy_set_header X-NginX-Proxy true; | ||
proxy_set_header Upgrade $http_upgrade; | ||
proxy_set_header Connection 'upgrade'; | ||
|
||
proxy_redirect off; | ||
} | ||
} |
Oops, something went wrong.