How to use openvpn in nodejs? - node.js

I have NodeJS App and want to start use OpenVPN connection in it.
To do that I found 2 modules on npm (openvpn-client and openvpn-bin) - but any of them has no good docs and examples, but I try as I can to use them and it was unsuccessful.
I have Ipvanish account (login/password) with 540 .opvn files, which I can use. I try this:
var openvpnmanager = require('node-openvpn');
var openvpnBin = require('openvpn-bin');
var path = require('path');
var filePath = path.normalize('../geo/ipvanish/ipvanish-AU-Sydney-syd-a16.ovpn');
var opts = {
host: 'syd-a16.ipvanish.com', // normally '127.0.0.1', will default to if undefined
port: 443, //port openvpn management console
timeout: 60000, //timeout for connection - optional, will default to 1500ms if undefined
config: filePath
};
var auth = {
user: 'email#gmail.com',
pass: 'password'
};
var openvpn = openvpnmanager.connect(opts)
openvpn.on('connected', function() {
// will be emited on successful interfacing with openvpn instance
console.log('connected')
openvpnmanager.authorize(auth).then(function(res){
});
});

I use this, more effective way (with it I can handle OpenVPN connection as child process, close and reconnect on the fly).
var exec = require('child_process').exec;
var psTree = require('ps-tree');
var kill = function (pid, signal, callback) {
signal = signal || 'SIGKILL';
callback = callback || function () {};
var killTree = true;
if(killTree) {
psTree(pid, function (err, children) {
[pid].concat(
children.map(function (p) {
return p.PID;
})
).forEach(function (tpid) {
try { process.kill(tpid, signal) }
catch (ex) { }
});
callback();
});
} else {
try { process.kill(pid, signal) }
catch (ex) { }
callback();
}
};
var ovpnProcess = null;
if(ovpnProcess != null){
console.log('close connection');
var isWin = /^win/.test(ovpnProcess.platform);
if(!isWin) {
kill(ovpnProcess.pid);
} else {
var cp = require('child_process');
cp.exec('taskkill /PID ' + ovpnProcess.pid + ' /T /F', function (error, stdout, stderr) {
// more debug if you need
// console.log('stdout: ' + stdout);
// console.log('stderr: ' + stderr);
// if(error !== null) {
// console.log('exec error: ' + error);
// }
});
}
}
// to open connection I use this code:
ovpnProcess = exec('openvpn ipvanish/'+account.ip+'.ovpn');
ovpnProcess.stdout.on('data', function(data) {
console.log('stdout: ' + data);
});
ovpnProcess.stderr.on('data', function(data) {
console.log('stdout: ' + data);
});
ovpnProcess.on('close', function(code) {
console.log('closing code: ' + code);
});

you can get help from https://www.npmjs.com/package/node-openvpn or OpenVPN with node, How it works?.

Related

Node.js net socket

