Извините, если я пропустил это в документации, но возможно ли подключиться к SFTP-серверу с закрытым ключом и паролем (а не парольной фразой для моего личного ключа).
Примеры показывают имя пользователя / пароль, имя пользователя / ключа и имя пользователя / ключа / ключа.
При подключении через командную строку я получаю это приглашение для моего пароля …
пароль пользователя @ xxxx:
Надеюсь, эта библиотека может справиться с этим?
В противном случае существуют ли какие-либо другие решения на базе PHP, которые могут поддерживать аутентификацию имени пользователя / ключа и сервера? Я довольно гибкий и могу установить модули, если это необходимо.
РЕДАКТИРОВАТЬ
Спасибо за помощь до сих пор … Я пробовал то, о чем вы упоминали Нойбера, но это, похоже, не сработало. И чтобы проверить, что необходимо для подключения к серверу, я проверил это в командной строке.
sftp key user@ip
– запрашивается пароль как ожидалось
sftp user@ip
– запрашивается пароль, но когда введен правильно, я «аутентифицирован с частичным успехом».
Я думаю, что разрешение на каталоги и ключи должно быть хорошо, если я могу использовать ключ, а затем пароль.
Я начинаю думать, что эта библиотека не поддерживает то, что мне нужно.
phpseclib поддерживает многофакторную аутентификацию . Вот пример того, как это сделать:
<?php include('Net/SSH2.php'); include('Crypt/RSA.php') $rsa = new Crypt_RSA(); $rsa->loadKey(file_get_contents('/path/to/key.pem')); $ssh = new Net_SSH2('www.domain.tld'); if (!$ssh->login('username', 'pass1', $rsa)) { exit('Login failed'); } // this does the same thing as the above //if (!$ssh->login($username, 'pass1') && !$ssh->login('username', $rsa)) { // exit('Login failed'); //} echo $ssh->exec('pwd'); echo $ssh->exec('ls -la'); ?>
в<?php include('Net/SSH2.php'); include('Crypt/RSA.php') $rsa = new Crypt_RSA(); $rsa->loadKey(file_get_contents('/path/to/key.pem')); $ssh = new Net_SSH2('www.domain.tld'); if (!$ssh->login('username', 'pass1', $rsa)) { exit('Login failed'); } // this does the same thing as the above //if (!$ssh->login($username, 'pass1') && !$ssh->login('username', $rsa)) { // exit('Login failed'); //} echo $ssh->exec('pwd'); echo $ssh->exec('ls -la'); ?>
в<?php include('Net/SSH2.php'); include('Crypt/RSA.php') $rsa = new Crypt_RSA(); $rsa->loadKey(file_get_contents('/path/to/key.pem')); $ssh = new Net_SSH2('www.domain.tld'); if (!$ssh->login('username', 'pass1', $rsa)) { exit('Login failed'); } // this does the same thing as the above //if (!$ssh->login($username, 'pass1') && !$ssh->login('username', $rsa)) { // exit('Login failed'); //} echo $ssh->exec('pwd'); echo $ssh->exec('ls -la'); ?>
Однако что-то иметь в виду: многие люди путают секретные ключи, защищенные паролем, как многофакторные (пароль и открытый ключ), когда на самом деле это не так. По крайней мере, не так далеко, как SSH.
Отказ от ответственности @MartinPrikryl: это решение устарело, теперь phpseclib поддерживает многофакторную аутентификацию изначально – см. Также ответ @BoukeVersteegh и @neubert .
Я столкнулся с одной и той же проблемой для одного из моих проектов, используя phpseclib. Я попробовал несколько предложений безрезультатно, и, наконец, сделал некоторые исследования в библиотечном коде. Я закончил его модификацию, хотя и не очень.
В частном методе SSH2.php «_privatekey_login» (вызванный из метода входа в систему, когда есть ключ), в конце метода есть код для обработки отказа аутентификации.
extract(unpack('Ctype', $this->_string_shift($response, 1))); switch ($type) { case NET_SSH2_MSG_USERAUTH_FAILURE: // either the login is bad or the server employs multi-factor authentication return false; case NET_SSH2_MSG_USERAUTH_SUCCESS: $this->bitmap |= NET_SSH2_MASK_LOGIN; return true; }
После ввода некоторых журналов я обнаружил, что ответ, который я возвращал с сервера, действительно был «паролем, клавиатурным интерактивным».
Я изменил все методы входа (как в классах SFTP, так и SSH2), чтобы взять второй пароль, передав его полностью методу «_privatekey_login». Затем я изменил приведенный выше раздел следующим образом:
extract(unpack('Ctype', $this->_string_shift($response, 1))); switch ($type) { case NET_SSH2_MSG_USERAUTH_FAILURE: // Possible multi-factor authentication. if ($password && $this->_keyboard_interactive_login($username, $password)) { $this->bitmap |= NET_SSH2_MASK_LOGIN; return true; } // the login is bad. return false; case NET_SSH2_MSG_USERAUTH_SUCCESS: $this->bitmap |= NET_SSH2_MASK_LOGIN; return true; }
Я скопировал интерактивный вызов на клавиатуре из другой части кода, поэтому некоторые из них могут быть совершенно не нужны. Хотя это может не относиться ко всем серверам, в моем случае это прекрасно работало.
Короткий простой ответ: сначала войдите с помощью ключа + пользователя, затем войдите с пользователем + pass.
$host = 'ftp.example.com'; $username = 'username'; $password = 'secret'; $key = new RSA(); $key->load(file_get_contents('~/.ssh/private_key.pem')); $sftp = new SFTP($host); if ($sftp->login($username, $key) || $sftp->login($username, $secret)) { // success } else { // failed }
Да, это уже упоминалось, но длинные заметки делали это неясным и выглядящим сложным.
Я решил удалить свой другой ответ, потому что, оказывается, я ошибся; вы можете делать многофакторные логины с SSH, а не стандартным образом. Ни один из этих методов проверки подлинности не является родным или встроенным в openssh, и поэтому нет стандартного способа его решения. Большинство пользователей Google Authenticator используют одноразовый пароль, но есть различия. Согласно тому, что рекомендует этот сайт , похоже, что это делается путем вызова команды ПОСЛЕ того, как пользователь был аутентифицирован сервером SSH. Глядя на исходный код phpseclib
в Net/SSH2.php
в Net/SSH2.php
login()
он имеет следующий код:
case NET_SSH2_MSG_USERAUTH_FAILURE: // can we use keyboard-interactive authentication? if not then either the login is bad or the server employees // multi-factor authentication [...] return false;
Даже разработчики phpseclib поняли, что многофакторная аутентификация возможна, но из-за отсутствия стандартов они не удосужились ее кодировать. Исправлен код ошибки
аутентифицирован с частичным успехом
показывает, что именно так настроен сервер, к которому вы пытаетесь подключиться. Если вы хотите кодировать многофакторную аутентификацию, специфичную для настройки вашего сервера, я не понимаю, почему это невозможно. Это файл, который вам нужно будет отредактировать, чтобы сделать это.
Вы можете использовать привязки SSH2 в PECL . Он поддерживает все механизмы аутентификации, о которых вы говорили, и работает достаточно хорошо.