iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >PHP+Swoole实现web版的shell客户端详解
  • 783
分享到

PHP+Swoole实现web版的shell客户端详解

2024-04-02 19:04:59 783人浏览 薄情痞子
摘要

目录一、前期准备1、安装ssh2拓展库2、swoole安装3、PHPseclib二、编写代码1、swoole.php2、function.php3、运行本来是想通过PHP的proc_

本来是想通过PHP的proc_open和进程进行交互,可是中间的坑太多了,不得不转换一下思路,然后想起来宝塔有网页版shell客户端,然后研究了一下,嘿嘿,发现能成 。

一、前期准备

PHP连接ssh是基于第三方拓展库,PECL/ssh2( libssh2的php扩展,允许php程序调用libssh2中的函数)

然后有一个现成的、封装好大部分常用操作的库phpseclib

通过swoole的协程实现SSH的读和写并发进行以及websocket和浏览器进行通信。

1、安装ssh2拓展库

1.1、Linux安装

首先要安装libssh2(libssh2是一个C 函数库,用来实现SSH2协议。)

yum install libssh2 libssh2-devel 

然后通过pcel安装ssh2拓展 ,找准版本

pecl install ssh2-1.1.2

当然也可以通过phpize进行手动安装。

1.2、window安装

libssh2好像一般都有,没有就下载丢到系统里,主要是安装ssh2。根据自己PHP的版本去下载,可以看下自己的php版本,以及是32位的还是64位的,32位的下载x86, 64位的下载x64

下载地址

php.ini中加入 extension=php_ssh2.dll ,完事。

2、swoole安装

参考官网:https://wiki.swoole.com/#/environment

3、phpseclib

官网:Https://phpseclib.com,composer安装即可:

composer require phpseclib/phpseclib:~3.0

二、编写代码

测试Demo:http://cname.teiao.com:5707/

通过swoole创建一个WEBSocket,连接成功时创建一个协程专门读取ssh返回的内容发送到websocket,客户端发送消息时转发给shell。

以下是简单的功能实现,不可应用于生产,经测试,实际使用过程中某些命令的输出需要进行特殊处理。

1、swoole.php

<?php

include_once 'include/functions.php';
include_once 'vendor/autoload.php';

use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\WebSocket\CloseFrame;
use Swoole\Coroutine\Http\Server;

use Swoole\Coroutine;
use function Swoole\Coroutine\Go;
use function Swoole\Coroutine\run;
use function Swoole\Coroutine\defer;
use phpseclib3\Net\SSH2;




Co::set([
    'socket_timeout'=>-1, //tcp超时
    'hook_flags' => SWOOLE_HOOK_ALL  //HOOK函数范围
]);



run(function () {

    
    $server = new Server('0.0.0.0', 5707, false);

    $server->handle('/ws', function (Request $request, Response $ws) {

        
        $ws->upgrade();

        
        $ssh = new SSH2('localhost',22);

        
        if (!$ssh->login('root', 'Qq461625091@')) {
            $ws->close();
            return;
        }

        
        $ssh->setTimeout(0.1);



        
        $subscribe=function () use($ws,$ssh){


            
            $ws->Gid = go(function () use ($ws,$ssh){

                
                defer(function () use ($ssh,$ws) {
                    
                    logs($ws->qq.',已断开链接!');
                    $ssh->disconnect();
                });


                try {

                    while (true){
                        $msg=$ssh->read('username@username:~$');
                        if(!empty($msg)){
                            $ws->push($msg);
                        }
                    }

                } catch (\Throwable $e) {
                    logs('读取异常');
                }

            });
        };


        
        $quit=function ($log) use ($ws){

            logs($log);//记录退出原因

            
            if(isset($ws->Gid)){
                Coroutine::cancel($ws->Gid); //关闭协程
            }

            $ws->close(); //断开ws

        };


        

        $subscribe(); //开始订阅

        $cmd=[
            'ps -ef',
            'ping 127.0.0.1',
            'ifconfig',
            "\x03"
        ];


        while (true) {

            $frame = $ws->recv(); //阻塞接收消息

            if ($frame === '') {

                $quit("断开连接,收到空数据!");
                break;

            } else if ($frame === false) {

                $quit(swoole_last_error());
                break;

            } else {

                if ($frame->data == 'close' || get_class($frame) === CloseFrame::class) {
                    $quit("用户主动关闭\n");
                    break;
                }

                
                if(!in_array($frame->data,$cmd)){
                    continue;
                }

                $ssh->write($frame->data."\n"); // note the "\n"

            }
        }
    });


    
    $server->handle('/', function (Request $request, Response $response) {
        $response->end(getTest());
    });

    $server->start();
});

