手机单控及玩客云服务部署小记

  近期家里拉了宽带,好友送了一个玩客云盒子,遂探索使用远程控制方式实现手机操作。

  一、手机篇

  对于远程控制的场景,一般使用红米这种技术开放程度高的品牌,遂在咸鱼上40多块淘了个红米note4x作测试。不过邮过来的手机,既没有电池又没有直充线,笔记本usb的电流不足无法将手机开机,只能勉强进入fastboot模式。在退换不方便的情况下,只能用充电头点亮手机,在全程无法开机连接电脑的前提下硬着头皮测验,还好最终实现了功能。

  1.解BL锁。

  可以照着B站的这个视频一步一步的操作:[从零开始 Vol.1]绑定及解锁BootLoader

  对于我来讲,下载小米的官方线刷工作后,使用管理员运行工具即正常安装驱动,然后在手机上进入开发者工具(接充电头),绑定小米账号后重启进入fastboot模式(接电脑),最后使用小米的官方解锁工具完成解锁。

  2.获取Root权限

  一般有两种方法,刷机至开发版或者使用面具(Magisk),我首先选择的是线刷开发版。但从最晚的9.8一直刷到9.1,甚至还刷了个8.12,都在获取Root功能中提示“下载过程中存在异常,建议您重新下载”,导致无法获取root。我上网上搜索也发现有类似的问题,我猜测应该是红米官方人为的关闭了老旧机型与系统的Root获取功能。最后只能重新刷了最新的稳定版11.0.2,然后选择面具方式获取Root。线刷时注意不要选择“全部删除并lock”,否则手机会重新锁住,便需再次执行第1步。

  可以照着面具中文网的教程一步一步的操作:Magisk安装教程,本质上masgisk就是一个破解工具,通过在boot.img中注入屏蔽代码,然后刷入手机替换原版,实现对操作系统的欺骗,最终完成Root获取。

  3.开机自启远程调试

  这一步需要修改手机的启动配置文件。安装老牌的文件管理器 Root Explorer并赋予Root权限,然后使用它打开 /system/build.prop 文件,在文件的最后添加开机自动打开adb访问端口,端口值可自定义。

service.adb.tcp.port=5555

  最后进入手机,打开开发者模式,打开usb调试模式,打开usb调试(安全设置)即可,其中开启后者前需要先插入一张sim卡。至此,手机侧的工作已准备好。

  4.其它设置

  红米note4x是实体按键,无虚拟按键选项。可在更多功能探索中,打开悬浮球选项,方便远程之后执行返回,开关机等操作。

 

其它参考:

Android 设备开机或联网时自动开启无线调试(WIFI调试)

scrcpy链接手机后只能显示无法触控/scrcpy启动脚本/adb传输文件打包

 

  二、玩客云

  手上玩客云的基本情况是arm7 32位架构的4核cpu,1G的内存,8G的存储,有千兆的网口,还有一个usb2口。盒子已经刷为了armbain 23.08系统,采用的debain分支bullseye版本,归属玩客云版本为6.1.31

  1.更换软件库

  首先将软件库更换为国内源,需要修改 /etc/apt/sources.list 及 /etc/apt/sources.list.d/armbian.list 两个文件。其中前者是通用软件库,后者是专用软件库,以更换为清华源为例。

sources.list,注释原有内容并填入如下内容

# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free

deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-updates main contrib non-free
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-updates main contrib non-free

deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-backports main contrib non-free
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-backports main contrib non-free

# 以下安全更新软件源包含了官方源与镜像站配置,如有需要可自行修改注释切换
deb https://security.debian.org/debian-security bullseye-security main contrib non-free
# deb-src https://security.debian.org/debian-security bullseye-security main contrib non-free

 

armbian.list,将 http://apt.armbian.com 替换为 https://mirrors.tuna.tsinghua.edu.cn/armbian ,如下

deb https://mirrors.tuna.tsinghua.edu.cn/armbian bullseye main bullseye-utils bullseye-desktop

 

最后统一升级软件库目录并执行软件更新,更新后归属玩客云版本号为6.6.32。

apt-get update
apt-get upgrade

 

  2.安装常用软件

  安装 screen、ne、alex,具体安装与设置方式,可参见我的另一篇 Ubuntu 22.04部署小记

 

参考

armbian-onecloud

清华大学debian

清华大学armbian

 

  三、手机投屏与控制

  市面上常见的控制软件大部份为scrcpy系,如scrcpy、qtscrcpy等,原理是通过手机的adb服务与手机进行交互。在填写手机被分配的IP后即可实现远程投屏与控制。教程很多,不赘述。

 

