background
M
K
e
2
#
S
>
|
6
s
4
Y
O
D
+
:
u
w
S
k
;
]
7
:
H
C
<
5
2
o
Q
-

favicon
favicon
Reverier 的博客
 

绳子上的运维日记

Reverier-Xu at 2024-09-07 02:08:19 Development CC-BY-NC-SA 4.0

这篇文章到底合不合规我也不清楚,大家看个乐子就行。为了防止本文变成某次护网或者蓄谋攻击的架构指导文章,我会混淆大部分实现细节。当然还是暴露了一些不影响安全的违规操作,在本文发布时已经全部进行了整改,请勿学习!

用绳子吊死运维

Reverier 是个干运维的,7x24 小时服务随叫随到的那种。

他负责了好几台服务器,没事还要响应各种各样的小事故(说通俗点就是擦屁股的),比如什么学弟不小心给自己的 /usr/lib 删了啊,隔壁楼实验室的学姐运维的古老 Ubuntu 14 找不到软件源了啊,楼上课题组跑 AI 的机器 CUDA 又爆了啊,室友搞二进制分析用的 PowerPC 虚拟机又起不来了什么的。

每次帮忙完,Reverier 都会去学校的 711 便利店买一瓶椰子水犒劳一下自己。

椰子水好喝,但是运维不好干。除了帮比奇堡的朋友们解决各种神奇的问题和棘手场景之外,Reverier 还要负责运维一些比较重要的网站,比如 西电 CTF 终端。但是 Reverier 只是个普通的研究牲,而重要的教育科研项目怎么可能全权交给一个研究牲负责呢 ---- 于是名义上的运维部门是信息化处,项目归属网络与信息安全学院。至于系统开发者和运维是谁?不熟。

牢骚就发到这里,再发就拿不到毕业证了。

教育网站属于国家官方网站,其安全措施与各项规定都十分严格。作为一个仅对软件部分有实际控制权的运维,Reverier 并不能碰到大部分的运维设施,比如 IPMI,PVE,服务器硬件等等;除此之外,服务器没有互联网访问权限,端口也只开放了 80 和 443。

对,你没看错,没有开放 22 端口,作为一个运维,Reverier 连 Shell 都得自己想办法。

由于本博客可能会涉及一些敏感的服务架构,为了防止被二次利用,博客里会对学校网站群的整体架构进行模糊描述,并且选择性的修改或者不写某些重要信息。

信息化处也并不是完全把路堵死了 ---- Reverier 还可以选择跑到北校区线下突袭信息化处,然后抢夺一台电脑 他们给了一个堡垒机,要通过堡垒机层层验证和保护之后,才通过堡垒机间接登录服务器的 SSH。

在没有互联网的情况下,想把某个软件包传递到服务器上可谓是难如登天。同时,如果不小心误操作干掉了 SSH 服务,那么整个服务器就会永远迷失在网站群里,唯一的拯救之路就只剩下突袭信息化处办公室了。

要在限制如此之多的场景之下正常的拉起一个稳定的服务,Reverier 把这种活称为 走钢丝式运维

我真的不是黑客

首先要解决的就是 Shell 问题。

就目前这个运维设施,堡垒机通过简单隧道协议将服务器 Shell 串流到运维的终端里,显然是没法用 scp 或者 rsync 之类基于 SSH 隧道服务传文件的工具。所以现在亟需解决绕过堡垒机登录 Shell 的问题。

████ ███ ██████ █████

信息化处对于服务器的部署存在一些问题,比如 ████████。这使得我们直接多了一个可用的 ████。除了用起来怪怪的之外,其他都没什么问题。但是这么做风险也不小,Reverier 手上负责的所有学校服务器都 备用 了这种方案。

TCP muxer

另一个可行的办法是自己搓一个 TCP muxer,并将其部署至 nginx 之前。SSHHTTP 协议包头都是固定的,因此实现思路很简单,使 TCP muxer 根据新 TCP 连接的第一个包头确认连接协议,然后将其路由到对应的服务即可。

这样的话,我们就可以使用浏览器访问 80/443 获取正常的 Web 服务,SSH 直连 80/443 也能直接连接到 SSHd 服务上。