2、function.php


<?php


function getTest(): string
{
    $test = <<<html
        <!DOCTYPE html>
        <html lang="zh-cn" xmlns="http://www.w3.org/1999/html">
        <head>
            <meta charset="UTF-8"/>
            <meta charset="UTF-8"/>
            <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-Scalable=no">
            <title>Web SSH客户端</title>
            <link href="https://nicen.cn/wp-content/themes/document/favicon.ico" rel="external nofollow"  rel="shortcut icon" type="image/x-icon"/>
            <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/Jquery/3.6.0/jquery.min.js" type="application/javascript"></script>
            <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/keyboardjs/2.6.2/keyboard.min.js" type="application/javascript"></script>
            <style>
                body{
                    background-color: #000000;
                    color: #e2e2e2;
                    padding: 15px;
                }
                 input{
                    background-color: black;
                    border: none;
                    color: white;
                    outline: none;
                    font-size: 17px;
                }
            </style>
        </head>
        <body>
        <h1>Web SSH测试</h1>
        <div>须知:测试环境只支持:ps -ef、ping 127.0.0.1、ifconfig,三个命令。</div>
        <div>提示:回车提交、ctrl+c中断(终端现在连接的是网站的主机)</div>
        <br />
        <main>
             <span id="content"></span>
             <input type="text">
        </main>

        </body>
        <script>

         window.onload=function (){

            let content=$("#content");
            let input= $('input');
            let wsServer = 'ws://cname.teiao.com:5707/ws';
            let websocket = new WebSocket(wsServer);

            websocket.onopen = function (evt) {
                content.append("Connected to WebSocket server.<br />");
            };

            websocket.onclose = function (evt) {
                content.append("Disconnected.<br />");
            };

            websocket.onmessage = function (evt) {
                content.append(evt.data.replaceAll("\\n",'<br />'));
                input.val("");
                $(window).scrollTop(document.documentElement.scrollHeight)  
            };

            websocket.onerror = function (evt, e) {
                content.append("Error occured: " + evt.data+"<br />");
            };


            input.focus();

            
            $(window).on("click",function (){
                input.focus();
            })

            
            keyboardJS.bind('enter', (e) => {
              websocket.send(input.val());
            });

            
             keyboardJS.bind('ctrl > c', (e) => {
              websocket.send("\x03");
            });
        }


        </script>
HTML;

    return $test;
}



function logs(string $log, bool $flag = true): void
{
    $time = date("Y-m-d H:i:s", time());

    if ($flag) {
        echo $time . ',' . $log . "\n";
    } else {
        file_put_contents('log.txt', $time . ',' . $log . "\n", FILE_APPEND);
    }
}

3、运行

php swoole.php

以上就是PHP+Swoole实现web版的shell客户端详解的详细内容,更多关于PHP Swoole shell客户端的资料请关注编程网其它相关文章!

--结束END--

本文标题: PHP+Swoole实现web版的shell客户端详解