参考

FreeControl

13k+ Stars 功能强悍,群控手机,开源无需root

 

  四、手机直控

  当手机adb服务假死,或者连接过程中因为网络原因掉线,再次连接时可能会提示端口占用而无法连接,此时只能通过人工现场重启adb服务,甚至重启手机的方式进行恢复。为了更稳健的远程手机,建议新增手机直控模式,即直接在手机内安装app,然后通过客户端工具将指令发给app,app调用手机shell直接执行或者解析屏幕显示模拟点击执行。

  目前比较经济高效的方式是借助手机的自动化框架完成上述事宜。市面比较常见的有hamibot、autojs、easyclick等。我这边选择的是autojs,其客户端工具名为autojs-web-control,使用了nodejs、nginx及mysql数据库,目前在github上存在好几个仓库版本。

  1.直接运行模式

  zrk1993的仓库版本使用了直接运行模式。

  1.1 npm

  使用apt工具进行安装

apt install npm

  将node与npm的镜像地址均修改为国内源(淘宝)

npm config set registry https://npmmirror.com/mirrors/npm/
npm config set disturl https://npmmirror.com/mirrors/node/

  1.2 mariadb

  系统使用mysql存储数据。可以使用mariadb平替。

apt install mariadb

  打开/etc/mysql/mariadb.conf.d/50-server.cnf,注释bind-address属性,打开远程访问权限。

#bind-address            = 127.0.0.1

  本机登录mariadb,打开root的远程登录权限并设置密码为root

mysql -u root -p
grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;
flush privileges;

  使用数据库工具连接mariadb,创建cloud_auto数据库,然后下载并解压仓库代码,执行cloud_auto.sql及update.sql,执行前者时如果脚本报错则删除开头注释后再次执行。

   1.3 server端

  打开server/utils/db.ts文件,将端口和密码修改为实际值

const orm = new DBM({
  connectionLimit: 10,
  host: 'localhost',
  port: 3306,
  user: 'root',
  password: 'root',
  database: 'cloud_auto',
  isDebug: true,
});

  在server目录执行打包,获取相关依赖库

npm install

  打开tsconfig.json文件,修改发布目标目录为dist

"outDir": "./dist",

  在server目录执行发布

npm run build

  修改package.json,添加start指令,简化服务启动命令

"scripts": {
    "start": "node ./modules/default/main.js",
    "build": "tsc -p tsconfig.build.json",
    "clean": "ts-clean",
    "lint": "tslint --fix -p tsconfig.json -c tslint.json"
  },

  将依赖库及引用文件复制至dist目录

cp -rf ./node_modules/ ./dist/
cp ./package.json ./dist/

  项目里引用了作者另外两个库,在实际操作中没有一并发布,如果现在直接运行本项目会报错,我这边手工编译也会报错,只需要手工下载作者的打包结果并放至指定目录即可

  下载 https://github.com/zrk1993/souljs 项目,解压后将 dist 文件夹复制至 dist/node_modules/souljs/ ,下载 https://github.com/zrk1993/soul-orm 项目,解压后将 dist 文件夹复制至 dist/node_modules/soul-orm/

cp -rf ./dist/ dist/node_modules/souljs/
cp -rf ./dist/ dist/node_modules/soul-orm/

  最后执行如下两种命令中的任意一种,均可开启服务,将监听9317端口数据

npm run start
node ./modules/default/main.js

   1.4 web端

  项目依赖python2,且使用的是python命令。注意不能最小化安装python2-minimial,否则编译过程会报找不到 compiler.ast 的错误,然后对python命令作软链接

apt install python2ln -s /usr/bin/python2 /usr/bin/python

  在web目录执行打包,获取相关依赖库。由于直接依赖与间接依赖存在冲突,需要增加legacy-peer-deps进行忽略

npm install --legacy-peer-deps

  修改web目录下 .env.staging 文件,将api与ws地址指向service端

VUE_APP_BASE_API = 'http://192.168.191.50:9317'
VUE_APP_WS_HOST = 'ws://192.168.191.50:9317'

  运行 npm run dev可以本地模式运行,但更建议以stage标签方式发布至dist目录下,然后挂载至nginx中访问,提高运行性能

npm run build:stage

  1.5 nginx服务挂载

  使用apt工具进行安装

apt install nginx

  修改 /etc/nginx/sites-enabled/default 配置文件 ,将根目录指向上面web端发布的dist目录

root /opt/autojs-web-control-master/web/dist;

  重启nginx后

systemctl restart nginx.service

  现在就可以使用浏览器访问服务器ip,使用admin/123456来登录 Autojs Web Control System

 