但是好景不长,因为这样相当于直接暴露了 SSH 端口,一些探测工具会将 80/443 端口识别为 SSH 服务,很不巧的是信息化处的自动审计工具就是这么 ████。在被打了两次电话之后最终还是抛弃了这个看起来最为简单和稳定的办法。

SSH over WebSocket

Reverier 写过一个工具叫作 WebSocket Reflector X,功能大概是通过 WebSocket 协议,在应用层上重新搭建传输层,并将服务器的内部端口通过临时的 TCP 客户端传递到 WebSocket 连接中,然后再通过客户端将 WebSocket 连接映射至用户的本机端口。

这个工具恰好解决了 Shell 的问题,只需要在服务器上部署好 WebSocket Reflector X,并设置规则,将某个 WebSocket 端点映射至服务器的 22 端口即可。

当然,使用 WebSocket Reflector X 的体验并不是很好,再加上堡垒机会将 HTTPS 解码为明文流量,在审计上可能会出问题。但是聪明的你也许想到了,有另一个大家都很熟知但是不太能拿到明面说的协议 █████,流量混淆、分流、加密、错误恢复都实现了,用来做这个工作简直是再合适不过了。

多途径反弹 Shell

[实现细节已删除] [已整改]

死亡迁移

在刚刚接手这台服务器的时候重装过一次系统,为了稍微稳定一点,Reverier 做出了一个令他后悔了好几次的决定:使用 Ext 4 文件系统。虽然 Ext 4 没什么问题,同样也是目前为止最为流行的单机文件系统,但是它还是存在一个巨大的问题:无法跨设备扩展分区。

这本来不应该是个什么大事的,但是前任运维和 Reverier 都低估了这台服务器以后的工作负载和用户数量 ---- 谁能想到一个新生赛能在短短四年里从 200 人规模膨胀到 6000 人啊。

于是这台服务器只申请了 100GB 的硬盘。

毫不意外地满了。

然后去寻求了信息化处的帮助,希望他们能给扩容一下。虽然不太爽快但还是扩容成功了,只是扩容的方式比较抽象,他们直接插了一块 1TB 的新硬盘上来。这下好了,绝大部分的存储负载都在 /var/lib/docker,还有相当一部分的负载在平台的题目存储,迁移哪个文件夹都很抽象。

经过深思熟虑后,Reverier 决定冒一次险,在新硬盘上自举一个全新的系统,然后修改 grub 指向新系统,最终完成迁移。

这个风险异常的大 ---- Reverier 手里只有一个 SSH,而这个 SSH 还要依赖 NGINX 和 WebSocket Reflector X 才能连接上来,如果在新系统里有一点配置出错了,那么就又得突袭信息化处了。

虽然如此,但依旧是能做的。

在经过了一些心理建设之后,Reverier 打开了 Arch Linux 的文档,打算自举一个 Arch 上去,然后被群友叫停了。对于一个互联网访问都不稳定的服务器而言,用 Arch 的风险还是太大了。于是掉转目标,使用 Debootstrap 来自举一个 Debian 到新硬盘上。

安装过程大抵跟着 这里 就行,使用 arch-install-scripts 简化了少许操作。

i use arch btw

在通过 arch-chroot /mnt/new_system 之后,第一件事是 pacman -Syu(不是) apt update(别惦记着你那系统更新了) 恢复网络配置。这里我只能靠赌新系统启动时能够和旧系统一样采用 BIOS 建议命名了,于是直接把旧系统的 /etc/network/interfaces 复制了过来。

接下来是处理 fstab,在进系统之前用 genfstab 处理了一下,但是似乎有一些 loop 设备也被生成进来了,得手动删除。

然后是依次配置 account、systemd 服务、NGINX、WebSocket Reflector X 以及 ██████████,最后返回旧系统,运行 update-grub,然后在生成的 grub.cfg 里手动修改第一启动项。

都完成后,用激动的心颤抖的手敲下 systemctl reboot 等待着奇迹发生。

os-prober!

满头大汗.jpg

期间还担心 grub 能不能跨盘引导,找 arch 群友求助了一番。

感恩群友

好在是福大命大。

我再也不会这么干了

未完待续……

服务不大事故不少,有空再写罢,给大伙找点乐子看。