phpseclib 3 は、通常 SSH/SFTP コンストラクタがホスト名を受け取る位置で、開かれたストリームリソースを受け取ります。これが、すでにプロキシ経由で運ばれている接続の公開された受け渡し点です。

まず、コネクタが実際の SFTP サーバーとポートへの HTTP CONNECT または SOCKS トンネルを確立します。次に、確立されたストリームを SFTP に渡します。

use phpseclib3\Net\SFTP;

$sftp = new SFTP($tunnel);

$actualHostKey = $sftp->getServerPublicHostKey();
if ($actualHostKey === false
    || !hash_equals($expectedHostKey, $actualHostKey)) {
    throw new RuntimeException('Unexpected SFTP server key');
}

if (!$sftp->login($sftpUser, $sftpCredential)) {
    throw new RuntimeException('SFTP login failed');
}

$tunnel は既存の接続済みストリームであり、プロキシ URL ではありません。$expectedHostKey はサーバーの信頼済み公開鍵文字列で、アプリケーションのプロビジョニング手順を通じて取得され、phpseclib が返す形式です。ログイン資格情報は、サポートされているパスワード、またはアプリケーションが選択した読み込み済み鍵オブジェクトです。

コネクタが返すものを定義する

ストリームはすでに SFTP サーバーへ通じている必要があります。HTTP CONNECT の場合、プロキシが宛先を受け入れ、プロキシ応答ヘッダーがすべて消費されていることを意味します。SOCKS の場合は、該当するネゴシエーションが正常に完了している必要があります。その境界を超えてすでに読み取られた SSH バイトは、SSH 実装が利用できる状態に保たなければなりません。

その時点で phpseclib は SSH 交換を実行し、同じストリーム上で SFTP を開始します。アプリケーションは通常の SFTP 操作を使用できます。コンストラクタインターフェースにより、内部ソケットフィールドを置き換えるためのアプリケーションサブクラスが不要になります。

関連記事