通过代理建立SSH连接的PHP方法

4

是否可能使用PHP通过代理建立SSH连接?

我的PHP代码如下:

$connection = ssh2_connect('x.x.x.x');

但是它会给出以下错误提示:
PHP Warning:  ssh2_connect(): Unable to connect to x.x.x.x

我也无法通过命令行建立ssh连接。

ssh root@x.x.x.x

解决方案(失败)

接着我找到了解决方案。我创建了**~/.ssh/config**文件,并在其中添加了代理定义。

Host x.x.x.x
    Hostname x.x.x.x
    User root
    ProxyCommand /usr/bin/corkscrew proxy.somewebsite.com 10080 %h %p

之后我可以通过命令行连接到ssh :)

但是我仍然无法通过php代码连接。我仍然得到相同的错误 :(

问题在于ssh2_connection函数没有使用ssh配置文件。有没有办法告诉函数使用它?

2个回答

2

使用phpseclib是完全可能的,而且相当简单。之前使用过php ssh2并且工作正常,但没有已知的方法通过代理建立连接。与php的ssh2相比,phpseclib更好。这意味着如果您正在使用ssh2_connect,则无法使用它。下面是一个对我有效的示例代码:

public function connect()
        {
            $auth = base64_encode($this->proxyUser.':'.$this->proxyPass);

            $fsock = fsockopen($this->proxyHost, $this->proxyPort);
            $request = "CONNECT $this->ssh_host:$this->ssh_port HTTP/1.0\r\nContent-Length: 0\r\nProxy-Authorization: Basic $auth\r\n\r\n";

            if(fputs($fsock, $request) != strlen($request)) {
                sys_error("Unable to connect to proxy");
            }

            $response = fgets($fsock); //Response should be 'Connection Established'

            $this->sftp = new Net_SFTP($fsock);  //Will work similarly for Net_SSH

            if(!$this->sftp->login($this->ssh_auth_user, $this->ssh_auth_pass)){
                sys_error('Login to sftp server failed');
                return false;
            }

            return true;
        }

2
与ssh2_connect相比,这种语法太糟糕了。 - Viktor Joras

0

那么你正在通过Corkscrew隧道连接到x.x.x.x,我假设这需要HTTP CONNECT代理才能工作。

HTTP CONNECT是一个相当简单的协议,所以我会让你自己解决,但是一旦你解决了这个问题,你可以使用phpseclib(我要注意的是,在你的原始帖子中实际上没有使用它)来更改套接字对象-从而准备套接字对象。即,所以你不是将主机名和端口号传递给构造函数,而是传递套接字。例如代码:

<?php
// http://us3.php.net/manual/en/context.socket.php
$opts = array(
    'socket' => array(
        'bindto' => '192.168.1.100:0',
    ),
);
$context = stream_context_create($opts);
$socket = stream_socket_client('tcp://example.net:80', $errno, $errstr, ini_get('default_socket_timeout'), STREAM_CLIENT_CONNECT, $context);

$ssh = new Net_SSH2($socket); 

更多信息:

https://github.com/phpseclib/phpseclib/issues/742#issuecomment-122351289


谢谢@neubert,我现在无法尝试它。我会在周一尝试并告诉您结果。 - Farid Movsumov
发布你的代码。我发布的不是一个合适的HTTP CONNECT客户端 - 我发布的只是一个示例,展示了如何对phpseclib将使用的套接字资源进行更改。你需要进行的更改与我发布的不同。我的帖子只是一个使用修改后的套接字的示例。 - neubert
我已经修改了你的代码以满足我的要求,但不幸的是它对我不起作用。抱歉,我现在没有那个代码。 - Farid Movsumov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接