Подтвердить что ты не робот

Подключение к серверу MySQL через SSH в PHP

Я хотел бы установить туннель ssh поверх ssh на мой сервер mysql.

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

Я нахожусь на общем хосте, у которого нет библиотек 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.

Любые мысли о постоянстве туннеля? Можно ли установить его с помощью другого script и просто воспользоваться его в PHP?

Спасибо.

4b9b3361

Ответ 1

Эрик,

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

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

- Joao

Ответ 2

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

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

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

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

Для получения дополнительной информации о трюках ssh см. отличная серия Брайана Хэтча по SSH и переадресации портов.

Ответ 3

Я попробовал это, выполнив 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.

Ответ 4

Туннель должен оставаться открытым во время действия (-ов) 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 установлено в этот таймфрейм, мы все настроены.

Ответ 5

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

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

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

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

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

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

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

Ответ 6

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