参考

AutoJs Web Control(一)

AutoJs Web Control 部署指南

npm disturl 是做什么用的?

从源码分析node-gyp指定node库文件下载地址

nvm、npm镜像源配置

MariaDB versus MySQL: Compatibility

mariadb新安装解决远程访问以及root登录

npm install xxxx --legacy-peer-deps命令是什么?为什么可以解决下载时候产生的依赖冲突呢?

ImportError: No module named compiler.ast on embedded linux

 

  1.6 auto.js app

  auto经历了二代,第一代的最终版是4.1.1,因为涉及某些原因被下架,然后发布出第二代,屏蔽了不少app的适配。我这边只是用于开关机或开关服务的简单操作,使用第一代即可。从这里下载第一代的最终版。

  安装至手机上后打开app,首先将提示需打开此app的无障碍服务,而后使用面具为其赋予Root权限。点击左上角的三根线图标,点击“连接电脑”,在弹出的框中输入布署server端的服务器ip地址,确认后即可在web端看到设备上线。

  在web端创建如下脚本,实现重启手机adb服务

auto.waitFor();

function RestartADBD() {
    toastLog("ADBD重启中……");
    shell("stop adbd", true);
    sleep(1000);
    shell("start adbd", true);
    toastLog("ADBD已重启。");
}

RestartADBD();

  在web端创建如下脚本,实现重启手机

auto.waitFor(); // 文档地址:https://docs.hamibot.com/reference/widgetsBasedAutomation

function ShutdownR() {
  //使用root权限重启
  shell("reboot", true);
  sleep(1000);
  //1秒后还未重启,则采用物理方式重启。
  powerDialog();  
  sleep(1000);
  click('重新启动');
}

ShutdownR();

  目前每次手机重启后,auto.js app连接电脑的设置会被默认关闭,服务端会丢失手机设备的连接,导致后续无法继续发送指令。可以借助auto.js app的自动化操作能力,实现设置的重打开。

  在开发者模式中,打开指针位置选项,确认好auto.js app在桌面上的坐标,然后在app中创建新脚本,如下

device.keepScreenDim(); // 保持屏幕常亮,但允许屏幕变暗来节省电量。当屏幕没有点亮,则会唤醒屏幕。
sleep(1000);
swipe(500, 1500, 900, 500, 201);    // 滑动解锁,小米手机的滑动时间应在201-230之间
sleep(1000)
click(650, 1400);   // 打开桌面auto.js应用
sleep(5000)
desc("打开侧拉菜单").click();   // 打开设置面板
sleep(1000)
swipe(500, 1200, 500, 500, 1000);   // 向上滑动显出连接电脑的选项
sleep(1000);
click(500, 1300);    // 点击连接电脑滑动开关
sleep(1000);
click(860, 775);   // 连接服务器

  点击脚本右链的三个点按钮,选择更多,创建定时任务,将脚本设置为特定事件(广播)触发运行 - 开机时,然后将 auto.js app 加入授权手机的开机自动。实测在本手机中,开机见到桌面后,再等40秒左右将自动运行此脚本连接server端。

 

  1.7 脚本调试

  一段合格的脚本编制需要大量的调试,app使用条件有限,建议使用vscode工具完成代码编制与脚本调试。

  1.7.1 vscode

  vscode的安装与使用网上有很多教程,不赘述。与auto.js app搭配使用的是Auto.js-autox.js-VSCodeExt插件,完成安装后,通过ctrl + shift + p 或者查看->命令菜单,调出命令框,输入auto.js,然后在智能提示中选择"开启服务并监听ADB设备(Start all server)",即可启动server端监听,然后在auto.js app中将连接电脑的ip地址指向vscode所在电脑ip地址即可完成连接。最后在vscode中创建任意名称的js文件,录入代码后,按F5键即可实现代码调试。

  1.7.2 auto.js app

  在代码编写与调试过程,经常需要对界面元素进行定位。auto.js支持两种定位模式。如果使用基于界面元素的定位,这时就需要开启app的悬浮窗功能,也需要手机对app授权悬浮窗权限,然后会在界面的左中侧显示一个小的悬浮圆钮,点击后会展开若干功能,其中第三个就是界面分析;如果使用基于坐标的定位,则是开启手机开发者模式中的指针位置,然后记录操作过程的坐标。在我的体验中,对于界面复杂且命名混乱,想实现的功能又特别简单,目标手机能保持相同品牌相同型号的,使用坐标定位会更简单。具体的使用方式参见官方教程。

 

  1.8 保持连接

  默认情况下,实测app会在锁屏之后2分钟左右断开与server端的连接,当在后台运行时,也可能受操作系统策略影响在任意不确定时间被系统后台中止,所以需要进行相关设置,使app长久稳定运行,且保持app与server端的连接状态。

  1.8.1 电池策略

  进入手机的设置,电池与性能,然后点击右上角的设置,关闭锁屏后断开数据,锁屏后清理内存,然后在应用智能省电中,将auto.js的策略设置为无限制。

  1.8.2 锁屏策略

  在web端使用如下命令来保持屏幕常亮且允许屏幕变暗来节省电量。进入手机的设置,锁屏和密码,然后将自动锁屏的策略修改为从不也是相关的效果(但不会屏幕变暗来节省电量),建议使用命令方式。

