mirror of
https://git.coolaj86.com/coolaj86/sclient.js
synced 2025-02-22 15:58:04 +00:00
v1.0.0: initial release
This commit is contained in:
commit
5779325061
41
LICENSE
Normal file
41
LICENSE
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
Copyright 2018 AJ ONeal
|
||||||
|
|
||||||
|
This is open source software; you can redistribute it and/or modify it under the
|
||||||
|
terms of either:
|
||||||
|
|
||||||
|
a) the "MIT License"
|
||||||
|
b) the "Apache-2.0 License"
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Apache-2.0 License Summary
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
70
README.md
Normal file
70
README.md
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
sclient.js
|
||||||
|
==========
|
||||||
|
|
||||||
|
Secure Client for exposing TLS (aka SSL) secured services as plain-text connections locally.
|
||||||
|
|
||||||
|
Also ideal for multiplexing a single port with multiple protocols using SNI.
|
||||||
|
|
||||||
|
Unwrap a TLS connection
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ sclient whatever.com:443 localhost:3000
|
||||||
|
> [listening] telebit.cloud:443 <= localhost:3000
|
||||||
|
```
|
||||||
|
|
||||||
|
Connect via Telnet
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ telnet localhost 3000
|
||||||
|
```
|
||||||
|
|
||||||
|
Connect via netcat (nc)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ nc telnet localhost 3000
|
||||||
|
```
|
||||||
|
|
||||||
|
Install
|
||||||
|
=======
|
||||||
|
|
||||||
|
### macOS, Linux, Windows
|
||||||
|
|
||||||
|
First download and install the *current* version of [node.js](https://nodejs.org)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install -g sclient
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx sclient example.com:443 localhost:3000
|
||||||
|
```
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sclient <remote> <local> [-k | --insecure]
|
||||||
|
```
|
||||||
|
|
||||||
|
* remote
|
||||||
|
* must have servername (i.e. example.com)
|
||||||
|
* port is optional (default is 443)
|
||||||
|
* local
|
||||||
|
* address is optional (default is localhost)
|
||||||
|
* must have port (i.e. 3000)
|
||||||
|
|
||||||
|
Examples
|
||||||
|
========
|
||||||
|
|
||||||
|
Bridge between `telebit.cloud` and
|
||||||
|
```bash
|
||||||
|
sclient telebit.cloud 3000
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sclient telebit.cloud:443 localhost:3000
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sclient badtls.telebit.cloud:443 localhost:3000 -k
|
||||||
|
```
|
57
bin/sclient.js
Executable file
57
bin/sclient.js
Executable file
@ -0,0 +1,57 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var pkg = require('../package.json');
|
||||||
|
var remote = (process.argv[2]||'').split(':');
|
||||||
|
var local = (process.argv[3]||'').split(':');
|
||||||
|
var localAddress;
|
||||||
|
var localPort;
|
||||||
|
var rejectUnauthorized;
|
||||||
|
|
||||||
|
function usage() {
|
||||||
|
console.info("");
|
||||||
|
console.info("sclient.js v" + pkg.version);
|
||||||
|
console.info("Usage: sclient <servername:port> <port> [-k | --insecure]");
|
||||||
|
console.info(" ex: sclient whatever.com 3000");
|
||||||
|
console.info(" (whatever.com:443 localhost:3000)");
|
||||||
|
console.info(" ex: sclient whatever.com:4080 0.0.0.0:3000");
|
||||||
|
console.info("");
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!remote[0]) {
|
||||||
|
usage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!remote[1]) {
|
||||||
|
remote[1] = 443;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!local[0]) {
|
||||||
|
usage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (local[0] === String(parseInt(local[0], 10))) {
|
||||||
|
localPort = parseInt(local[0], 10);
|
||||||
|
localAddress = 'localhost';
|
||||||
|
} else {
|
||||||
|
localAddress = local[0];
|
||||||
|
localPort = parseInt(local[1], 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!localPort) {
|
||||||
|
usage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/^-k|--insecure$/.test(process.argv[4])) {
|
||||||
|
rejectUnauthorized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var opts = {
|
||||||
|
remoteAddr: remote[0]
|
||||||
|
, remotePort: remote[1]
|
||||||
|
, localAddress: localAddress
|
||||||
|
, localPort: localPort
|
||||||
|
, rejectUnauthorized: rejectUnauthorized
|
||||||
|
};
|
||||||
|
require('../')(opts);
|
51
index.js
Normal file
51
index.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var net = require('net');
|
||||||
|
var tls = require('tls');
|
||||||
|
|
||||||
|
function listenForConns(opts) {
|
||||||
|
var server = net.createServer(function (c) {
|
||||||
|
var sclient = tls.connect({
|
||||||
|
servername: opts.remoteAddr, host: opts.remoteAddr, port: opts.remotePort
|
||||||
|
, rejectUnauthorized: opts.rejectUnauthorized
|
||||||
|
}, function () {
|
||||||
|
console.info('[connect] ' + sclient.localAddress.replace('::1', 'localhost') + ":" + sclient.localPort
|
||||||
|
+ " => " + opts.remoteAddr + ":" + opts.remotePort);
|
||||||
|
c.pipe(sclient);
|
||||||
|
sclient.pipe(c);
|
||||||
|
});
|
||||||
|
sclient.on('error', function (err) {
|
||||||
|
console.error('[error] (remote) ' + err.toString());
|
||||||
|
});
|
||||||
|
c.on('error', function (err) {
|
||||||
|
console.error('[error] (local) ' + err.toString());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
server.on('error', function (err) {
|
||||||
|
console.error('[error] ' + err.toString());
|
||||||
|
});
|
||||||
|
server.listen({
|
||||||
|
host: opts.localAddress
|
||||||
|
, port: opts.localPort
|
||||||
|
}, function () {
|
||||||
|
console.info('[listening] ' + opts.remoteAddr + ":" + opts.remotePort
|
||||||
|
+ " <= " + opts.localAddress + ":" + opts.localPort);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testConn(opts) {
|
||||||
|
// Test connection first
|
||||||
|
var tlsSock = tls.connect({
|
||||||
|
servername: opts.remoteAddr, host: opts.remoteAddr, port: opts.remotePort
|
||||||
|
, rejectUnauthorized: opts.rejectUnauthorized
|
||||||
|
}, function () {
|
||||||
|
tlsSock.end();
|
||||||
|
listenForConns(opts);
|
||||||
|
});
|
||||||
|
tlsSock.on('error', function (err) {
|
||||||
|
console.warn("[warn] '" + opts.remoteAddr + ":" + opts.remotePort + "' may not be accepting connections: ", err.toString(), '\n');
|
||||||
|
listenForConns(opts);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = testConn;
|
28
package.json
Normal file
28
package.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "sclient",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Secure Client for exposing TLS (aka SSL) secured services as plain-text connections locally. Also ideal for multiplexing a single port with multiple protocols using SNI.",
|
||||||
|
"main": "index.js",
|
||||||
|
"bin": {
|
||||||
|
"sclient": "bin/sclient.js"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"bin",
|
||||||
|
"lib"
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.coolaj86.com/coolaj86/sclient.js.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"stunnel",
|
||||||
|
"s_client",
|
||||||
|
"telebit",
|
||||||
|
"openssl"
|
||||||
|
],
|
||||||
|
"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)",
|
||||||
|
"license": "(MIT OR Apache-2.0)"
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user