使用Docker运行ws-scrcpy:实现Android web远程桌面

使用Docker运行ws-scrcpy:实现Android web远程桌面

一、引言上一篇文章我写了一遍关于用嫖的甲骨文Arm通过Redroid image开一个Andriod容器用来安卓挂机,更好的利用吃灰的甲骨文做点事情,但是很多人误会了我那篇文章的意思,并不是非得是Arm64架构才能运行此镜像。只是甲骨文Arm的性能过剩了才拿出来做的栗子,...

一、引言

上一篇文章我写了一遍关于用嫖的甲骨文Arm通过Redroid image开一个Andriod容器用来安卓挂机,更好的利用吃灰的甲骨文做点事情,但是很多人误会了我那篇文章的意思,并不是非得是Arm64架构才能运行此镜像。

只是甲骨文Arm的性能过剩了才拿出来做的栗子,其实只要是能跑docker的arm64/amd64都能启动Redroid。

本篇文章将用oracle Arm机型做栗子,根据别人善意提醒,ws-scrcpy可以通过ws提供一个web版Android的远程桌面。

我去了解了一下,确实比起传统的用iptables限制ip访问adb得到的安全性相比,能有个web端,能让我们更方便的访问和做授权访问。

优点: web端可以通过任意浏览器直接访问方便,还能套诸如cloudflare支持ws的cdn,加速访问; 不用做上一篇文章那种复杂的防火墙规则来保证安全。

缺点: 需要配置nginx auth模块、小白噩梦、多跑一个scrcpy-web容器

下方介绍如有纰漏、错误,请留言指正

二、结果展示

如果你参照如下的说明,你就会得到一个可以授权的web版桌面(密码验证是nginx做的),下面是gif展示:

看着还不错是吧?

那就往下看,仔细阅读,你会得到的很方便安全的云手机。

如果是第一次阅读,请跟着我的说明,参数都不要乱动,等配置成功一次之后再自行发挥。

三、具体步骤

1.准备工作

为了避免复制粘贴,先给没有基础的用户一个提醒,没有看过上一篇文章的看这里:甲骨文ARM利用docker镜像运行安卓云手机。

如果你要熟悉使用本篇文章的说明请阅读至这篇文章的<使用> <四. 拉取docker镜像并启动容器>,查看完该docker命令是什么意思不需要启动容器有点不一样,做好准备工作就行。

2. 启动redroid容器

这里和上一篇文章不用web的直接连接adb时不一样,下面有说明,请注意

docker run -itd \
    --memory-swappiness=0 \
    --privileged --pull always \
    -v /root/test/data:/data \
    --rm \
    --name=redroid8 \
    redroid/redroid:8.1.0-latest \
    androidboot.hardware=mt6891 ro.secure=0 ro.boot.hwc=GLOBAL       ro.ril.oem.imei=861503068361145 ro.ril.oem.imei1=861503068361145 ro.ril.oem.imei2=861503068361148 ro.ril.miui.imei0=861503068361148 ro.product.manufacturer=Xiaomi ro.build.product=chopin \
    redroid.width=720 redroid.height=1280
  • –name redroid8 也是给容器起个名字,方便连接adb
  • 没有映射adb端口,因为我们这里不需要它暴露adb端口到外网
  • 这个分辨率可以适当调大,因为是web端嘛,自测

3.用docker运行scrcpy-ws获得web端

目前ws-scrcpy没有官方镜像,有人提了pr但是都一年多了都没有合并,看原作者的意思是不希望维护docker镜像,需要该pr的人维护,但是提该pr的人可能也觉得麻烦不想维护…..

所以我自己打包了个scrcpy-web镜像push到dockerhub上去了,支持amd64和arm64(其他架构貌似需求不大所以没加),随缘更新,保证可用就行。

docker run --rm -itd --privileged -v /root/scrcpy-web/data:/data --name scrcpy-web -p 127.0.0.1:48000:8000/tcp  --link redroid8:myphone1 emptysuns/scrcpy-web:v0.1
  • -p 127.0.0.1:48000:8000/tcp 这里只映射127.0.0.1,因为我们下面需要用nginx做密码登录,所以只允许本机访问,防止有人扫描抓取,如果你有其他玩法,就改变这个映射端口。
  • –name scrcpy-web 这里最好加个名称,因为后面连接adb要用到,比如这个名称就叫scrcpy-web
  • -v /root/scrcpy-web/data:/data 映射一个目录进去,方便到时候用adb install 安装本地apk,因为启动的安卓容器只能由这个scrcpy-web访问,方便以后本地向容器里传数据。
  • –link redroid8:myphone1 意思是本容器连接到其他容器,<你需要连接的容器名称>:<自定义别名>,这里这么写就是为了只需要scrcpy-web容器能连接改adb端口,其他都是拒绝,为了安全。

