前面曾说过,自己因为 reset UFW 时,忽视提示,结果把自己锁到服务器外面了,最后费了好大劲才重新进入系统。

本文详细记一下,情况是这样的:

那天给服务器启用 UFW 服务,顺便测试,结果有一次运行了 reset UFW 的命令,运行命令后,系统给出提示,在重置后可能有意想不到的结果,比如失去 ssh 操作权限等,但是我当时也没细想,就直接回车了,然后,PuTTY 的界面就定住了,没法再输入命令了,但此时后悔也来不及了。

一想到自己竟然把自己锁到服务器外面了而且服务器上的内容都还没有备份,不知所措了,想删掉实例重来又不忍,因为已经配置的差不多了。不过又一想,Google 云服务官网上不是可以 ssh 登录么,这些云服务商都提供网页版的后台登录。其实自己也不报特别大的希望,因为服务器实例相当于把所有 ssh 登录方式都禁掉了,但是有没有可能网页控制台上的登录方式有更高的权限?于是就试了试,结果不出所料,网页控制台也无法登录。

这下有点绝望了,于是就用更具体的关键词来搜索,结果搜到说 GCP Compute Engine 支持 startup script,又有希望了,而且感觉通过这种方式,肯定能把 UFW 配置成运行 ssh 登录。实践证明,确实可以。

关于开机启动脚本的使用,Google 官方文档介绍的非常详细,可以参考: Running Startup Scripts,本文只说比较简单的方式。

点击自己的实例,会进入到实例详情页面,能看到自己创建这个实例时的一些配置,页面上方有编辑按钮,也就是说可以给创建好的实例做一些改动的,点击编辑后,找到 Custom metadata 这个选项,然后添加相应的 key 和 value,key 可以填写 startup-script,或者 startup-script-url,意思很明确,我在这儿用的是前者,而 value 部分就是我们要添加的启动脚本了,我要开启 UFW ssh,所以脚本如下:

#! /bin/bash
sudo ufw allow ssh
echo "y" | sudo ufw enable

之所以这么写,是因为前面我摸索着试过很多种写法,因为粗心,写错了很多次,有一次成功了,但是是把 UFW 禁用了,但是还是没法登录,于是又添加 ssh 允许命令并开启 UFW 服务,最终成功了,可以登录了。注意其中的 echo "y",因为命令执行过程中需要输入一次 y,当然这也是我在脚本执行出错后学到的。

这次的教训也很深刻,虽说最后把问题解决了,但是却花了很多时间,中途重启了很多次实例,因为脚本只是在实例启动后运行一次,所以如果脚本写错了,就要关掉实例,编辑 metadata 下的脚本,然后重新启动。

另外,网上还有一种处理方法:

首先把现有实例的磁盘做一个镜像,然后新开一个实例,挂载出问题的实例的磁盘镜像,然后把所做的错误改动纠正,然后再使用纠正过错误后的镜像新开一个实例,就相当于把先前的实例复制了一下,但是错误已经被纠正了,问题解决后把没用的两个实例删掉就可以了。

可以看出,这种通过新开实例并挂载出错磁盘的方式相比开机启动脚本更加复杂,但是,如果遇到的不是像我这种简单的麻烦(自己把自己锁在外面),而是大麻烦的话,这种迂回方法几乎就是唯一可行的方法了。