类SSH php套接字服务器

lf5gs5x2  于 2023-05-16  发布在  PHP
关注(0)|答案(3)|浏览(197)

我有一个CLI php脚本,它收集用户输入,处理它,并基于它返回信息。目前,只有当您SSH进入PHP所在的服务器并运行php scriptname.php时才能使用它,但是,我知道PHP可以创建套接字服务器。有没有可能创建一个套接字服务器,它监听连接,一旦用户连接,就为脚本提供一个类似终端的环境,直到用户断开连接?对于每个连接的用户,它也将是脚本的不同示例。不需要身份验证。
编辑:如果这在PHP中不可能实现,还有其他选择吗?
编辑:我使用的一些代码如下
对于收集用户输入:

echo "Enter a command or question... \n";
  $line = $this->input();
  $line = trim($line);

这将调用input函数,该函数将使用readline获取用户输入并返回它,然后脚本解释输入并基于它生成响应,然后将请求更多的输入。这个脚本不会结束,除非你告诉它,我想能够通过PHP套接字服务器或类似的连接到它,这样我就可以发送命令,而不使用SSH。
编辑:所以,我尝试了xinetd服务器,我可以连接到它,但readline和许多其他东西,包括通过SSH访问时工作的格式不再与telnet工作。是否有其他方法来做到这一点或方法来配置它更灵活的格式和readline?

92dk7w1h

92dk7w1h1#

当然有可能。你不需要一个Apache Web服务器,或者PHP's built in web server或类似的东西。我的意思是你可以使用这些东西,但最简单的只是写一个PHP脚本,让它监听一些端口。要么调整你的脚本,要么写另一个在套接字和脚本之间传输stdio的脚本。一般来说,如果你用C写代码,你会使用任何系统C库或POSIX库,都有PHP Package 器。在您的情况下,您可能希望使用Sockets。在PHP sockets docs中有很多例子。
这是一个简单的PHP回显服务器--它只是打印回您键入的任何内容。我不记得我是从哪里得到这个的,很抱歉缺乏attibutation:

error_reporting(E_ALL);

/* Allow the script to hang around waiting for connections. Only applies to httpd module. */
set_time_limit(0);

/* Turn on implicit output flushing so we see what we're getting as it comes in. Only applies to httpd module.*/
ob_implicit_flush();

$address = '127.0.0.1';
$port = 10000;

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
}
if (socket_bind($sock, $address, $port) === false) {
    echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}
if (socket_listen($sock, 5) === false) {
    echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}
do {
    if (($msgsock = socket_accept($sock)) === false) {
        echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
        break;
    }
    /* Send instructions. */
    $msg = "\nWelcome to the PHP Test Server. \n" .
        "To quit, type 'quit'. To shut down the server type 'shutdown'.\n";
    socket_write($msgsock, $msg, strlen($msg));
    do {
        if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
            echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n";
            break 2;
        }
        if (!$buf = trim($buf)) {
            continue;
        }
        if ($buf == 'quit') {
            break;
        }
        if ($buf == 'shutdown') {
            socket_close($msgsock);
            break 2;
        }
        $talkback = "PHP: You said '$buf'.\n";
        socket_write($msgsock, $talkback, strlen($talkback));
        echo "$buf\n";
    } while (true);
    socket_close($msgsock);
} while (true);
socket_close($sock);
hsgswve4

hsgswve42#

这个问题可能是旧的,但在这里我分享一个可能实现你想要的。实际上它被称为远程shell,客户端连接到服务器,客户端可以控制服务器。
下面的代码是一个例子(概念验证),需要在安全性,内存管理,客户端处理程序等方面进行更多的改进,以使其在生产中有效运行。
server.php

error_reporting(0);
set_time_limit(0);
ob_implicit_flush();

$address = "192.168.0.150";
$port = 10000;

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sock, $address, $port);
socket_listen($sock, 5);

while(true){
    $client = socket_accept($sock);
    $input = socket_read($client, 2048, PHP_NORMAL_READ);
    $output = shell_exec($input) . "\n";

    socket_write($client, $output, strlen($output));
    socket_close($client);
}

client.php

while(true){
    $fp = fsockopen("192.168.0.150", 10000, $errno, $errstr, 3600);
    echo ">";
    $f = fopen("php://stdin", "r");
    $out = fgets($f);
    
    fwrite($fp, $out);
    while (!feof($fp)) {
        echo fgets($fp);
    }
    
    fclose($fp);
}

上面的代码打开一个端口10000并接受来自客户端的连接。即使客户端关闭连接,端口仍在等待(仅支持单客户端)。
服务器实际上只是接收一个字符串,并以shell_exec(不安全的方式)执行它,然后将其返回给客户端。这意味着,客户端现在可以控制服务器的“类ssh”终端。

7gs2gvoe

7gs2gvoe3#

我使用@Barmar的评论来帮助我设置xinetd服务器。
您需要将脚本添加到服务文件**/etc/services**中:

...
myservice port/tcp # my service

然后添加xinetd配置文件**/etc/inetd.d/myservice**

# default: on
# description: service script

service myservice
{
        socket_type             = stream
        protocol                = tcp
        wait                    = no
        user                    = gleblanc
        server                  = /usr/bin/php
        server_args             = /home/service/scriptname.php
        log_on_success          += DURATION
        nice                    = 10
        disable                 = no
}

相关问题