device.keepScreenDim()

  1.8.3 应用锁定策略

  打开手机自带的app切换页面,然后长键auto.js应用,在弹出的按钮中点击锁按钮,这样可以保证应用在后台运行时不被清理。

  1.8.4 设置为前台服务

  打开 auto.js app,打开设置面板,打开前台服务开关,可以提高应用的存活率。

  1.8.5 心跳包策略

  通过设置心跳包,让app与server端定期通信,可以增强连接的可靠性。在web端创建一个运行脚本,录入上面让屏幕保持常亮的语句,执行设备选择目标设备(实测选择所有设备时运行无效果),然后在计划任务中设置每间隔1分钟执行一次,最后启动此定时任务即可,cron表达式如下。在我目前实测中,做到前面两步即可保持常连接。

*/1 * * * *

 

参考

第一代API文档

必看的入门基础

从0到1,教你如何使用Tasker+Autojs实现自动打卡功能

autojs,定时脚本的一个简单应用,应用自启动与手动启动的区别。

Auto.js 九宫格解锁、密码解锁

AutoJs Web Control(二)

【Android】【应用保活】保证应用在后台继续运行

 

  2.docker模式运行(未成功)

  shonngithub的仓库版本使用了docker-compose模式。下载并解压,进入deploy目录。但其主理人只编译了amd64架构的镜像,玩客云为armv7 32位架构无法运行,故需要重新寻找镜像。

  2.1 docker及docker-compose

  使用apt工具进行安装

apt install docker.io docker-compose

  创建或修改/etc/docker/daemon.json,添加国内的镜像加速源。今年7月以来很多加速源均失效了,需要不断的更新这个目录。

{
    "registry-mirrors": [
        "https://docker.m.daocloud.io",
        "https://registry.docker-cn.com",
        "https://docker.mirrors.ustc.edu.cn",
        "https://hub-mirror.c.163.com",
        "https://mirror.baidubce.com",
        "https://ccr.ccs.tencentyun.com",
        "https://dockerhub.icu/",
        "https://hub.rat.dev/",
        "https://docker.wanpeng.top"
    ]
}

  项目里deploy/docker-compose文件的版本为3.8,需要下降至3.7或更低,否则运行报错

version: '3.7'

  2.2 mysql

  经查找,biarms/mysql 提供了5.7的armv7架构的mysql,修改编辑docker-compose.yml,将image属性进行修改

image: biarms/mysql:5.7.33-beta-circleci

  2.3 autojs服务端

  服务端为个性化代码,需要自己重新编译。解压根目录的Dockerfile文件中引用了 shonnz/node-nginx:alpine,但可惜这个镜像也属于主理人,也作了个性化处理,且找不到Dockerfile,即使通过dfimage工具逆向出来的Dockerfile参考也不得所以,目前已向主理人申请Dockerfile文件,等待返馈。

 

参考

docker 与 docker-compose 文件版本 对应关系

DockerHub 国内加速镜像列表

在 armv7l 和 s390x 架构服务器上启用 MySQL 和 OpenResty

