Title: Node.js ORM mysql connect via SSH tunnel
Tags: node.js;node-orm2
Question: I'm trying to set up a node.js application which uses node-orm2. However our cloud hosted DB can only be connected via SSH tunnel. Checking the ORM doc I can not see any config option to connect to the DB via SSH tunnel. Is there any way to set up this or I need to find some way to connect without SSH?

Comment: You can always use SSH outside of your Node.js app to handle this.  http://www.revsys.com/writings/quicktips/ssh-tunnel.html

Here is the accepted answer: I updated the code example for tunnel-ssh 1.1.0, because it's actually the only working example on the internet (for so far i searched..). 
It was quite a hassle to get this new tunnel-ssh configured... 

```var mysql = require('mysql');
var Tunnel = require('tunnel-ssh');

module.exports = function (server) {
    return new Object({
            tunnelPort: 33333,          // can really be any free port used for tunneling

            /**
             * DB server configuration. Please note that due to the tunneling the server host
             * is localhost and the server port is the tunneling port. It is because the tunneling
             * creates a local port on localhost
             */
            dbServer: server || {
                host: '(566)234-0132',
                port: 33333,
                user: 'username',
                password: 'yourpwd',
                database: 'yourdb'
            },

            /**
             * Default configuration for the SSH tunnel
             */
            tunnelConfig: {
                remoteHost: '(566)234-0132', // mysql server host
                remotePort: 3306, // mysql server port
                localPort: 33333, // a available local port
                verbose: true, // dump information to stdout
                disabled: false, //set this to true to disable tunnel (useful to keep architecture for local connections)
                sshConfig: { //ssh2 configuration (https://github.com/mscdex/ssh2)
                    host: 'your_tunneling_host',
                    port: 22,
                    username: 'user_on_tunneling',
                    password: 'pwd'
                    //privateKey: require('fs').readFileSync('<pathToKeyFile&gt;'),
                    //passphrase: 'verySecretString' // option see ssh2 config
                }
            },

            /**
             * Initialise the mysql connection via the tunnel. Once it is created call back the caller
             *
             * @param callback
             */
            init: function (callback) {
                /* tunnel-ssh < 1.0.0 
                //
                // SSH tunnel creation
                // tunnel-ssh < 1.0.0
                var me = this;
                me.tunnel = new Tunnel(this.tunnelConfig);
                me.tunnel.connect(function (error) {
                    console.log('Tunnel connected', error);
                    //
                    // Connect to the db
                    //
                    me.connection = me.connect(callback);

                });
                */

                /* tunnel-ssh 1.1.0 */
                //
                // SSH tunnel creation 
                //
                var me = this;

                // Convert original Config to new style config:
                var config = this.tunnelConfig;

                var newStyleConfig = {
                    username: config.sshConfig.username, 
                    port: config.sshConfig.port,
                    host: config.sshConfig.host,
                    // SSH2 Forwarding... 
                    dstPort: config.remotePort,
                    dstHost: config.remoteHost,
                    srcPort: config.localPort,
                    srcHost: config.localHost,
                    // Local server or something...
                    localPort: config.localPort,
                    localHost: config.localHost,
                    privateKey: config.privateKey
                }


                me.tunnel = tunnel(newStyleConfig, function (err) {
                    console.log('Tunnel connected', err);
                    if (err) {
                        return callback(err);
                    }

                    me.connection  = me.connect(callback);
                });
            },

            /**
             * Mysql connection error handling
             *
             * @param err
             */
            errorHandler: function (err) {

                var me = this;
                //
                // Check for lost connection and try to reconnect
                //
                if (err.code === 'PROTOCOL_CONNECTION_LOST') {
                    console.log('MySQL connection lost. Reconnecting.');
                    me.connection = me.connect();
                } else if (err.code === 'ECONNREFUSED') {
                    //
                    // If connection refused then keep trying to reconnect every 3 seconds
                    //
                    console.log('MySQL connection refused. Trying soon again. ' + err);
                    setTimeout(function () {
                        me.connection = me.connect();
                    }, 3000);
                }
            },

            /**
             * Connect to the mysql server with retry in every 3 seconds if connection fails by any reason
             *
             * @param callback
             * @returns {*} created mysql connection
             */
            connect: function (callback) {

                var me = this;
                //
                // Create the mysql connection object
                //
                var connection = mysql.createConnection(me.dbServer);
                connection.on('error', me.errorHandler);
                //
                // Try connecting
                //
                connection.connect(function (err) {
                    if (err) throw err;
                    console.log('Mysql connected as id ' + connection.threadId);
                    if (callback) callback();
                });

                return connection;
            }
        }
    );

};
```

Comment for this answer: The examples in this thread let you connect to a database server via a remote server via ssh. It does this by setting up a ssh tunnel. Then you tell MySQL to connect to a port (the tunnel port) on your local machine with your database credentials for your remote database and you're connected.

Here is another answer: Finally it was resolved by dropping orm2 and using node-mysql and tunnel-ssh modules as in the code below.