I'm using the net module to create a listener but I've experienced some issues. I'm trying to make it wait till it's done writing the "text" to the client before the client can type again. If I'm not doing this and I hold in enter it'll just make you able to write enters between text leading to weird formatting etc.
So how could I make it wait till it's written to the client?
Code:
const net = require('net');
const server = new net.Server();
server.on('connection', async function (socket) {
console.log("Client connected!");
socket.on('data', async function (data) {
socket.setEncoding('utf8');
let input = data.toString().replace(/(\r\n|\n|\r)/gm, "");
if (input == "echo")
socket.write("$ ");
else
socket.write("invalid command");
});
});
server.listen(1337, function() {
console.log("listening");
});
Picture:
https://imgur.com/a/lc21Y13
Edit:
This is on localhost, let's say I'd host it on a server so there's a higher ping it's way worse.
Edit:
Here a picture from when it's hosted on a server:
https://imgur.com/a/LIKRRr9
Edit:
I've tried using SSH instead of telnet and raw and got basically the same result now.
Picture:
https://imgur.com/a/XJmpGSa
Code:
var fs = require('fs');
var username = null;
var ssh2 = require('ssh2');
new ssh2.Server({
hostKeys: [fs.readFileSync('ssh.key')]
}, function (client) {
console.log('Client connected!');
client.on('authentication', function (ctx) {
if (ctx.method !== 'password') return ctx.reject(['password']);
if (ctx.method === 'password') {
username = ctx.username;
console.log(username);
console.log(ctx.password);
ctx.accept();
}
else {
console.log("rejected.");
ctx.reject();
}
}).on('ready', function () {
console.log('Client authenticated!');
client.on('session', function (accept, reject) {
var session = accept();
session.once('shell', function (accept, reject, info) {
var stream = accept();
stream.write("$ ");
stream.on('data', function (data) {
var args = data.toString().split(" ");
console.log(args);
switch (args[0]) {
case "echo":
args.shift();
stream.write(args.join(" ") + "\r\n");
break;
case "whoami":
stream.write(username + "\r\n");
break;
case "exit":
stream.exit(0);
stream.end();
stream = undefined;
break;
default:
stream.stderr.write(args[0] + ": No such command!\r\n");
break;
}
if (typeof stream != 'undefined') {
stream.write("$ ");
}
});
});
});
}).on('end', function () {
console.log('Client disconnected');
});
}).listen(1337, function () {
console.log('Listening on port ' + this.address().port);
});
Try This. What this code does is simply buffering until \n enter is received from a client.
const net = require("net");
const readline = require("readline");
const execCommand = (command, args, socket) => {
return new Promise((res, rej) => {
setTimeout(() => {
// to clear the terminal
socket.write("\u001B[2J\u001B[0;0f");
socket.write(
`Executed command: ${command} with args: ${args} and result was: ${Math.random()}`
);
socket.write('\n>')
res();
}, 3000);
});
};
const server = net.createServer((socket) => {
socket.write("Connected");
// nice prompt
socket.write("\n>");
const rl = readline.createInterface({
input: socket,
output: socket,
});
rl.on("line", (line) => {
if (line.length === 0) {
socket.write("No command to execute!");
socket.write('\n>')
return;
}
// destructuring command and args
// E.g. command arg1 arg2 ....
const [command, ...args] = line.split(" ");
execCommand(command, args, socket);
});
});
server.listen(1337, "127.0.0.1");

How to access the electron process from another npm process?

I am made a script that opens a tcp server and listens for incoming requests and then creates a windows notification. Here is the code:
const notifier = require('node-notifier');
const path = require('path');
const net = require('net');
const port = 7070;
const host = '';
const server = net.createServer();
server.listen(port, host, () => {
console.log('TCP Server is running on port ' + port + '.');
});
let sockets = [];
server.on('connection', function(sock) {
console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
sockets.push(sock);
sock.on('data', function(data) {
var tryCatch = true;
try {
JSON.parse(data);
} catch (err) {
tryCatch = err;
}
if (tryCatch == true) {
var JSONdata = JSON.parse(data);
if (JSONdata["action"] == "notification") {
notifier.notify({
title: 'Recived Message',
message: JSONdata["message"],
icon: path.join(__dirname, 'icon.png'),
actions: ["OK", "Abbrechen"]
},
(err, data) => {
console.log('Waited');
console.log(JSON.stringify({ err, data }));
sock.write(JSON.stringify({ err, data }));
sock.write('\r');
sock.destroy();
}
);
} else if (JSONdata["action"] == "closeServer") {
sock.destroy();
server.close();
}
} else {
sock.write(tryCatch.message);
sock.destroy();
}
});
// Add a 'close' event handler to this instance of socket
sock.on('close', function(data) {
let index = sockets.findIndex(function(o) {
return o.remoteAddress === sock.remoteAddress && o.remotePort === sock.remotePort;
})
if (index !== -1) sockets.splice(index, 1);
console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
// server.close();
});
});
That script works without a problem. Now i want to connect it with my electron app. I want to access the electron app from this npm process to for example open a page. But i don't know how to access the electron process from outside and by outside i mean from another npm process. Hope someone could help me or point me in the right direction. I am thankful for every answer or info.
Simple to say. I didnt find a solution on how to access another proccess but instead you can just vorbidd or intercept and interrupt if the user tries to open another window. Then you can instead spawn your own window and use the ipcMain and ipcRender modules to send smth to the requried window.

