2015-06-05 3 views
3

Я запускаю сайт узла Express на своей машине OS X локально.Не удается подключиться к MySQL через SSH

Мне нужно ssh для удаленной базы данных mysql, поэтому я могу начать писать запросы против него.

Теперь я могу передать ssh на наш удаленный сервер (запустив базу данных mysql) в облаке, когда я это сделаю через терминал OS X Yosemite.

Но я не успел сделать это в коде с использованием промежуточного программного обеспечения node-mysql и туннеля-ssh.

Мой код работает, но на самом деле это не ошибка, за исключением моего GET при отладке моего экспресс-приложения в Webstorm.

Некоторые факты:

  • Я могу SSH в MySql из OS X с помощью этой команды:

    SSH -L 3306: 127.0.0.1: 3306 ourCloudServerName.net MyUserNameHere

  • Я могу затем подключиться к MySQL с помощью следующей команды:

    MySQL -h локальный -p -u myUserNameHere

  • Когда я нахожусь в командной строке mysql и нажимаю SHOW GLOBAL VARIABLES LIKE 'PORT', я понимаю, что сервер (или база данных, я думаю, это означает ... не уверен) работает на порту 3306

  • Я отладка с помощью WebStorm 10.0.3 Это означает, что я отладка моего приложения Node Express, который начинается так:

    вара порт = 3000;

    app.set ('порт', порт);

    app.listen (app.get ('порт'), функция() { console.log ('веб-сервер Экспресс прослушивает порт' + app.get ('порт'));} )

    • Я могу запустить мой экспресс-приложение с помощью локального хоста: 3000 в Chrome

Теперь вот моя первая попытка попробовать и использовать как узел-MySQL и тоннельного SSH

mysqlConfig.js

var databaseConfig = module.exports = function(){}; 

module.exports = { 

    mySQLConfig: { 
     host: '127.0.0.1', 
     username: 'root', 
     password: 'rootPassword', 
     database: 'SomeDatabaseName', 
     port: 3306, 
     timeout: 100000 
    }, 

    sshTunnelConfig: { 
     username: 'myusername', 
     password: 'mypassword', 
     host: 'ourCloudServerName\.net', 
     port: 22, 
     //localPort: 3306, //4370 
     //port: 3333, 
     //localPort: 4370, 
     dstPort: 3306, 
     srcHost: 'localhost', 
     dstHost: 'localhost', 
     localHost: 'localhost' 
    } 
}; 

connection.js

var mysql = require('mysql'), 
    config = require('./mysqlConfig'), 
    tunnel = require('tunnel-ssh'); 


var connection = module.exports = function(){}; 

createDBConnection = function(){ 
    var mysqlConnection = mysql.createConnection({ 
     host: config.mySQLConfig.host, 
     user: config.mySQLConfig.username, 
     password: config.mySQLConfig.password, 
     database: config.mySQLConfig.database, 
     connectTimeout: config.mySQLConfig.timeout 
    }); 

    return mysqlConnection; 
}; 


connection.invokeQuery = function(sqlQuery){ 

    var data = undefined; 

    var sshTunnel = tunnel(config.sshTunnelConfig, function(error, result) { 

     var sqlConnection = createDBConnection(); 

     sqlConnection.connect(function (err) { 
      console.log(err.code); 
     }); 
     sqlConnection.on('error', function (err) { 
      console.log(err.code); 
     }); 

     data = sqlConnection.query({ 
      sql: sqlQuery, 
      timeout: config.mySQLConfig.timeout 
     }, function (err, rows) { 

      if (err && err.code) { 
       console.log("error code: " + err.code) 
      } 
      if (err) { 
       console.error("error stack: " + err.stack) 
      } 
      ; 

      if (rows) { 
       console.log("We have Rows!!!!!!") 
      } 
     }); 

     sqlConnection.destroy(); 
    }); 

    return data; 
}; 

маршрутизатор/индекс.JS

var connection = require('../config/database/connection'); 
var express = require('express'); 
var router = express.Router(); 

router.get('/', function(req, res) { 
    var sqlStatement = "Select top 10 from someTable"; 

    var rows = connection.invokeQuery(sqlStatement); 
}); 

module.exports = router; 

Так что я стараюсь отладки в WebStorm и я либо никогда не получить хорошую ошибку, выводимой на консоль или если я делаю, это общая ошибка узла как. У меня могла бы возникнуть фундаментальная проблема с кодом и/или просто не устанавливать правильные значения или использовать право промежуточного программного обеспечения, я просто не знаю. Во время отладки это не говорит. Я просто знаю, что:

1) Я не получаю подключение к серверу через ssh. Соединения показывают 0 в объекте сервера SSH во время отладки

2) MySQL объект подключения показывает отсоединен, никогда не подключен

3) Я также получаю эту ошибку узла в WebStorm при выполнении экспресс-сайт, который не говорит мне домкрат:

enter image description here