本文链接: https://www.lsjlt.com/news/165357.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • PHP+Swoole实现web版的shell客户端详解
    目录一、前期准备1、安装ssh2拓展库2、swoole安装3、phpseclib二、编写代码1、swoole.php2、function.php3、运行本来是想通过PHP的proc_...
    99+
    2024-04-02
  • Pythonasyncoresocket客户端实现方法详解
    目录介绍1.定义类并且继承 asyncore.dispatcher2.实现类中的回调代码调用父类方法创建socket对象连接服务器3.创建对象并且执行asyncore.loop进入运...
    99+
    2022-12-22
    Python asyncore socket Python asyncore库
  • 详解Golang语言HTTP客户端实践
    目录HTTP客户端封装 测试脚本 测试服务 最近在学习Golang语言,中间遇到一个前辈指点,有一个学习原则:Learning By Doing。跟我之前学习Java的经验高度契合。...
    99+
    2024-04-02
  • Java Socket实现Redis客户端的详细说明
    Redis是最常见的缓存服务中间件,在java开发中,一般使用 jedis 来实现。 如果不想依赖第三方组件,自己实现一个简单的redis客户端工具,该如何实现呢?本文就是介绍这样一...
    99+
    2024-04-02
  • Spring Cloud实现提供API给客户端的方法详解
    前言现在越来越多的公司开始拥抱Spring Cloud了,Spring Boot做为下一代 web 框架,Spring Cloud 作为最新最火的微服务的翘楚,你还有什么理由拒绝。很多Java方向的同学也开始积极的学习Spring Clou...
    99+
    2023-05-30
  • Android socket实现原理详解 服务端和客户端如何搭建
    本文实例为大家分享了Android socket的实现原理,供大家参考,具体内容如下Socket套接字 是网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。socket实现的原理机制:通信的两端都有Socket...
    99+
    2023-05-30
    android socket roi
  • redis客户端实现高可用读写分离的方式详解
    背景 (1) redis单机的读写性能轻松上大几万,不过线上环境不会只部署光秃秃的一个节点,还是会配合 sentinel 再部署一个 slave作为高可用节点的; 但是standby...
    99+
    2024-04-02
  • 客户端JavaScript的线程池设计详解
    目录1.介绍:2.准备工作:3.测试spark-md5是否正常工作:4.线程池设计5.spark-md5对文件进行md5编码6.大量文件进行MD5加密并使用线程池优化总结1.介绍: ...
    99+
    2024-04-02
  • C#编写网游客户端的实现
    目录一、项目初步设置 二、连接服务器三、发送数据四、播放背景音乐五、实现游戏背景图片变换六、总结参考一、项目初步设置 1. 新建项目 新建一个WIndows 窗体应用(.Net F...
    99+
    2024-04-02
  • PHP 实现支付宝APP 支付 (服务端 + 客户端 + 异步)
    目录 一、使用实例 二、服务端 1.下载SDK 2.业务层 3.业务层返回实例 推荐使用联调工具: 4.回调层 三、客户端 总结 一、使用实例 官方信息: 二、服务端 1.下载SDK App 支付服务端 DEMO&...
    99+
    2023-09-18
    python pandas php mysql thinkphp
  • PHP+Socket如何实现客户端与服务端数据传输
    这篇文章主要介绍“PHP+Socket如何实现客户端与服务端数据传输”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“PHP+Socket如何实现客户端与服务端数据传输”文章能帮助大家解决问题。sock...
    99+
    2023-07-05
  • C++实现一个简单的SOAP客户端
    目录1、简介2、实现客户端2.1 准备xml文件2.2 引入库文件2.3 构建请求数据的xml2.4 执行Http协议的POST方法2.5 解析响应数据的xml3、测试客户端1、简介...
    99+
    2024-04-02
  • nginx配置客户端保存cookie的实现
    目录问题解决问题 昨晚在部署一个前人留下的dotnet core后台服务,在服务器上小心翼翼的修改前端代码,把ajax请求地址换成了localhost,登录、请求数据正常。但是把lo...
    99+
    2023-03-07
    nginx客户端保存cookie nginx 保存cookie
  • 如何解决C#版Nebula客户端编译的问题
    小编给大家分享一下如何解决C#版Nebula客户端编译的问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、需求背景从Nebula的Github上可以发现,Ne...
    99+
    2023-06-20
  • Python基于win32com客户端实现Excel操作的详细过程
    目录测试环境代码实现非多线程场景下使用新建并保存EXCEL读取现有EXCEL多线程场景下使用参考连接测试环境 Python 3.6.2 代码实现 非多线程场景下使用 新建并保存EXC...
    99+
    2023-05-18
    Python Excel操作 Python win32com Excel操作
  • PHP+Socket系列之实现客户端与服务端数据传输
    本篇文章给大家带来了关于php+socket的相关知识,其中主要介绍了什么是socket?php+socket如何实现客户端与服务端数据传输?感兴趣的朋友下面一起来看一下,希望对大家有帮助。socket介绍实现网络进程之间的通信,几乎所有应...
    99+
    2023-05-14
    php socket
  • PHP作为memcached客户端的具体实现方法是什么
    PHP作为memcached客户端的具体实现方法是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。我们通过以前文章的介绍可以知道memcached 的具体工作原理。那么,今天...
    99+
    2023-06-17
  • xterm.js在web端实现Terminal示例详解
    目录快速上手首次建立链接处理输入逻辑 通常在一些公司内部的系统中,会在 web 端实现一个 Terminal 功能,用户只需要登陆网站就可以使用,而不需要再使用 SSH 的连接方式,...
    99+
    2022-11-13
    xterm.js web端实现Terminal xterm.js实现Terminal
  • 如何使用PHP实现基于MQTT的客户端(代码示例)
    MQTT是一种轻量级的消息传输协议,它是基于发布/订阅模式的。MQTT提供了一种低延迟、可靠的连接,特别适用于小型传感器和单片机等硬件设备的通信。在本文中,我们将介绍如何使用PHP实现基于MQTT的客户端代码。MQTT协议简介在开始编写代码...
    99+
    2023-05-14
  • elasticsearch java客户端action的实现简单分析
    上一篇介绍了elasticsearch的client结构,client只是一个门面,在每个方法后面都有一个action来承接相应的功能。但是action也并非是真正的功能实现者,它只...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作