Node.js connecting through ssh - mysql

I have a node.js server that works but needs to be set up for ssh connections:
var mysql = require('mysql')
var io = require('socket.io').listen(3000)
var db = mysql.createConnection({
host: 'hostname',
user: 'username',
password: '12345',
database: '12345',
port: 3306,
socket: '/var/run/mysqld/mysqld.sock'
})
db.connect(function(err){
if (err) console.log(err)
})
I'm aware that there are ssh npm libraries for this purpose, however the options available (ssh2, node-sshclient, etc) appear to deal with pretty intricate features that may overcomplicate things. I'm looking for the simplest way to connect to my mysql db through ssh. What would be the best way to accomplish this?

If you are running a linux/unix system do the following:
Connect to your mysql server via ssh and proxy the mysql port (default is 3306) via this ssh tunnel.
This works as follows:
1 Type in screen (to start a screen session which is permanent even if the shell gets closed).
2 Type into screen shell:
ssh -L 3306:127.0.0.1:3306 your_servers_domain_or_ip -lyour_login_name
3 Enter your ssh password / or use a PKI auth to avoid manual steps
4 Done... now it’s possible to connect MySQL like you would do when it’s installed on the same machine as your application.
Connect to MySQL from node.js like below:
var db = mysql.createConnection({
host: '127.0.0.1', // Important to connect to localhost after connecting via ssh in screen
user: 'username',
password: '12345',
database: '12345',
port: 3306
});

Sometimes it's preferrable to instantiate the SSH tunnel connection dynamically (in code) rather than separately using OS libraries. For example, it makes it easier to automatically close the connection, share the environment with other developers, or conditionally use an SSH tunnel depending on the environment.
With packages such as tunnel-ssh, this is easy. Building on the example provided, the connection code would look like:
import { createSSHTunnel } from "./sshTunnel";
const { srcAddr, srcPort } = await createSSHTunnel();
var db = mysql.createConnection({
host: srcAddr,
port: srcPort,
user: 'username',
password: '12345',
database: '12345'
});
With all logic cleanly abstracted away in the sshTunnel module, that could look like:
// sshTunnel.js
import { createTunnel } from "tunnel-ssh";
export async function createSSHTunnel(srcAddr = "127.0.0.1", srcPort = 12345) {
const tunnelOptions = {
autoClose: true,
};
const serverOptions = {
port: srcPort,
};
const sshOptions = {
host: process.env.SSH_HOST,
port: parseInt(process.env.SSH_PORT),
username: process.env.SSH_TUNNEL_USER,
password: process.env.SSH_TUNNEL_PASSWORD,
};
const forwardOptions = {
srcAddr: srcAddr,
srcPort: srcPort,
dstAddr: process.env.DB_HOST,
dstPort: parseInt(process.env.DB_PORT),
};
try {
await createTunnel(
tunnelOptions,
serverOptions,
sshOptions,
forwardOptions
);
} catch (error) {
if (error.code === "EADDRINUSE") {
// Assume port is uniquely used by SSH tunnel, so existing connection can be reused
console.log(`Returning existing SSH tunnel on ${srcAddr}:${srcPort}.`);
return { srcAddr, srcPort };
} else {
throw error;
}
}
console.log(`SSH tunnel successfully created on ${srcAddr}:${srcPort}.`);
return { srcAddr, srcPort };
}
Remarks:
The SSH tunnel arbitrarily uses local port 12345
The environment variables involved are:
DB_HOST: the database hostname
DB_PORT: the database port, 3306 in the original MySQL example, 5432 for Postgres etc.
SSH_HOST: the hostname of the machine serving the SSH tunnel
SSH_PORT: the port of the machine serving the SSH tunnel
SSH_TUNNEL_USER: the username for the SSH tunnel
SSH_TUNNEL_PASSWORD: the password for the SSH tunnel

Related

mariadb for node.js ER_ACCESS_DENIED_ERROR Access denied for user

