用 php 远程登录。控制远程 APC PDU

Posted

技术标签:

【中文标题】用 php 远程登录。控制远程 APC PDU【英文标题】:Telnet with php. Control remote APC PDU 【发布时间】:2012-08-23 17:34:41 【问题描述】:

我正在尝试通过执行一些 php 命令来控制远程电源开关。

我正在使用一个 telnet 库来建立 telnet 连接:http://www.soucy.org/project/cisco/source.php

我的连接函数如下所示:

public function connect() 

    $this->_connection = fsockopen($this->_hostname, $this->_port, $errno, $errstr, $this->_timeout);
    if ($this->_connection === false) 
        die("Error: Connection Failed for $this->_hostname\n");
     // if
    stream_set_timeout($this->_connection, $this->_timeout);
    $this->_readTo(':');
    if (substr($this->_data, -9) == 'Username:') 
        $this->_send($this->_username);
        $this->_readTo(':');
     // if
    $this->_send($this->_password);

    $this->_send(''); //blank space, because we need to press <Enter> for the second login prompt 

   //Login Second time

    $this->_send($this->_username2);
    $this->_send($this->_password2);

发送函数如下所示:

private function _send($command) 

    fputs($this->_connection, $command . "\r\n");
 

因此,如果我们要控制远程电源开关,则有一个菜单。在这个菜单中,用户可以这样导航:

------- 控制台 -------------------------------------- ------------------

 1- Device Manager
 2- Network
 3- System
 4- Logout

 <ESC>- Main Menu, <ENTER>- Refresh

当我们按 1 时,我们将转到另一个菜单:

------- 设备管理器 -------------------------- ------------------

 1- Bank Monitor
 2- Outlet Management
 3- Power Supply Status

 <ESC>- Back, <ENTER>- Refresh

等等...所以我们只需输入这些数字就可以访问我们想要的插座。

重新加载插座的功能(插座号 22):

public function ReloadOutlet22() 


$this->_send('1'); // Access Device Manager
$this->_send('2'); // Access Outlet Management
$this->_send('1'); // Outlet Control/Configuration
$this->_send();    // '<Enter> to continue'
$this->_send('22'); // Access Outlet number 22
$this->_send('6');  // Delayed Reboot (reboot with 5 sec delay)
$this->_send('YES'); // 'Yes' to continue
$this->_send();      // <Enter> to continue'

//Everything is working till there. I can successfully reload the outlet which I want. After the reload I want to go to the main menu and logout from this console.

$this->_send('\e');  // <Esc> - back
$this->_send('\e');  // <Esc> - back
$this->_send('\e');  // <Esc> - back
$this->_send('\e');  // <Esc> - back
$this->_send('\e');  // <Esc> - back
$this->_send('4');   // Logout

所以有问题。下次,当我想重新加载另一个插座时,例如编号为 23 的插座,我无法成功登录 APC PDU。我可以在登录提示中看到尝试使用 '\e' 作为用户名和密码。

所以也许你们有一个想法,为什么在成功重新加载后我的代码不能正常工作?为什么我无法返回主菜单并退出?

感谢您的宝贵时间。

【问题讨论】:

您确定需要 5 个 esc 序列才能返回吗?当您简单地断开并重新连接时会发生什么? 如果我只是简单地断开并重新连接,我仍然会登录。如果我想重新加载不同的电源插座,如果我可以注销会更简单。否则我的“重启插座”序列将不起作用。感谢您的回答! 您的问题描述听起来好像您发送的 esc 序列比必要的多,也许您需要在回来的路上解析屏幕? 如果我想进入可以通过按数字 4 使用“注销”命令的主菜单,我需要使用 5 个转义序列。但看起来脚本有时会在发送“YES”命令后停止。 【参考方案1】:

您可能需要在 "\e" 周围加上双引号 - 单引号将其视为文字字符串(没有像 \n 这样的转义序列)

$this->_send("\e");  // <Esc> - back

如果这不起作用,请使用

$this->_send(chr(27));  // <Esc> - back

使用数字 ASCII 值发送转义键

http://php.net/manual/en/function.chr.php

【讨论】:

我不知道为什么,但是会话以某种方式挂起,当我尝试重新加载另一个插座时无法正常登录。感谢您提供转义键序列,我会使用它! 当通过 SSH 连接到服务器时,您可能需要在发送密码后休眠一两秒才能运行登录脚本(以及启动硬盘驱动器),然后再发送任何命令。在您发送密码和实际看到登录提示之间,服务器将丢弃任何输入。睡 2-3 秒为我解决了这个问题。 是的,亲爱的罗伯特,我尝试使用它,但如果我使用例如 sleep(3);在我的 php 代码上执行命令我会收到以下错误:严重性:通知消息:fputs(): send of 2 bytes failed with errno=32 Broken pipe 也许您需要在第二次登录之前读取服务器发送的所有内容(以清除缓冲区) 另外,您的发送命令会附加 \r\n,因此您实际上是在按 并在每个数字后按 Enter。可能不是你想要的【参考方案2】:

APC 提供控制台(基于文本的菜单驱动),以及它们的命令行界面(“CLI”),它接受各种特定于控制 PDU 插座的命令行。

要使用命令行界面而不是控制台,请在使用 telnet 登录时将“-c”附加到您的密码 - 即,如果您的 telnet 密码是“abcdefg”,则使用密码“abcdefg -c”登录进入 CLI。 CLI 命令提示符是“APC>”。

重启(重启)插座的 CLI 命令很简单:

APC> reboot x
(x = the outlet number to power cycle)

【讨论】:

谢谢!太棒了,一直在找这个!我会努力的!

以上是关于用 php 远程登录。控制远程 APC PDU的主要内容,如果未能解决你的问题,请参考以下文章

windows怎么打开远程登录

windows远程登录Linux

如何远程使用PHP云主机的MYSQL

windows:shellcode 代码远程APC注入和加载

如何通过修改注册表取消远程桌面连接登录密码

用openssh/sftp实现远程文件传输控制