```var mysql = require('mysql');
var Tunnel = require('tunnel-ssh');

module.exports = function (server) {

    return new Object({

            tunnelPort: 33333,          // can really be any free port used for tunneling

            /**
             * DB server configuration. Please note that due to the tunneling the server host
             * is localhost and the server port is the tunneling port. It is because the tunneling
             * creates a local port on localhost
             */
            dbServer: server || {
                host: '(566)234-0132',
                port: 33333,
                user: 'username',
                password: 'yourpwd',
                database: 'yourdb'
            },

            /**
             * Default configuration for the SSH tunnel
             */
            tunnelConfig: {
                remoteHost: '(566)234-0132', // mysql server host
                remotePort: 3306, // mysql server port
                localPort: 33333, // a available local port
                verbose: true, // dump information to stdout
                disabled: false, //set this to true to disable tunnel (useful to keep architecture for local connections)
                sshConfig: { //ssh2 configuration (https://github.com/mscdex/ssh2)
                    host: 'your_tunneling_host',
                    port: 22,
                    username: 'user_on_tunneling',
                    password: 'pwd'
                    //privateKey: require('fs').readFileSync('<pathToKeyFile&gt;'),
                    //passphrase: 'verySecretString' // option see ssh2 config
                }
            },

            /**
             * Initialise the mysql connection via the tunnel. Once it is created call back the caller
             *
             * @param callback
             */
            init: function (callback) {
                //
                // SSH tunnel creation
                //
                var me = this;
                me.tunnel = new Tunnel(this.tunnelConfig);
                me.tunnel.connect(function (error) {
                    console.log('Tunnel connected', error);
                    //
                    // Connect to the db
                    //
                    me.connection = me.connect(callback);

                });
            },

            /**
             * Mysql connection error handling
             *
             * @param err
             */
            errorHandler: function (err) {

                var me = this;
                //
                // Check for lost connection and try to reconnect
                //
                if (err.code === 'PROTOCOL_CONNECTION_LOST') {
                    console.log('MySQL connection lost. Reconnecting.');
                    me.connection = me.connect();
                } else if (err.code === 'ECONNREFUSED') {
                    //
                    // If connection refused then keep trying to reconnect every 3 seconds
                    //
                    console.log('MySQL connection refused. Trying soon again. ' + err);
                    setTimeout(function () {
                        me.connection = me.connect();
                    }, 3000);
                }
            },

            /**
             * Connect to the mysql server with retry in every 3 seconds if connection fails by any reason
             *
             * @param callback
             * @returns {*} created mysql connection
             */
            connect: function (callback) {

                var me = this;
                //
                // Create the mysql connection object
                //
                var connection = mysql.createConnection(me.dbServer);
                connection.on('error', me.errorHandler);
                //
                // Try connecting
                //
                connection.connect(function (err) {
                    if (err) throw err;
                    console.log('Mysql connected as id ' + connection.threadId);
                    if (callback) callback();
                });

                return connection;
            }
        }
    );

};
```

Comment for this answer: could you please give the correct answer to @Joshua Angnoe ?

Here is another answer: Thanks for the existing answers in this thread. The following solution worked for me:

```function connect() {
    return new Promise(async resolve =&gt; {
        let tunnelPort = 33000 + Math.floor(Math.random() * 1000);

        Tunnel({
            //First connect to this server over ssh
            host: '(566)234-0132',
            username: 'vagrant',
            privateKey: await fs.readFile('path/to/private_key'),

            //And forward the inner dstPort (on which mysql is running) to the host (where your app is running) with a random port
            dstPort: 3306,
            localPort: tunnelPort
        }, (err) =&gt; {
            if (err) throw err;
            console.log('Tunnel connected');

            let connection = mysql.createConnection({
                //Now that the tunnel is running, it is forwarding our above "dstPort" to localhost/tunnelPort and we connect to our mysql instance.
                host: '(566)234-0132',
                port: tunnelPort,
                user: 'root',
                password: 'password',
                database: 'dbName'
            });

            connection.on('error', err =&gt; { throw err; });
            connection.connect((err) =&gt; {
                if (err) throw err;
                console.log('Mysql connected as id ' + connection.threadId);

                resolve(connection);
            });
        });
    })
}
```

Comment for this answer: Its works. But after a while of querying with database, it disconnects from ssh connection. And its throws PROTOCOL_CONNECTION_LOST error.

Here is another answer: You can use the ```settings``` parameters to ```node-orm2``` in order pass an ```options``` object to the underlying driver. For example, if you are using a ```mysql``` then you can pass an ```ssl``` option. See https://github.com/felixge/node-mysql#ssl-options in this case. 

Comment for this answer: Sorry, probably the question wasn't clear enough. I can provide the ssl auth details in the ssl config option. But as the question states I need to connect to the mysql server via an SSH tunnel (see http://serverfault.com/questions/517081/connecting-to-mysql-over-ssh-tunnel).
Comment for this answer: There is no Heroku involved in the setup. So I'm not sure what do you exactly mean. Basically I have 
SSH: server, port, user, pwd
MySQL: server, port, user, pwd
What I need is to configure node-orm2 to connect to the mysql server via an SSH tunnel created on the SSH server.
Comment for this answer: I misunderstood, then. If that's the case then then you probably need to set up the tunnel yourself (`ssh remote_host -L ...`), as mentioned in @Brad's comment, and point your connection string to the local host using the supplied tunneled port. Does that answer the question?
Comment for this answer: Assuming that your SQL server is running on `db.com:1234`, you would need to have `ssh -L 5678:localhost:1234 db.com` running on your Heroku app host, and set your connection string to connect to `localhost:5678`. If that works for you, then we can discuss more advanced options such as `-M` etc. Let's see if I understand the problem first, though.

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 4, 'CommentCount': 1, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2014:00:08/02/14', 'FavoriteCount': 4.0, 'PostTypeId': 1, 'Tags': '<node.js><node-orm2>', 'Title': 'Node.js ORM mysql connect via SSH tunnel', 'ViewCount': 11201, 'id': 25100174, 'user_AboutMe': '<p>Tech lead at a small UK mobile dev startup interested in everything tech. Programming in c, c++, perl, php, javascript, objective c, etc. When not in front of the computer then most likely can be found underwater taking pictures.</p>\n', 'user_AccountId': 961218.0, 'user_DisplayName': 'Zoltan Magyar', 'user_Reputation': 864.0, 'user_Views': 151.0, 'user_id': 985538.0}}