Truncated Output from Nodejs ssh2-exec

Can someone please help me understand why the ssh command output is getting truncated when using result[ip] = data.toString(); but not console.log(data.toString());? I only get the first 50 bytes or so for the object assignment, but console.log gets everything. The reason I'm using Promise/await is because I'm planning to eventually have this reach out to several hosts simultaneously and get the results using Promise.all before moving on.
#!/usr/local/bin/node
var fs = require('fs');
var ssh_client = require('ssh2').Client;
var ssh_config = {
port: 22,
username: 'username',
password: 'password',
readyTimeout: 5000 };
var cmd = 'find /home/username -type f -iname "*.txt"';
async function main() {
let ip = '10.10.10.110';
let result = await sshExec(ip);
console.log(result[ip]);
}
function sshExec(ip) {
return new Promise(function(resolve, reject) {
let ssh = new ssh_client();
let config = Object.assign(ssh_config, {'host': ip});
let result = {};
ssh.connect(config);
ssh.on('ready', function() {
console.log("Connected to " + ip + ".");
ssh.exec(cmd, function(err, stream) {
if (err) throw err;
stream.on('data', function(data) {
//console.log(data.toString());
result[ip] = data.toString();
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
}).on('close', function(code, signal) {
ssh.end();
});
});
});
ssh.on('error', function(e) {
console.log(ip + ', connection failed, ' + e.message);
});
ssh.on('close', function(hadError) {
if (!hadError) {
console.log('Connection to ' + ip + ' closed without errors.');
resolve(result);
}
else {
console.log('Connection to ' + ip + ' closed with errors.');
reject(result.ip = 'failure');
}
});
});
}
main();

node.js - connect listner is not getting executed in tcp server

I am trying to build a tcp chat server with following code -
var net = require("net");
Array.prototype.remove = function(e) {
for (var i = 0; i < this.length; i++) {
if (e == this[i]) { return this.splice(i, 1); }
}
};
function Client(stream) {
this.name = null;
this.stream = stream;
}
var clients = [];
var server = net.createServer(function (stream) {
var client = new Client(stream);
clients.push(client);
stream.setTimeout(0);
stream.setEncoding("utf8");
stream.addListener("connect", function () {
stream.write("Welcome, enter your username:\n");
});
stream.addListener("data", function (data) {
if (client.name == null) {
client.name = data.match(/\S+/);
stream.write("===========\n");
clients.forEach(function(c) {
if (c != client) {
c.stream.write(client.name + " has joined.\n");
}
});
return;
}
var command = data.match(/^\/(.*)/);
if (command) {
if (command[1] == 'users') {
clients.forEach(function(c) {
stream.write("- " + c.name + "\n");
});
}
else if (command[1] == 'quit') {
stream.end();
}
return;
}
clients.forEach(function(c) {
if (c != client) {
c.stream.write(client.name + ": " + data);
}
});
});
stream.addListener("end", function() {
clients.remove(client);
clients.forEach(function(c) {
c.stream.write(client.name + " has left.\n");
});
stream.end();
});
});
server.listen(7000);
But whenever I am trying to connect to this tcp server with
nc localhost 7000
or
telnet localhost 7000
connect block is not getting executed.
stream.addListener("connect", function () {
stream.write("Welcome, enter your username:\n");
});
I have also tried to connect to this tcp server with small iOS code but but no luck.
Any idea when/how this connect block will get executed?
Note: I am new to node.js and using mac os x.
First of all it should be connection event.
The function passed to createServer becomes the event handler for the 'connection' event.
var server = net.createServer(function (stream) {
//if you are here you are already connected
});
If you want to listen for connection event do it like this -
var server = net.createServer(function (stream) {
//your code
});
server.addListener("connection", function () {
console.log("connected");
});

