SSHで繋がらなくなったOCIサーバーを直した話

この記事は [Akatsuki Games Advent Calendar 2024](https://adventar.org/calendars/10718) の 17日目の記事です。

# はじめに

アカツキゲームスでサーバーエンジニアしているちょうです。

仕事ではアプリケーション開発がメインで、既存コードのリファクタリングや高速化もよくやっています。社内では高速化マニアと自称していて、最近長年運用されているタイトルでRails製サーバーのレスポンスタイムを全体的に30%くらい速くできた大工事をしました。リリースはまだなので、次回のネタにでもします。

今日はプライベートサーバーでやらかしたことについてお話しします。

## TL;DR
OSアプデでサーバーを壊しました。その経緯や復旧時にやったことをこの記事にまとめています。

以下のようなことで困っている方向けの手順は最後あたりに用意しておきます。
- OSアプデートでの故障でssh接続できない
- rootパスワードがなくてログイン困っている



# ことの始まり

### Oracle Cloudの無料枠、美味しい

OCIは業務で使われているわけではないのですが、無料枠があまりにも美味しすぎます。
ARM製のCPUを4コア、24GBメモリ分を無料で利用できますので、少し重いアプリケーションのホスティングでも十分できます。

クラウドを理解してもらうためにある枠ではありますが、設定などが面倒だったので、3年前くらいからVPSがわりに利用し始めました。

https://www.oracle.com/jp/cloud/free/

ほかのVPSも契約してますが、性能面の良さで愛用していて、色々なオレオレサービスをこのサーバーに入れてきましたし、最近も自作中のサービスを入れる作業をしています。

### OSアプデート中のsshタイムアウト

OSアプデートできるよ、とログイン時に出ていたので、これを機にアップデートしようと思いました。3年前に作ったインスタンスなので、OS は Ubuntu 20.04 LTS で、今回は最新の 24.04 に更新します。

プライベートなサーバーですし、いい加減な気持ちで開始しました。`do-release-upgrade` を実行したら、ssh越しでやらないほうがいいよ、みたいなアラートを無視して、tmuxのような復帰可能なセッションも貼らずに開始しました。

夜のながら作業でやっていたというのもあり、sshはアプデ中の選択画面で途切れました。sshで繋ぎ直しましたが、`do-release-upgrade` の続きができなくて、困っていた。
そこで、`apt upgrade`はできそうだったので、何も考えずに実行しましたが、また同じようにsshが切れて落ちてしまいました。

それで、何もできなくなってしまいましたが、戻す手段なども調べれば出ていたが、面倒くさくなって、ゾンビプロセスがいくつもあることが見えていたので、再起動すれば治ると勝手に思って、`sudo reboot` をしたのが最後、sshに繋がらなくなりました。

# 対応開始

反省は後回しにして、このサーバーには消えてほしくないものがたくさんあるので、無くしたくないですね。sshは起動できていなかったっぽいし、サーバー管理用のパネルソフトは起動できていそうですが、ログイン時にライブラリー系のエラーが出ていました。

### コンソール接続

幸いなことに、OCIにはコンソール接続機能があります。
> コンソール接続を使用して、正常に動作していないインスタンスをリモートからトラブルシューティングします。

それっぽいので、この機能を利用してみることに

![スクリーンショット 2024-12-16 23.23.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2346330/316db86c-2be8-27b3-6792-84e645778c12.png)

一時的なワーカーを立ち上げてくれて、そこにWEBで接続できたので、非常に便利な機能で感動しました。しかし、今までsshで鍵を使って認証していて、どの user でもパスワードなんて持っていなかったので、ログインできない問題があります。


### Recoveryモード

手元のPCと同じように、OS起動時に起動オプションを変えれば、色々できるのかもしれない。
クラウドの場合でも、手元と同じようにESCキーなどでできるはず。
コンソール接続をしたままで、OCIの管理画面で再起動をかけ、ESCキーを連打すると、GRUBメニューに入れました。

![スクリーンショット 2024-12-16 23.25.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2346330/d0585bfe-6ce8-a1b3-269d-9d66e9b748ad.png)

しかし、ここでは選べそうなものがなさそうでした。

この画面を出てから、ESCを引き続き連打しましたが、反応はありませんでした。
調べると、youtubeでの動画のコメントで、F5キーでできるという書き込みがあったので、GRUB画面後にF5を連打してみたらRecoveryモードに入れました。

記事の画像はその場のものではないのですが、このような画面が見えました。

![スクリーンショット 2024-12-17 0.07.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2346330/39ec03a9-aae1-f2ce-2e0a-50f641fa306d.png)

ここのrootオプションで色々できそうな予感もしますが、パスワードが必要。

![スクリーンショット 2024-12-17 10.58.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2346330/956708ef-a24b-8b08-1bfc-07b8bc6720c9.png)

このような文言が表示され、（WEB版ではControl-Dを押すと接続切れちゃうので、SSH経由でのコンソール接続も試してみたが）Control-Dを押したら前の画面に戻ったので、何もできませんでした。
ここまで来てお手上げなんて、悔しい...

そこで、クライマックスが来る

# rootパスワードがなくてもrootのprompt起動できる
困っていたところで、この動画に助けられた。
https://www.youtube.com/watch?v=66aXSTAt14w

メニューに、dpkgという項目があり、パッケージの修正を行うコマンドです。

![スクリーンショット 2024-12-17 0.28.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2346330/123c89bd-73fb-0281-73a1-269dc977a94e.png)

パッケージをダウンロードしたり直したりするので、rootで実行されます。その実行途中に、detailsというオプションがあり、更新内容の一覧をlessで見られるようになっています。

そこで、less経由で下記のようなコマンドを実行すると、promptが起動できました。

```
!/bin/bash
```

そこで、下記コマンドでパスワードを変更できました。
```
passwd root
```

通常再起動し、rootで入り、色々直す作業をしていたら、無事サーバーは復活できました。

# 反省点
解決するのに4時間以上かかりましたね。面白かったが、2度も経験したくないので、今後は自前サーバーでもインフラ作業をちゃんとしようと思いました。
みなさんも同じ過ちを繰り返さないでくださいね！

#### ssh越しの作業時は、ちゃんとtmuxでやるべき
tmuxなどのツールを使うことで、セッションが切れても作業は止まらないし、再接続で復帰できます。
仕事の時はちゃんとしていますが、自分のサーバーでも、副作用がありそうな作業時は、tmuxを貼っておくべきでしたね。
もっとtmuxを自由自在に扱えていたら、呼吸のように使っていたのかもしれないし、こんなことに時間取られなかったですね。

#### ssh設定で、簡単に切れてしまわないように設定すべきでした

サーバーの設定もありますが、クライアント側の設定ででも十分だったりしますね。
ssh の config にこのような設定を書いておけば困ることはなかったのかもです。
```
Host *
  ServerAliveInterval 60
```

#### OSアプデで壊れたら、そこでちゃんと調べるべき

再起動で治ることもありますが、さらに悪くなることもありますからね。



# 手順早見用
1. 壊れたインスタンスにコンソール接続する
1. ウェブの管理画面で再起動する
1. ESCを連打し、GRUBに入る
1. GRUB出て、F5を連打し、起動オプション画面に入り、Recoveryモードに入る
1. `dkpg` を選択し、途中で `Details[d]` を選択
1. `!/bin/bash` と入力し、promptを起動
1. `passwd root` でrootパスワードを設定
1. 再起動して、rootで通常ログインして、直す作業を行う