【问题标题】:Connect to SFTP using PHP and private key使用 PHP 和私钥连接到 SFTP
【发布时间】:2015-03-31 03:42:28
【问题描述】:

我已经阅读了一篇又一篇文章,但找不到适合我所拥有的“解决方案”。

我正在尝试使用 php 脚本通过 SFTP 上传文件。我已使用 Cyber​​Duck 成功连接,但我需要以编程方式进行。

我在 Cyber​​Duck 中使用了来自供应商的 .PPK 文件。我有一个用户名。我有主机名。如果我打开 PPK 文件,我会看到一些 Public Lines、Private Lines 和 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。

感谢您提供的任何帮助。

【问题讨论】:

  • 我强烈建议您使用phpseclib 来实现您想要实现的目标。它比php内置的ssh2功能要好得多,而且非常容易使用
  • 您似乎不知道 ssh2_auth_pubkey_file 需要 4 个参数而不是 3 个。php.net/manual/en/function.ssh2-auth-pubkey-file.php
  • @charlotte,我确实看到了这就是我认为我遇到问题的原因。我可以将 PPK 文件拆分为缺少的元素吗?
  • @michael,谢谢,我会看看
  • ppk 扩展名表示密钥是 PuTTY 格式的私钥。 libssh2 仅适用于 PKCS1 格式的私钥。 phpseclib - 由 michael 推荐 - 支持两者。见phpseclib.sourceforge.net/ssh/compare.html#pubkey

标签: php sftp libssh2


【解决方案1】:

这个问题很老了,但是当我在寻找完全相同的答案时,这是我设法收集到的。

首先:将密钥格式从 .ppk 更改为 .pem

.pkk 密钥是 PuTTY 格式的私钥。

如果要将其更改为 .pem 格式,则需要安装 putty-tools:

sudo apt install putty-tools

(在 Mac 上,使用 homebrew 安装 putty 包。对于 Windows,我不知道。)

然后你可以改变key的格式:

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

以防万一您想从该私钥中提取公钥,(您不需要该答案的其余部分,但以防万一)这很容易:

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

第二种:使用sFTP登录

现在您有了privatekey.pem,您可以使用phpseclib 通过SFTP 进行连接。首先,用 Composer 安装 phpseclib:

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's 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 feature list

【讨论】:

  • 如果您使用的是 phpseclib,则无需将 ppk 格式的密钥转换为 pem。 phpseclib 内置支持 ppk 格式的密钥。
  • 如果NET_SFTP_LOCAL_FILE 有错误,请尝试SFTP::SOURCE_LOCAL_FILE
【解决方案2】:

如果我可以根据 Stéphane Le Solliec 回答的代码示例分享我的发现,你们必须检查你的 phpseclib 版本。要通过 composer (windows) 检查 phpseclib 版本,您只需在命令提示符下输入composer require phpseclib/phpseclib,如果安装,结果将显示版本。

如果phpseclib版本是1.0,建议修改$sftp = new SFTP('sftp.server.com');$sftp = new NET_SFTP('sftp.server.com');

如果phpseclib版本是2.0,我建议你修改$sftp-&gt;put('remote.txt', 'local.txt', NET_SFTP_LOCAL_FILE);$sftp-&gt;put('remote.txt', 'local.txt', SFTP::SOURCE_LOCAL_FILE);

谢谢。

【讨论】:

    【解决方案3】:

    您可以使用 Flysystem 的 sftp 适配器进行 php。您可以使用 composer 安装在任何框架中使用它。 Flysystem Filesystem Abstraction for PHP(PHP 库)。

    https://flysystem.thephpleague.com/v2/docs/
    

    使用命令安装库。

    composer require league/flysystem-sftp:^2.0
    

    使用下面的代码通过文件系统连接 SFTP。

    <?php
    require_once('vendor/autoload.php');
    use League\Flysystem\Filesystem;
    use League\Flysystem\PhpseclibV2\SftpConnectionProvider;
    use League\Flysystem\PhpseclibV2\SftpAdapter;
    use League\Flysystem\UnixVisibility\PortableVisibilityConverter;
    use League\Flysystem\DirectoryAttributes;
    use League\Flysystem\FileAttributes;
    $private_key='sftp_keys/new_private.ppk';
    
    $filesystem = new Filesystem(new SftpAdapter(
        new SftpConnectionProvider(
            'host', // host (required)
            'username', // username (required)
            null, // password (optional, default: null) set to null if privateKey is used
            $private_key, // private key (optional, default: null) can be used instead of password, set to null if password is set
            null, // passphrase (optional, default: null), set to null if privateKey is not used or has no passphrase
            22, // port (optional, default: 22)
            false, // use agent (optional, default: false)
            30, // timeout (optional, default: 10)
            10, // max tries (optional, default: 4)
            null, // host fingerprint (optional, default: null),
            null // connectivity checker (must be an implementation of 'League\Flysystem\PhpseclibV2\ConnectivityChecker' to check if a connection can be established (optional, omit if you don't need some special handling for setting reliable connections)
        ),
        '/', // root path (required)
        PortableVisibilityConverter::fromArray([
            'file' => [
                'public' => 0640,
                'private' => 0604,
            ],
            'dir' => [
                'public' => 0740,
                'private' => 7604,
            ],
        ])
    ));
    $allFiles = $filesystem->listContents('Outbound')->toArray();
    $response = $filesystem->write('Outbound/info.txt', 'Hello How are you',array());
    if($response){
        echo "Success";
    }else echo "Error";
    print_r($allFiles );
    ?>
    

    Composer.json 看起来像

    {
        "name": "league/flysystem-sftp",
        "description": "Flysystem adapter for SFTP",
        "license": "MIT",
        "authors": [
            {
                "name": "Frank de Jonge",
                "email": "info@frenky.net"
            }
        ],
        "require": {
            "php": ">=5.6.0",
            "league/flysystem-sftp": "^2.1",
            "phpseclib/phpseclib": "~2.0"
        },
        "require-dev": {
            "mockery/mockery": "0.9.*",
            "phpunit/phpunit": "^5.7.25"
        },
        "autoload": {
            "psr-4": {
                "League\\Flysystem\\Sftp\\": "src/"
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-28
      • 2020-06-24
      • 1970-01-01
      • 2022-06-15
      • 1970-01-01
      • 2021-10-18
      • 1970-01-01
      • 2022-10-17
      相关资源
      最近更新 更多