Подключение к SFTP с использованием PHP и закрытого ключа

Я прочитал статью после статьи и просто не могу найти "решение", которое работает для того, что у меня есть.

Я пытаюсь загрузить файлы через SFTP, используя php-скриптинг. Я успешно использовал CyberDuck, но мне нужно сделать это программно.

У меня есть файл.PPK от поставщика, который я использовал в CyberDuck. У меня есть имя пользователя. У меня есть имя хоста. Если я открою файл PPK, я вижу некоторые публичные линии, частные линии и Private-MAC.

Есть ли в любом случае я могу получить доступ к серверу, чтобы делать то, что мне нужно, используя информацию, которую у меня есть?

Вот код, с которым я играл:

<?php if (!function_exists("ssh2_connect")) die("function ssh2_connect doesn't exist");
?>
<?php
$conn = ssh2_connect('hostname.com', 22);
echo $conn;
ssh2_auth_pubkey_file($conn,'USERNAME','/var/www/html/FILENAME.PPK');

// send a file
ssh2_scp_send($conn, '/var/www/html/FILETOSEND.TXT', 'FILETOSEND.TXT', 0644);
?>

Я не получаю никаких ошибок, но файл не отображается на сервере. Я могу подтвердить, что SSH2 установлен на моем веб-хосте.

Спасибо за любую помощь, которую вы можете предоставить.

Ответ 1

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

Во-первых: измените формат ключа с .ppk на .pem

Ключи .pkk представляют собой закрытый ключ формата PuTTY.

Если вы хотите изменить это на формат .pem, вам нужно установить putty-tools с помощью:

sudo apt install putty-tools

(На Mac установите пакет putty с помощью homebrew. Для Windows я понятия не имею.)

Затем вы можете изменить формат ключа:

puttygen privatekey.ppk -O private-openssh -o privatekey.pem

На всякий случай, если вы хотите извлечь открытый ключ из этого закрытого ключа (остальная часть ответа вам не понадобится, но на всякий случай), это довольно просто:

openssl rsa -in privatekey.pem -pubout > publickey.pub

Второе: войдите с помощью sFTP

Теперь, когда у вас есть privatekey.pem, вы можете использовать phpseclib для подключения через SFTP. Сначала установите phpseclib с помощью Composer:

composer require phpseclib/phpseclib

Тогда в PHP:

require "vendor/autoload.php";

use phpseclib\Crypt\RSA;
use phpseclib\Net\SFTP;

$sftp = new SFTP('sftp.server.com');

// create new RSA key
$privateKey = new RSA();

// in case that key has a password
$privateKey->setPassword('private key password');

// load the private key
$privateKey->loadKey(file_get_contents('/path/to/privatekey.pem'));

// login via sftp
if (!$sftp->login('username', $privateKey)) {
    throw new Exception('sFTP login failed');
}

// now you can list what in here
$filesAndFolders = $sftp->nlist();

// you can change directory
$sftp->chdir('coolstuffdir');

// get a file
$sftp->get('remoteFile', 'localFile');

// create a remote new file with defined content
$sftp->put('newfile.txt', 'new file content');

// put a local file
$sftp->put('remote.txt', 'local.txt', NET_SFTP_LOCAL_FILE);

Если вам нужна дополнительная информация, перейдите в список функций phpseclib sFTP.

Ответ 2

если я могу поделиться своими выводами, основанными на образце кода, на который ответил Стефан Ле Соллик, вы, ребята, должны проверить свою версию phpseclib. чтобы проверить версию phpseclib по composer (windows), вам просто нужно ввести в командной строке composer require phpseclib/phpseclib, результат покажет версию, если она установлена.

Если версия phpseclib - 1.0, я предлагаю изменить строку $sftp = new SFTP('sftp.server.com'); на $sftp = new NET_SFTP('sftp.server.com');

Если версия phpseclib 2.0, я предлагаю изменить строку $sftp->put('remote.txt', 'local.txt', NET_SFTP_LOCAL_FILE); на $sftp->put('remote.txt', 'local.txt', SFTP::SOURCE_LOCAL_FILE);.

Спасибо.