Подключение к серверу MySQL через SSH в PHP - PullRequest
19 голосов
/ 21 ноября 2008

Я бы хотел установить ssh-туннель через ssh к моему серверу mysql.

В идеале я бы возвращал указатель mysqli db точно так же, как подключался напрямую.

Я на общем хосте, у которого нет библиотек SSH2 , но я могу установить их локально с помощью PECL.

Если есть способ, который использует собственные команды, это было бы замечательно.

Я думал примерно так, но без этих библиотек это не сработает.

$connection = ssh2_connect('SERVER IP', 22); 

ssh2_auth_password($connection, 'username', 'password');

$tunnel = ssh2_tunnel($connection, 'DESTINATION IP', 3307);

$db = new mysqli_connect('127.0.0.1', 'DB_USERNAME', 'DB_PASSWORD', 
                         'dbname', 3307, $tunnel)
    or die ('Fail: ' . mysql_error());  

У кого-нибудь есть идеи? Я использую общий хост CentOS Linux на liquidweb.

Есть какие-нибудь мысли по поводу сохранения туннеля? Можно ли установить его с помощью другого сценария и просто воспользоваться этим в PHP?

Спасибо.

Ответы [ 6 ]

14 голосов
/ 22 ноября 2008

Я бы использовал инструмент autossh для создания постоянного ssh-туннеля к вашей базе данных mysql. Тогда все, что вам нужно сделать в своем PHP-коде, это указать его на localhost.

Вы можете проверить это (без автоматического перезапуска), выполнив:

ssh -L 3306:localhost:3306 user@domain.com

Установите ключ ssh, чтобы вам не нужно было использовать пароли, и настройте файл .ssh / authorized_keys в системе mysql, чтобы разрешить его использование только для переадресации портов.

Подробнее о трюках ssh см. Отличная серия Брайана Хэтча по SSH и переадресации портов.

6 голосов
/ 30 сентября 2012

Туннель должен оставаться открытым в течение действия SQL. Следующий пример из RJMetrics объясняет:

Вот общий синтаксис команды SSH:

ssh -f -L bind-ip-address:bind-port:remote-ip-address:remote-port \
username@remote-server [command] >> /path/to/logfile

Вот как безопасно установить соединение с удаленной базой данных всего за 2 строки кода PHP:

shell_exec("ssh -f -L 127.0.0.1:3307:127.0.0.1:3306 user@remote.rjmetrics.com sleep 60 >> logfile");  
$db = mysqli_connect("127.0.0.1", "sqluser", "sqlpassword", "rjmadmin", 3307);

Мы используем функцию shell_exec() для создания туннеля с открывающимся окном в 60 секунд, а затем используем функцию mysqli_connect(), чтобы открыть соединение с базой данных, используя перенаправленный порт. Обратите внимание, что здесь мы должны использовать библиотеку «mysqli», потому что mysql_connect() не позволяет нам указать порт, а функции mysql_* устарели.

sleep 60: Когда речь идет о туннельных соединениях, у нас в основном есть два варианта: оставить соединение открытым все время или открыть его и закрыть его при необходимости. Мы предпочитаем последнее, и поэтому мы не указываем опцию -N при создании туннеля, которая оставляла бы его открытым до тех пор, пока процесс не будет уничтожен вручную (плохо для автоматизации). Так как -N не указан, наш туннель закроется сам, как только сессия SSH не будет использоваться ни для чего. Это идеальное поведение, за исключением нескольких секунд между тем, когда мы создаем туннель и когда мы получаем соединение MySQL и работаем через туннель. Чтобы выиграть нам некоторое время в течение этого периода, мы создаем безвредную команду sleep 60 при создании туннеля, которая обычно дает нам 60 секунд, чтобы что-то еще проходило через туннель, прежде чем оно закроется. Пока в этот период установлено соединение MySQL, мы все настроены.

6 голосов
/ 23 января 2009

Я попытался сделать это, выполнив SSH как с правами суперпользователя, так и с парой открытого личного ключа. Это позволяет мне соединяться через командную строку, но не через код PHP.

Я также пытался создать туннель (используя функции SSH2) и запустить команды оболочки из кода PHP (system, exec и т. Д.); ничего не получалось.

Наконец-то я попробовал функцию SSH2 для выполнения команды оболочки, и она наконец заработала:)

Вот мой код, если он вам поможет:

$connection = ssh2_connect($remotehost, '22');
if (ssh2_auth_password($connection, $user,$pass)) {
    echo "Authentication Successful!\n";
} else {
    die('Authentication Failed...');
}


$stream=ssh2_exec($connection,'echo "select * from zingaya.users where id=\"1606\";"  | mysql');
stream_set_blocking($stream, true);
while($line = fgets($stream)) {
    flush();
    echo $line."\n";
}

Попробуйте, если хотите специально использовать функции PHP.

3 голосов
/ 22 ноября 2008

Это возможно возможно, но почему? Это сложнее, чем нужно, и подвержено ошибкам.

Не можете ли вы запустить базу данных локально? Если нет, то не можете ли вы использовать что-то вроде SQLite, XML-файлы или что-то еще, что не требует отдельного демона сервера?

Вы действительно не хотите инициализировать туннель внутри сценариев PHP. Инициализация туннеля SSH занимает много времени (это может быть секунда или две), так что при загрузке каждой страницы, которая подключается к базе данных, будет задержка 2 секунды.

Если у вас есть для этого (что я настоятельно рекомендую), лучшим способом будет иметь скрипт, поддерживающий соединение в фоновом режиме.

Установка пары ключей SSH . Затем, используя autossh или простой скрипт, который будет выполнять требуемую команду SSH, дождитесь, пока процесс не прекратится, и запустите его снова. Он может быть более умным и пытаться запускать команду каждые 10-20 секунд, переподключаться, если она не работает.

Используя пару ключей SSH, вам не придется жестко задавать пароль удаленного пользователя в скрипте. Я бы порекомендовал ограничить возможности удаленного пользователя (используя выделенного туннельного пользователя и назначив ему ограниченную оболочку, см. этот вопрос)

Короче говоря, я настоятельно рекомендовал бы сначала попробовать SQLite, затем посмотреть, насколько это возможно для хранения данных с использованием файлов XML, а затем попытаться настроить ваш веб-хост на наличие локального сервера MySQL. Опция туннелирования SSH.

1 голос
/ 22 ноября 2008

Я думаю, что вам лучше всего найти другого хостинг-провайдера; Я предлагаю VPS-решение (Virtual Private Server), которое дает вам полный контроль над вашим веб-хостом. Таким образом, если вам не нравится конфигурация по умолчанию, вы можете обновить ее самостоятельно.

1 голос
/ 21 ноября 2008

Эрик

Я думаю, тебе не повезло в этом. Вы можете использовать расширение ssh в своем PHP-коде или, если у вас есть доступ к серверу, вы можете попытаться создать туннель ssh в командной строке.

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

- Joao

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...