2008-11-21 3 views
18

Я хотел бы установить туннель ssh через ssh на мой сервер mysql.Подключение к серверу MySQL через SSH в PHP

В идеале я бы вернул указатель 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?

Спасибо.

+0

Вы понимаете, что все остальные на этом общем хосте также смогут напрямую подключаться к вашей базе данных? – Zoredache 2008-11-21 18:01:23

+0

Для подключения все равно потребуется действующее имя пользователя и пароль, но это определенный риск. Будет ли это так, если туннель был создан для выполнения в php? – 2008-11-21 18:09:48

+0

Я удалил свой предыдущий ответ, как я заметил, прочитав документацию, что это намного больше, чем я думал, чтобы заставить mysqli использовать SSL. – Powerlord 2008-11-21 18:20:38

ответ

0

Eric,

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

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

--Joao

1

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

14

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

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

ssh -L 3306:localhost:3306 [email protected] 

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

Для получения дополнительной информации о трюках ssh см. Brian Hatch's отличная серия по SSH и переадресации портов.

+0

Этот ответ дал мне правильный путь. Я, наконец, понял это: http://stackoverflow.com/questions/464317/connect-to-a-mysql-server-over-ssh-in-php#comment65229024_16138417 – Ryan 2016-08-13 19:59:17

2

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

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

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

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

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

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

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

6

Я попробовал это, выполнив SSH как с помощью учетных данных root, так и с помощью пары открытого частного ключа. Это позволяет мне взаимодействовать через командную строку, но не через 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 функции специально.

6

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

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

ssh -f -L bind-ip-address:bind-port:remote-ip-address:remote-port \ 
[email protected] [command] >> /path/to/logfile 

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

shell_exec("ssh -f -L 127.0.0.1:3307:127.0.0.1:3306 [email protected] 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 устанавливается в этот таймфрейм, мы все настроены.