PHP - 通过 socks5 代理从私钥连接到 sftp
PHP - Connect to sftp from private key through socks5 proxy
我正在尝试通过代理使用 rsa 私钥身份验证连接到 sftp。
use phpseclib\Net\SFTP;
use phpseclib\Crypt\RSA;
$proxyHost = 'proxy-host';
$proxyPort = 1080;
$fsock = fsockopen($proxyHost, $proxyPort);
$host = 'sftp.hostname.com';
$login = 'sftp_login';
$privatekey = file_get_contents('sftp_private.ppk');
$password = new RSA();
$password->loadKey($privatekey);
$request = "CONNECT $host:22 HTTP/1.0\r\nContent-Length: 0\r\n\r\n";
if(fputs($fsock, $request) != strlen($request)) {
exit("premature termination");
}
while ($line = fgets($fsock, 1024)) {
if ($line == "\r\n") {
break;
}
//echo $line;
}
$sftp = new SFTP($fsock);
if (!$sftp->login($login, $password)) {
exit('Login Failed');
}
我得到 "Login Failed" 出口。
谢谢
引用
https://github.com/phpseclib/phpseclib/issues/1460 :
Port 1080 is typically used for SOCKS5 proxies - not HTTP proxies.
Assuming you're using a SOCKS5 proxy then something like this should
work:
// SSH connection info
$port = 22;
$address = 'localhost';
// SOCKS5 connection info
$fsock = fsockopen('127.0.0.1', 1080, $errno, $errstr, 1);
if (!$fsock) {
throw new \Exception($errstr);
}
$port = pack('n', $port);
$address = chr(strlen($address)) . $address;
$request = "[=10=]";
if (fwrite($fsock, $request) != strlen($request)) {
throw new \Exception('Premature termination');
}
$response = fread($fsock, 2);
if ($response != "[=10=]") {
throw new \Exception('Unsupported protocol or unsupported method');
}
$request = "[=10=]$address$port";
if (fwrite($fsock, $request) != strlen($request)) {
throw new \Exception('Premature termination');
}
$response = fread($fsock, strlen($address) + 6);
if (substr($response, 0, 2) != "[=10=]") {
echo bin2hex($response) . "\n";
throw new \Exception("Unsupported protocol or connection refused");
}
$ssh = new SSH2($fsock);
$ssh->login('username', 'password');
echo $ssh->exec('ls -latr');
That said, SOCKS5 has a lot more bells and whistles then this sample
code currently accommodates. Really, what'd be good is a full on
SOCKS5 class.
希望对其他人有所帮助。
我正在尝试通过代理使用 rsa 私钥身份验证连接到 sftp。
use phpseclib\Net\SFTP;
use phpseclib\Crypt\RSA;
$proxyHost = 'proxy-host';
$proxyPort = 1080;
$fsock = fsockopen($proxyHost, $proxyPort);
$host = 'sftp.hostname.com';
$login = 'sftp_login';
$privatekey = file_get_contents('sftp_private.ppk');
$password = new RSA();
$password->loadKey($privatekey);
$request = "CONNECT $host:22 HTTP/1.0\r\nContent-Length: 0\r\n\r\n";
if(fputs($fsock, $request) != strlen($request)) {
exit("premature termination");
}
while ($line = fgets($fsock, 1024)) {
if ($line == "\r\n") {
break;
}
//echo $line;
}
$sftp = new SFTP($fsock);
if (!$sftp->login($login, $password)) {
exit('Login Failed');
}
我得到 "Login Failed" 出口。
谢谢
引用 https://github.com/phpseclib/phpseclib/issues/1460 :
Port 1080 is typically used for SOCKS5 proxies - not HTTP proxies.
Assuming you're using a SOCKS5 proxy then something like this should work:
// SSH connection info $port = 22; $address = 'localhost'; // SOCKS5 connection info $fsock = fsockopen('127.0.0.1', 1080, $errno, $errstr, 1); if (!$fsock) { throw new \Exception($errstr); } $port = pack('n', $port); $address = chr(strlen($address)) . $address; $request = "[=10=]"; if (fwrite($fsock, $request) != strlen($request)) { throw new \Exception('Premature termination'); } $response = fread($fsock, 2); if ($response != "[=10=]") { throw new \Exception('Unsupported protocol or unsupported method'); } $request = "[=10=]$address$port"; if (fwrite($fsock, $request) != strlen($request)) { throw new \Exception('Premature termination'); } $response = fread($fsock, strlen($address) + 6); if (substr($response, 0, 2) != "[=10=]") { echo bin2hex($response) . "\n"; throw new \Exception("Unsupported protocol or connection refused"); } $ssh = new SSH2($fsock); $ssh->login('username', 'password'); echo $ssh->exec('ls -latr');
That said, SOCKS5 has a lot more bells and whistles then this sample code currently accommodates. Really, what'd be good is a full on SOCKS5 class.
希望对其他人有所帮助。