Можно ли установить ssh соединение через прокси используя php?
Мой php код
$connection = ssh2_connect('x.x.x.x');
Но это дает ошибку ниже
PHP Warning: ssh2_connect(): Unable to connect to x.x.x.x
Я не могу установить ssh соединение через командную строку тоже.
ssh [email protected]
Решение (FAIL)
Тогда я нашел решение. я создал **~/.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. Есть ли способ сказать функции использовать его?
Действительно возможно и довольно просто с помощью phpseclib. Ранее использовал php ssh2 и работал нормально, но не было никакого известного способа установить соединение через прокси. phpseclib сравнительно лучше, чем php ssh2. Это означает, что нет 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;
}
Таким образом, вы туннелируете соединение с x.x.x.x через Штопор, который, я полагаю, требует прокси HTTP CONNECT для работы.
HTTP CONNECT — это довольно простой протокол, поэтому я позволю вам разобраться с этим, но, как только вы это сделаете, вы можете использовать phpseclib (который я должен отметить, что вы на самом деле не используете его в своем посте orig), чтобы изменить объект сокета — для своего рода подготовить объект сокета. то есть. поэтому вместо передачи имени хоста и номера порта конструктору вы передаете сокет. Пример кода:
<?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