如何通过PHP SSH经路由器R1访问R2并实现任务自动化
解决方案:通过R1跳板SSH访问R2并执行命令
方法1:SSH端口转发(推荐)
先在R1上建立端口转发,将本地端口映射到R2的SSH端口,实现直接从PC访问R2,无需交互式输入:
<?php // 连接R1 $r1Connection = ssh2_connect('IP of R1', 22); ssh2_auth_password($r1Connection, 'username_r1', 'password_r1'); // 建立端口转发:本地2222端口映射到R2的22端口 ssh2_tunnel($r1Connection, 'IP of R2', 22, '127.0.0.1', 2222); // 通过本地转发端口连接R2 $r2Connection = ssh2_connect('127.0.0.1', 2222); ssh2_auth_password($r2Connection, 'username_r2', 'password_r2'); // 在R2执行命令并获取输出 $stream = ssh2_exec($r2Connection, 'your_command_on_r2'); stream_set_blocking($stream, true); $output = stream_get_contents($stream); echo "<pre>{$output}</pre>"; // 关闭连接 fclose($stream); ssh2_disconnect($r2Connection); ssh2_disconnect($r1Connection); ?>
此方法逻辑清晰,稳定性高,无需处理交互式输入时序问题。
方法2:原生SSH2扩展处理交互式会话
如果无法使用端口转发,可通过交互式shell模拟输入用户名和密码:
<?php // 连接R1 $connection = ssh2_connect('IP of R1', 22); ssh2_auth_password($connection, 'username_r1', 'password_r1'); // 创建交互式shell $shell = ssh2_shell($connection, 'xterm'); stream_set_blocking($shell, true); // 发送连接R2的命令 fwrite($shell, "ssh IP_of_R2\n"); sleep(1); // 输入R2用户名 fwrite($shell, "username_r2\n"); sleep(1); // 输入R2密码 fwrite($shell, "password_r2\n"); sleep(1); // 执行目标命令 fwrite($shell, "your_command_on_r2\n"); sleep(2); // 获取输出 $output = stream_get_contents($shell); echo "<pre>{$output}</pre>"; // 关闭连接 fclose($shell); ssh2_disconnect($connection); ?>
注意:sleep时长需根据网络延迟调整,此方法依赖时序稳定性,可靠性略低于端口转发。
方法3:使用phpseclib库(更可靠的交互式处理)
原生SSH2扩展对交互式场景支持有限,推荐用纯PHP的phpseclib库处理:
- 先通过Composer安装:
composer require phpseclib/phpseclib - 编写代码:
<?php require 'vendor/autoload.php'; use phpseclib3\Net\SSH2; // 连接R1 $ssh1 = new SSH2('IP of R1'); if (!$ssh1->login('username_r1', 'password_r1')) { exit('R1登录失败'); } // 启动到R2的SSH连接,处理交互式认证 $ssh1->write("ssh IP_of_R2\n"); $ssh1->setTimeout(5); $ssh1->read('username:'); $ssh1->write("username_r2\n"); $ssh1->read('password:'); $ssh1->write("password_r2\n"); // 等待R2提示符(根据实际提示符修改) $ssh1->read('#'); // 执行命令并读取输出 $ssh1->write("your_command_on_r2\n"); $output = $ssh1->read('#'); echo "<pre>{$output}</pre>"; $ssh1->disconnect(); ?>
phpseclib通过匹配提示符字符串处理交互,无需依赖固定等待时间,稳定性更高。
内容的提问来源于stack exchange,提问作者Subhankar Pandit
相关产品推荐
相关产品推荐