等待容器启动成功后,用curl访问一下127.0.0.1:48000查看是否启动成功

root@ubuntu:~# curl 127.0.0.1:48000
 
#如果有如下返回值就说明成功
<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" name="viewport"/><title>WS scrcpy</title><script defer="defer" src="bundle.js"></script><link href="main.css" rel="stylesheet"></head><body></body></html>

4. scrcpy-web容器连接adb端口

这个简单,scrcpy-web是你给scrcpy-web镜像启动的容器起的名称,redroid8是安卓容器起的名称,如果你没有改动我上面的介绍,直接输入就行。

docker exec -it scrcpy-web adb connect myphone1:5555
connected to myphone1:5555 #出现这个说明启动成功

5. nginx反代scrcpy-web端口,增加密码登录

Tips:如果你觉得下方配置nginx过程麻烦,且你不熟悉nginx配置文件,你可以用cloudflare argo tunnel+workers增加web访问和授权,会自动配置https,可以忽略以下所有配置过程。

由于原本的scrcpy-web也是没有鉴权功能的,他只是一个web前端,如果要增加登录验证功能需要去改源码,比较麻烦,我们可以曲线救国,用nginx auth模块来做登录即可。

如果你是如上一步一步走下来的,没有改东西,则默认scrcpy-web只监听127.0.0.1本机ip,如果你在第2步设置了端口映射,允许0.0.0.0访问了,请自行解决授权安全问题。

5.1 用openssl生成账号密码文件
echo -n "test:" > /etc/nginx/passwd_scrcpy_web #生成一个用户名,将test改成自己的用户名
openssl passwd qwert1234 >> /etc/nginx/passwd_scrcpy_web #加密密文,qwert1234改成自己的密码
5.2 配置nginx auth模块

这里给出样例代码,照着自己nginx配置就行,我先说好,我不扫盲,如果你连nginx配置文件都不会修改,就尽力自己解决好吧。

这里只有80的代码,但是最好开启https,修改方法一样,这里不做说明

map http_upgradeconnection_upgrade {
    default upgrade;
    '' close;
}
upstream websocket {
 
     #这里是scrcpy-web的ip+端口,docker ps可以查看
     #你是如上操作的就是127.0.0.1:48000,因为这里要代理websocket
    server 127.0.0.1:48000; 
}
 