I am using the following code to establish connection to a MariaDB 10 server:
var mysql = require('mysql');
var con = mysql.createConnection({
host: "local_ip",
user: "username",
password: "my_password",
port: 3307,
database: "name_of_db",
});
con.connect(function(err) {
if (err) {
return console.error('error: ' + err.message);
}
The SQL-Server is running on a machine within a local network.
The SQL-User is granted connections from all hosts (%).
I am able to establish a connection with a SQL GUI tool, with exact the same user.
Seems to me like a bug inside the mysql node package, anybody encountered such a problem?

initiating sequelizer mysql connection via tunnel-ssh module

I'd like to connect to a MySQL database using Sequelizer. Right now, I'm getting a Connection Refused Error.
To access the database, I have to SSH in. According to Mick Hansen here: https://github.com/sequelize/sequelize/issues/3753, one way to SSH in is to use tunnel-ssh to establish the tunnel, then initiate Sequelizer.
My (unsuccessful) approach so far has been to initiate the tunnel, then when the tunnel opens, test whether Sequelizer has authenticated.
Update
Host: DigitalOcean
CLI Success: I can 1) ssh into digitalocean server 2) login into mysql from the server and 3) access all database information as the root user.
Sequel Pro: I can also log into the database using Sequel Pro.
MySQL 127.0.0.1:3306: Based on the mysql/my.cnf file, the port is 3306 and the bind-address is 127.0.0.1. The config file also says instead of skip-networking, the default is to listen only on localhost, if that's relevant.
socketPath -> Error Connection Switching from TCP to socket seems to sometimes work for this type of problem, but when I tried it, I continued to get a connection refused error.
2 Error Types - "All Configured Authentication Methods Failed" and "Error Connection Refused"
Thanks for the help!
Code:
// sequelize config
var sequelize = new Sequelize('database', 'user', 'pass', {
host: '127.0.0.1',
dialect: 'mysql',
port: 3306,
pool: {
max: 10,
min: 0,
idle: 20000
}
});
// tunnel config
var config = {
user:'user',
host:'sshHost',
port:22,
dstHost:'127.0.0.1',
dstPort:3306,
srcHost:'127.0.0.1',
srcPort:3306,
localHost:'127.0.0.1',
localPort: 3306,
privateKey:require('fs').readFileSync('/path/to/key')
};
var tunnel = require('tunnel-ssh');
// initiate tunnel
tunnel(config, function (error, server) {
//....
if(error) {
console.error(error);
} else {
console.log('server:', server);
// test sequelize connection
sequelize
.authenticate()
.then(function(err) {
console.log('Connection established');
})
.catch(function(err) {
console.error('unable to establish connection', err);
})
}
})
When my config is set to the object above, I get an "All configuration methods failed error".
If I change my config to the below, I get a "Sequelize Error Connection Refused" error.
// tunnel config
var config = {
user:'user',
host:'sshHost',
port:22,
dstHost:'127.0.0.1',
dstPort:3306,
//srcHost:'127.0.0.1',
//srcPort:3306,
//localHost:'127.0.0.1',
//localPort: 3306,
privateKey:require('fs').readFileSync('/path/to/key')
};
localPort is the port listening on your local system. Currently you have it defined as 27000 but your Sequelize config is set to 3306.

node.js-mysql connection failed on windows7

I am just getting started with nodejs.
My question is that i get an Error:
connect ECONNREFUSED
npm install mysql;
server.js
var mysql = require('mysql');
var connection = mysql.createConnection({
host: '127.0.0.1',
port: '3306'
});
connection.connect(function(err) {
if(err) {
console.log(err);
}
});
connection.end();
Finally
1.I don't know the "user" and "password";
2."In mysql.conf, comment skip-networking.", I can't find mysql.conf;
3.I have tried this and it's not working, my platform is windows 7.
var client = mysql.createClient({
user: uuuu,
password: pppp,
host: '127.0.0.1',
port: '3306',
_socket: '/var/run/mysqld/mysqld.sock',});
It's clear you have not install mysql server in your windows yet. So you should go to http://www.mysql.com and download the server, install and set up, you can set your username and password and grant privilege to it, so you will know the user and password, and mysql.conf will be inside your installation. And if you are in windows, generally you would not use a UNIX socket to build the connection. So "_socket: '/var/run/mysqld/mysqld.sock'" should not be here.

Can't connect to localhost database from node.js server

