# dockerups **Repository Path**: pysstt/dockerups ## Basic Information - **Project Name**: dockerups - **Description**: B设备中的docker应用定期调访问有ups的A设备,一旦访问不到给B设备下发关机指令 btw,好像在哪里看到过实现,找到了就用现成的,如果没找到考虑自己写一个。 相关的文档留个档 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-06-01 - **Last Updated**: 2024-06-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # dockerups #### 介绍 B设备中的docker应用定期调访问有ups的A设备,一旦访问不到给B设备下发关机指令 btw,好像在哪里看到过实现,找到了就用现成的,如果没找到考虑自己写一个。 相关的文档留个档 ### Docker实现宿主机关机 [原文链接:骚操作:在Docker容器内重启宿主机](https://www.jerryzone.cn/reboot-host-side-containers/) 防止元链接失效,把原文内容页copy过来 骚操作:在Docker容器内重启宿主机 新冠疫情期间,受困在家远程办公。连接上VPN后,能够正常连接并操作服务器,由于网络连接不稳定,在服务器上留下了一些异常的连接,表现为htop中能够看到一些sshd子进程,其下包含了一些诸如htop,bwm-ng之类不会自动结束的监控进程,于是开始作死。 使用sudo取得了管理员权限后,进入htop,按F5进入树形模式。最开始还是比较保守地结束sshd下的bash子进程,使sshd连接对应的父进程自动结束。后来也不知道怎么想的,退出htop直接killall sshd。于是问题出现,瞬间ssh断开连接,使用ssh工具重新连接远程主机发现提示connection refuse。至此,发现出事了。 在作死killall sshd的同时,把sshd最根上的那个爷爷辈的守护进程给一起杀了,相当于把ssh服务给停了,因此无法访问服务器。 万幸的是服务器并没有跑什么业务,只是为我开发做一个带GPU的调试环境。为了开发方便,开启了Docker的远程访问端口。于是着手从Docker看看有没有可能访问到宿主机,执行一些命令或者重启sshd。 首先为了操作方便,配置了一下本地WSL(Windows Subsystem Linux,Ubuntu)中的docker-ce-cli: 1 2 3 4 5 #与正常安装Docker引擎相同,先添加docker官方的源 curl -fsSLhttps://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" #与正常安装Docker引擎不同的是,只安装docker-ce-cli sudo apt install docker-ce-cli 至此,本地WSL中的docker命令安装完成。因为本地WSL中并没有安装dockerd,所以此时的docker命令是无法使用的,通过在.bashrc中添加环境变量DOCKER_HOST使其默认使用远程主机开放的接口。此时,已经能够使用docker命令看到远程主机的一些信息: docker info 期初,希望能够不重启宿主机,只是重启其上的sshd。在搜索引擎中找了一下关于docker容器内逃逸在宿主机上执行命令的内容,发现了V2EX上的一篇讨论(https://www.v2ex.com/t/417477),其中有个大佬提出了一种利用chroot和–privileged将docker内文件系统环境切换为宿主机文件系统的方案: V2EX大佬 但是在我尝试后发现,除了一句Failed to connect to bus: No data available,并没有什么效果(现在来看可能当时是生效了,但是我没有继续尝试连接ssh),于是认为可能执行个简单的命令不太可能了,考虑直接触发宿主机重启。 后来在Github上找到一篇issue(https://github.com/moby/moby/issues/6401),提到了一个可能意外发现的在docker内执行reboot会触发宿主机系统重启的问题: GitHub issue 其中提到即使没有使用–privileged参数给予docker内真正的root权限,使用–net host将host的网络环境直接放在docker内,执行reboot会触发宿主机重启,删除–net host参数后则不会。 抱着试试看的心态,我尝试了如下命令来启动一个具备绝对权限的docker: 1 docker run -it --rm --net host --privileged ubuntu /bin/bash 但是官方提供的ubuntu镜像并没有提供reboot这个命令,甚至init命令也没有,导致无法正确触发重启信号。考虑到前面V2EX大佬提供的思路,我重新创建了docker: 1 docker run -it --rm -v /:/host --net host --privileged ubuntu /bin/bash 随后在位于docker中的ubuntu中使用chroot命令切换根路径: 1 chroot /host /bin/bash 看似没有什么变化,实际上如果通过ls /会发现,/host目录已经不存在了,即证明已经切换到了宿主机的根文件系统中。随后我执行了reboot命令,虽然和之前一样报了相同的错误: 切换根目录并重启 但是与之前不同的是,docker立即断开了连接,此时宿主机应当是已经在重启了。稍等片刻,等待宿主机重启完成后发现22端口开放,可以使用ssh登录终端。启动htop后发现uptime为2分钟前,可以证明之前确实重启了服务器: 重启过后 这个例子中可以看出: 1.对外开放无认证的Docker API是非常危险的行为,生产环境应当禁止对外开放 2.–privilege能不用尽量不要用 3.–net host下可能触发重启的bug貌似还没有解决 4.reboot信号是通过网络发送给内核的?(有待考证)