server {
	listen 80;
	server_name test.com;
	#root /usr/share/nginx/html;
	auth_basic "Please input password:"; #这里是输入密码的提示信息
        auth_basic_user_file /etc/nginx/passwd_scrcpy_web; #这里是密码文件位置
	location / {
 
		add_header Access-Control-Allow-Origin *;
    		add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    		add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
	     if (request_method = 'OPTIONS') {
        		return 204;
    		}
		proxy_pass http://websocket;
		proxy_set_header Hosthost; 
		proxy_set_header X-Real-IP remote_addr;
                proxy_set_header X-Forwarded-Forproxy_add_x_forwarded_for;
                proxy_http_version 1.1;
                proxy_set_header Upgrade http_upgrade;
                proxy_set_header Connectionconnection_upgrade;
}

其实如上加了一群header是为了做一些简单的防护和允许跨站请求,方便你把这个网页插入其他站点做内嵌网页,最关键的就是以下三点 + 转发ws的部分:

proxy_pass http://websocket;
proxy_set_header Host host; 
proxy_set_header X-Forwarded-Forproxy_add_x_forwarded_for;
5.3检查nginx配置并重启
> nginx -t
 
#如下说明nginx配置没问题
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
> nginx -s reload #nginx平滑重启
5.4 检查是否配置成功

提示需要密码登录,输入用户名密码

检查结果

四、scrcpy-ws说明

webshell:

自定义画面参数

H264 Converter 结果查看

五、选读

5.1 cloudflare argo tunnel + workers实现内网穿透和鉴权,省去nginx

感谢 @ChenYFan 提供的思路 https://cyfan.top/

既然使用了cloudflare了,那么不如直接用cloudflare workers做鉴权。

用cloudflared tunnel 做内网穿透,还能省下配置nginx步骤,很简单

5.1.1 根据自己的架构和系统下载支持的cloudflared

https://github.com/cloudflare/cloudflared/releases

比如我是Arm选择的是:cloudflared-linux-arm64

wget https://github.com/cloudflare/cloudflared/releases/latest/cloudflared-linux-arm64
 
mv cloudflared-linux-arm64 cloudflared #改个名字
5.1.2 登录cloudflare账号并授权域
./cloudflared tunnel login

这里会给你个网址,自己复制到浏览器打开,登录cloudflare,选择一个域完成授权

你选择的这个域后面能将隧道路由到这个域名或者这个域名的任意三级域名

授权完成后默认在$HOME/.cloudflared/cert.pem 生成一个证书用于加密隧道通信,不用管它

5.1.3 创建隧道并连接内网服务

如上成功授权并生成证书后

./cloudflared tunnel create scrcpy-web #scrcpy-web是隧道名称,你可以任意取名字
./cloudflared tunnel list #查看当前隧道
./cloudflared tunnel delete ***** #删除****隧道

配置tunnel路由,让该隧道指定个三级域名(这里可以不用自己的域名,可以用cloudflare给你分配的,但是为了方便还是换成自己的吧,具体怎么操作,自己查查docs)

./cloudflared tunnel route dns 隧道名称 你刚才授权的域名
#例如 ./cloudflared tunnel route dns scrcpy-web scrcpyweb.a.com

配置隧道连接本地web服务,用nohup挂起进程,输出日志在本目录argotunnel.log

nohup ./cloudflared tunnel run --url 127.0.0.1:你的scrcpy-web端口 隧道名称 > argotunnel.log 2>&1 &
 
# nohup ./cloudflared tunnel run --url 127.0.0.1:48000 scrcpy-web > argotunnel.log 2>&1 &

因为没有创建服务,所以这个nohup挂起在系统重启后会关闭,感兴趣可以自己创建systemd来守护进程或者将这个命令写到开机脚本里,我这里就不废话了,谁天天没事老重启服务器啊。

重复以上过程你能得到复数隧道…

此时你浏览器访问scrcpyweb.a.com就能看到后台了,这里还没有鉴权,你可以先测试一下

5.1.4 用workers增加授权界面

粘贴并复制下方workers代码,用户名和密码改成自己的,保存并部署

const username = "XXX"//用户名
const password = "123456"//密码
 
const handle = (req) => {
    const auth = req.headers.get('Authorization') || "Basic "
    if (auth.split(' ')[1] == btoa(username + ":" + password)) return fetch(req)
    return new Response(null, {
        status: 401,
        headers: {
            'WWW-Authenticate': 'Basic realm="This is a Private App!"'
        },
        body: 'Your ip has been recorded, please do not try to crack the password.'
    })
}
 
addEventListener('fetch', event => {
    event.respondWith(handle(event.request))
})

配置路由,给你的workers增加别名,使用自己的域名访问,workers.dev已经被墙了

部署完成后你就能通过你tunnel绑定的别名访问你的scrcpy-web了,这省去了配置nginx的步骤

5.1.5 workers有被刷的风险

cloudflare workers不是无限的请求,每日免费10w次,但是对白嫖用户来说很充足了,但是如果你将域名分享出去,遭到别人刷请求量后,超过10w次会立刻无法访问workers,需等第二天恢复。

所以尽可能不要分享出去,让自己用就行了。

六、常见问题

1. 可以套cloudflare/cloudfront这种cdn吗?

可以,不过比如cloudflare需打开cdn的ws选项

不过不建议无脑套cdn,因为有时你分配到的节点会非常卡顿,导致远程桌面反应迟缓,如果你的服务器裸连很慢套一个也无所谓。

2. 折腾半天有什么用?

不知道,总有人会有用,自己考虑用途

3. 我不是甲骨文Arm可以用吗?

可以,看我上面开头说明,不管你是不是甲骨文,只要你觉得的机器性能尚可,都可以试试内存起码准备4G以上的

4. 我如何连接多个adb? / 我可以安全连接其他主机上的容器吗?

看我发的这两篇文章,自己总结办法,我充其量只是介绍基础用法,灵活使用,看你了。只要你认真看完介绍了,这个问题很简单,还是那个规则不扫盲,扫盲请右转学校

5. 我还有其他问题怎么办?

看看有没有热心的好人帮你解决,作者偶尔看看群

6. 如果用了之后甲骨文被封了怎么办?

拨打市长热线12345,举报甲骨文非法经营不尊重用户合法权益。

7. webview浏览器无法下载任何文件怎么办?

<三、具体步骤> <2. 用docker运行scrcpy-ws获得web端>里向主机映射了一个目录-v /root/scrcpy-web/data:/data用来向容器里传数据。

如果你无法通过webview浏览器下载东西,请装一个via浏览器

下载via.apk放到/root/scrcpy-web/data目录下

docker exec -it scrcpy-web adb install /data/via.apk

这样你就离开古老的webview了

8. redroid容器启动失败怎么办?

docker exec -it redroid8 sh #进入容器内
> logcat #查看输出的日志

9. cloudflare 开启CDN后无法正常代理怎么办?

检查域名界面的ssl/tls设置是否正确

七、结束

其实上面东西写的多,操作起来很简单

八、参考

https://github.com/NetrisTV/ws-scrcpy

原文链接:https://www.vipiu.net/archives/2023/01/08/19071.html,转载请注明出处。
0

评论0

请先

会员低至49元,开通享海量VIP资源免费下载 自助开通
显示验证码
没有账号?注册  忘记密码?