phpseclib – Могу ли я подключиться с использованием имени пользователя, ключа и пароля (а не ключевой фразы)

Извините, если я пропустил это в документации, но возможно ли подключиться к 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 . Он поддерживает все механизмы аутентификации, о которых вы говорили, и работает достаточно хорошо.