running nodejs from cli gives error ENOTFOUND

Below is my nodejs script. All of a sudden running it with: sudo NODE_ENV=test node server.js gives:
info - socket.io started
{ [Error: getaddrinfo ENOTFOUND]
code: 'ENOTFOUND',
errno: 'ENOTFOUND',
syscall: 'getaddrinfo',
fatal: true
}
What can I do to debug ?
var iniparser = require('iniparser');
var config = iniparser.parseSync('../Config/init/db.ini');
var env = process.env.NODE_ENV || 'dev'; //startup nodejs with e.g: NODE_ENV=test forever start server.js
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
fs = require('fs'),
mysql = require('mysql'),
connectionsArray = [],
connection = mysql.createConnection({
host: config[env]['host'],
user: config[env]['user'],
password: config[env]['pwd'].replace(/"/g, ''),
database: config[env]['dbname']
}),
POLLING_INTERVAL = 1000,
pollingTimer;
// If there is an error connecting to the database
connection.connect(function (err) {
// connected! (unless `err` is set)
console.log(err);
});
// creating the server ( localhost:8000 )
app.listen(1443);
// on server started we can load our client.html page
function handler(req, res) {
fs.readFile(__dirname + '/client.html', function (err, data) {
if (err) {
console.log(err);
res.writeHead(500);
return res.end('Error loading client.html');
}
res.writeHead(200);
res.end(data);
});
}
/*
*
* HERE IT IS THE COOL PART
* This function loops on itself since there are sockets connected to the page
* sending the result of the database query after a constant interval
*
*/
var pollingLoop = function () {
// Doing the database query ap.line_state != 0 means busy
var query = connection.query('SELECT p.id, ap.* FROM active_player ap LEFT JOIN player p ON ap.dossier_id=p.dossier_id '),
players = []; // this array will contain the result of our db query
// setting the query listeners
query
.on('error', function (err) {
// Handle error, and 'end' event will be emitted after this as well
console.log(err);
console.log("ENDPOINT", this.request.httpRequest.endpoint);
updateSockets(err);
})
.on('result', function (player) {
// it fills our array looping on each user row inside the db
players.push(player);
})
.on('end', function () {
// loop on itself only if there are sockets still connected
if (connectionsArray.length) {
pollingTimer = setTimeout(pollingLoop, POLLING_INTERVAL);
updateSockets({players: players});
}
});
};
function is(a, b) {
return a === b && (a !== 0 || 1 / a === 1 / b) // false for +0 vs -0
|| a !== a && b !== b; // true for NaN vs NaN
}
// creating a new websocket to keep the content updated without any AJAX request
io.sockets.on('connection', function (socket) {
console.log('Number of connections:' + connectionsArray.length);
// starting the loop only if at least there is one user connected
if (!connectionsArray.length) {
pollingLoop();
}
socket.on('disconnect', function () {
var socketIndex = connectionsArray.indexOf(socket);
console.log('socket = ' + socketIndex + ' disconnected');
if (socketIndex >= 0) {
connectionsArray.splice(socketIndex, 1);
}
});
console.log('A new socket is connected!');
connectionsArray.push(socket);
});
var updateSockets = function (data) {
// adding the time of the last update
data.time = new Date();
// sending new data to all the sockets connected
connectionsArray.forEach(function (tmpSocket) {
tmpSocket.volatile.emit('notification', data);
});
};
For get fully information about exceptions replace
console.log(err);
To:
console.err(err.stack)
And add if for err variable in connecttion.connect callback function.
Also you can add this code, for safy catch all exceptions:
process.on('uncaughtException', function globalErrorCatch(error, p){
console.error(error);
console.error(error.stack);
});

Resources