Какая связь отказано, я бегу этот сайт через локальный порт 3000. является ли это высказывание не может подключиться к SSH? Я понятия не имею. Это не всегда появляется или происходит, это прерывистая ошибка и может быть просто отладочной вещью webstorm, где мне просто нужно снова отлаживать отладку и обычно уходить ... но может быть взаимосвязано, не имеет понятия.

А вот что мой объект конфигурации имеет, когда я проверить его во время отладки

enter image description here enter image description here enter image description here

И в туннельном SSH/index.js, строка 70, где она возвращает сервер, он пытается создать, я вижу, что нет никакой связи SSH:

enter image description here

UPDATE - на СУГ Gestions из ответов

enter image description here enter image description here enter image description here enter image description here

+0

Можете ли вы попробовать console.log (ошибка, результат) внутри обратного вызова туннеля SSH, чтобы узнать, что такое ошибка SSH? – Harangue

+0

, где бы я положил это сразу после закрытия соединения DB (уничтожить линию)? – PositiveGuy

+0

Прямо в начале вашего обратного вызова (после var sshTunnel ...). Если то, что говорит ваше сообщение, верно, соединение SSH никогда не устанавливается, поэтому нам нужно выяснить, что вызывает это. – Harangue

ответ

4

Это может быть упрощено, если все, что вам нужно сделать, это туннелировать подключения MySQL внутри вашего приложения. Модуль mysql2 имеет (лучшую) поддержку для передачи пользовательского потока для использования в качестве подключения к базе данных, это означает, что вам не нужно запускать локальный TCP-сервер и слушать подключения к туннелю через.

Вот пример использования mysql2 и ssh2:

var mysql2 = require('mysql2'); 
var SSH2Client = require('ssh2').Client; 

var sshConf = { 
    host: 'ourCloudServerName.net', 
    port: 22, 
    username: 'myusername', 
    password: 'mypassword', 
}; 
var sqlConf = { 
    user: 'root', 
    password: 'rootPassword', 
    database: 'SomeDatabaseName', 
    timeout: 100000 
}; 

var ssh = new SSH2Client(); 
ssh.on('ready', function() { 
    ssh.forwardOut(
    // source IP the connection would have came from. this can be anything since we 
    // are connecting in-process 
    '127.0.0.1', 
    // source port. again this can be randomized and technically should be unique 
    24000, 
    // destination IP on the remote server 
    '127.0.0.1', 
    // destination port at the destination IP 
    3306, 
    function(err, stream) { 
     // you will probably want to handle this better, 
     // in case the tunnel couldn't be created due to server restrictions 
     if (err) throw err; 

     // if you use `sqlConf` elsewhere, be aware that the following will 
     // mutate that object by adding the stream object for simplification purposes 
     sqlConf.stream = stream; 
     var db = mysql2.createConnection(sqlConf); 

     // now use `db` to make your queries 
    } 
); 
}); 
ssh.connect(sshConf); 

Вы хотите расширить на этом примере, конечно, добавить обработку в SSH и тузд уровня ошибки в случае либо уйти по какой-то причине (TCP соединение отключается или службы ssh/mysql останавливаются, например). Как правило, вы можете просто добавить error обработчикам событий для ssh и db, чтобы обрабатывать большинство случаев, хотя вы можете также прослушать end событий, чтобы узнать, когда вам нужно восстановить либо оба соединения ssh, и db.

Кроме того, может быть целесообразным настроить keepalive на уровне ssh и mysql. ssh2 имеет пару keepalive options, которые ведут себя так же, как и параметры keepalive клиента OpenSSH. Для mysql2, как правило, то, что я сделал, это просто позвонить db.ping() на некоторый интервал. Вы можете передать обратный вызов, который вызывается, когда сервер отвечает на пинг, поэтому вы можете использовать дополнительный таймер, который очищается при выполнении обратного вызова, может. Таким образом, если обратный вызов не выполняется, вы можете попытаться снова подключиться.

+0

спасибо, позвольте мне попробовать. Интересно, тогда в чем смысл connect-ssh – PositiveGuy

+0

сладкий! Кажется, у меня есть ssh-соединение. Как только получить mysql auth errors сейчас, работая над этим, мы, надеюсь, будем работать в ближайшее время. Я даже не видел mysql2, wtf! должно было использовать это в первую очередь! – PositiveGuy

+0

Я предполагаю, что это было просто вопрос тестирования другого промежуточного программного обеспечения mysql. Спасибо – PositiveGuy

0

Это проблема SELinux и ваш HTTPd/веб-сервер не может подключиться через сеть, ответ на ваш вопрос будет следующей командой:

setsebool -P httpd_can_network_connect 1 

Тогда он должен хорошо работать. Я полагаю, вы используете apache?

+0

Я попытался вставить это в терминал (на моей локальной машине OS X), но он не распознает setsebool – PositiveGuy

+0

Разве эта команда не должна копироваться в терминале SSH - другими словами, сервер, который вы пытаетесь подключить? – pbalazek

+0

, если это нужно запустить с Ubuntu, у меня нет доступа к серверу и не знаю, зачем мне это нужно, если я могу ssh из моей ОС X, но не могу в узле – PositiveGuy

Смежные вопросы