phpseclib 3 accepts an open stream resource where its SSH/SFTP constructor would otherwise receive a hostname. That is the public handoff point for a connection already carried through a proxy.

First, the connector establishes an HTTP CONNECT or SOCKS tunnel to the actual SFTP server and port. Then pass the established stream to 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 is an existing connected stream, not a proxy URL. $expectedHostKey is the server's trusted public-key string obtained through the application's provisioning process, in the format returned by phpseclib. The login credential can be the supported password or loaded key object selected by the application.

Define what the connector returns

The stream must already lead to the SFTP server. For HTTP CONNECT, this means the proxy has accepted the destination and the complete proxy response headers have been consumed. For SOCKS, the relevant negotiation must have completed successfully. Any SSH bytes already read beyond that boundary must remain available to the SSH implementation.

At that point, phpseclib performs the SSH exchange and starts SFTP over the same stream. The application can use its ordinary SFTP operations. The constructor interface avoids an application subclass whose job is to replace internal socket fields.

Mikanda mikatakata