【Docker】从零开始将自己的应用打包到docker镜像

 

  五、搭建网络连接

  笔记本随自携带,一部份手机可能随身携带,一部份手机放在家里,玩客云肯定放在家里,所以我需要找到一种方式,能够随时将自己与家里链接起来。目前家里的路由器使用的是京东云A6600,俗称雅典娜,光猫桥接至路由器,路由器播号上网。

  我测试的第一种方式,是直接使用ip6公网ip访问内网手机。但是京东云自带的不论是dmz还是端口映射,都只能配置ip4版本,京东云也不支持将ip6转为ip4后转发,所以无法成功。但按这种思路,可以衍生出使用玩客云安装openwrt软路由播号上网,然后玩客云本身也作为服务器实现端口映射。这种思路后面再研究。下面几种方式均基于ip4。

  第二种方式,是使用京东云自带的花生壳+端口映射,但是测试了很久,花生壳一直登录不上去,可能是版本老旧的原因,无法成功

  第三种方式,是使用官方的花生壳树莓派客户端+官方花生壳内网穿透,这个测试成功了,但是免费账号只能配置2个内网穿透。虽然后面研究后,可以使用nginx的负载均衡(upstream)的轮询功能,通过scrcpy工具的主动连接与主动断开,实现相同端口对不同手机的访问,但是终究是复杂了点。(备用方案)

  我最终选择了第四种方式,即使用zerotier或tailscale架设私有VPN。具体来讲又有两种策略,一种是在所有在手机、笔记本、玩客云上安装z或t,所有通信均在z或t网下进行。z或t网服务器在国外,通信的稳定性不足,且在手机上安装z或t比较费时,最终我选择了另一种,即只在笔记本和玩客云上安装z或t,玩客云通过端口映射转发至手机。

  1. 安装zerotier

  按照 内网穿透神器ZeroTier使用教程 这个教程一步一步的注册账号、创建网络、加入网络、分配ip等工作,实现笔记本与玩客云的互通。

  可以通过部署私有化行星或月亮服务器加快访问速度(参考1参考2),不过其要求有固定的外网ip,故放弃。

  2. 安装tailscale(个人首选)

  按照 下一代VPN工具:体验TailScale的简便和高效 这个教程在笔记本上一步一步的下载安装、注册账号、官方管理端配置禁用DNS。

  然后回到官网选择linux下的手工安装模式,选择 Raspberry Pi Bullseye ,然后按照官方教程一步一步的安装,在执行 tailscale up 命令时,将弹出的地址在浏览器中打开,然后使用相同的账号进行登录绑定,即可完成笔记本与玩客云的组网。可在官方管理端或使用 tailscale ip -4 命令查询ip地址。个人实测感觉t网的连接速度比z网略快(但均慢于花生壳)。

  3. 安装蒲公英(个人首选)

  首先登录贝锐蒲公英后台创建网络,然后按照 中国版的Zerotier:蒲公英进阶玩法,想不想白嫖,全在你! 这个教程,在笔记本安装win版贝锐蒲公英并登录相同账户,同时在玩客云安装arm 32位版贝锐蒲公英并登录相同账户,此时蒲公英将自动将这两台设备组网。在各自的客户端或贝锐蒲公英后台可查看各设备虚拟ip。

  下一步配置转发,端口映射又有两种实现方式:nginx转发、iptables转发。

  4 nginx转发(个人首选)

  这个比较简单,在 /etc/nginx/nginx.conf 中添加stream流转发规则,然后重启nginx即可。注意stream节点需与http平级。

stream {
   server {
    listen 51000;
    proxy_pass 192.168.68.177:5555;
  }
}

 

  4 iptables转发

  首先打开 /etc/sysctl.conf 设置 net.ipv4.ip_forward 属性开启 ip4 数据转发功能,然后重启服务器。使用 sysctl -p 检查设置结果

net.ipv4.ip_forward = 1

  然后配置转发规则。目前玩客云有两张网卡,一张是物理网卡连接了wifi,与手机通信,另一张是vpn网卡与笔记本通信,所以 PREROUTING 规则应该配置从VPN网卡到手机的通信, POSTROUTING 规则应该配置手机到物理网卡的通信,然后由玩客云内部自行实现从物理网卡到VPN网卡的通信,最终再从VPN网卡至笔记本的通信。由于手机无法寻址玩客云VPN网卡,POSTROUTING 直接对 PREROUTING 作反向配置将导致数据回传丢包。配置完将立即生效。

iptables -t nat -A PREROUTING -d 192.168.191.50 -p tcp --dport 52000 -j DNAT --to-destination 192.168.68.177:5555

iptables -t nat -A POSTROUTING -d 192.168.68.177 -p tcp --dport 5555 -j SNAT --to 192.168.68.160

  目前相关配置仅存于内存中,服务器重启后将丢失,所以需要进行保存。debian体系下,iptables安装后不是服务,所以需要保存规则至文件,然后自建开机自启加载服务。或者使用 iptables-persistent 包完成上述工作。相关操作见参考即可。

 

参考

iptables实现端口映射(本地和远程端口映射)

双网卡Iptables端口转发

Linux 防火墙指南:如何永久保存 iptables 规则?

Debian下配置防火墙iptables

posted @ 2024-08-04 19:24  永远的阿哲  阅读(85)  评论(0编辑  收藏  举报