Been having a lot of trouble trying to connect to to my localhost database. I've tried using the mysql and mysql-simple node modules but in both cases I just can't get it to connect.
Here's what I used with the 'mysql' module:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
port : '8000',
user : 'uber',
password : 'pass',
});
connection.connect(function(err) {
if (err) throw err;
console.log('Connection Successful');
});
connection.query('USE someDB', function(err) {
if (err) throw err;
console.log('Query Successful');
});
And here' what I used with the 'mysql-simple' module:
var database = require('mysql-simple');
database.init('uber', 'pass', 'mysql', 'localhost', 8000);
database.querySingle('SELECT Host FROM user', function(err, results) {
if (err) {
console.log('error fetching some active users: ' + err);
return;
}
log('Query Successful');
for (var i = 0; i < results.length; i++)
console.log('got active user ' + results[i]);
}
In both cases, when I run my node.js server, it never logs that its connected. I've tried replacing localhost with '127.0.01' and creating a new user to make sure the password is correct, but to no avail. Why isn't it connecting?
Thanks
It's most likely that networking is turned off, that means that mysql server communicates with clients via UNIX sockets and not via TCP/IP. You can check that out running mysql client and run "status" command. If you see port number there, then your mysql server communicates via TCP/IP, or else you'll see something like "socket pathname…", get the pathname and give it to node.js connection parameters, e.g.
...
socketPath: '/opt/lampp/var/...',
...
Check that out in https://github.com/felixge/node-mysql page (search for "socketPathname")
Hope, that's your problem.
You should use mysql_config to show the path to socket.
This a sample on my MAC
QuyLes-MacBook-Pro:freelancer quyle$ mysql_config
Usage: /Applications/MAMP/Library/bin/mysql_config [OPTIONS]
Options:
--cflags [-I/Applications/MAMP/Library/include -fno-omit-frame-pointer -g -DNDEBUG]
--include [-I/Applications/MAMP/Library/include]
--libs [-L/Applications/MAMP/Library/lib -lmysqlclient -lz]
--libs_r [-L/Applications/MAMP/Library/lib -lmysqlclient_r -lz]
--plugindir [/Applications/MAMP/Library/lib/plugin]
--socket [/Applications/MAMP/tmp/mysql/mysql.sock]
--port [0]
--version [5.5.42]
--libmysqld-libs [-L/Applications/MAMP/Library/lib -lmysqld]
--variable=VAR VAR is one of:
pkgincludedir [/Applications/MAMP/Library/include]
pkglibdir [/Applications/MAMP/Library/lib]
plugindir [/Applications/MAMP/Library/lib/plugin]
and then, you add key socketPath for yourMysqlConnection.
bellow on my sample
MysqlServer: {
adapter: 'sails-mysql',
host: 'localhost',
user: 'root', //optional
password: 'root', //optional
database: 'nodejs', //optional,
socketPath: '/Applications/MAMP/tmp/mysql/mysql.sock'
},
change this
database.init('uber', 'pass', 'mysql', 'localhost', 8000);
to
database.init('uber', 'pass', 'mysql', 'localhost', 3306);
and you should be through
Make sure that MySQL and express are running on the same port.
I had MySQL bundled from XAMPP, that ran on Port 3036.
On setting app.listen to 3036, my code worked. FINALLY!
Try this code it's work for me
var mysql = require('mysql');
var connection = mysql.createConnection(
{
host : 'localhost',
user : 'root',
password : '',
database : 'urdatabase',
}
);
connection.connect();
query = connection.query("SELECT * FROM UrTable;");
query
.on('error', function(err) {
console.log( err );
})
.on('result', function( data ) {
socket.emit('YourData',data);
});
I hope this will be helpful for you
In my case, anything happened, so I solved by generating new GRANTs with a new user for nodejs apps
Its due to the networking is turned off in MySQL configurations.
In Ubuntu 20.04.2 and MySQL 8.x.x(its worked in my case) you can find this settings in
/etc/systemd/system/mysql.service.d/override.conf
there will be a ExecStart key and its have multiple configurations.
Here you can provide --skip-networking as OFF
--skip-networking=OFF
And you have to restart your service
systemctl restart mysql.service
It will allow you to connect localhost

Acces database from appfog's node.js server (Database settings)

I'm trying to connect to a database using a node.js server both hosted on appfog.com using these settings:
var client = mysql.createConnection({
host: 'mysql-node01.eu-west-1.aws.af.cm',
user: '****#gmail.com',
password: '*******',
database: 'd2dc10d6a450048b587114fa9b11756ed',
port: 3306
});
I'm pretty sure the host, database and maybe port are incorrect but I don't know which values to use, i.e. should I use localhost?
Use the db credentials from the VCAP_SERVICES environment var and do not hard code them. The credentials are provided when the app is started on AppFog. See the Appfog Node Docs
var env = JSON.parse(process.env.VCAP_SERVICES);
var creds = env['mysql-5.1'][0]['credentials']; # grabs the creds for the first mysql database
var client = mysql.createConnection({
host: creds.hostname || 'localhost',
user: creds.username,
password: creds.password,
database: creds.name,
port: creds.port || 3306
});
I created a npm package to help facilitate getting production and development credentials. See AppFog Env
How to use it:
First set a local env var with your local dev database credentials:
export DEV_DB_CREDS='{ "username": "root", "name": "dev-db-name" }'
Then get the creds in the app:
var service = appfog.getService('mysql-db-name', process.env.DEV_DB_CREDS)
var creds = service.credentials
This method allows the same code to work locally and in production.