EC2で誤って「rm /*」を実行してSSH接続できなくなった際の復元手順

とあるEC2上のサーバーにて、サーバー内にあるバックアップファイルをS3に転送するバッチを作成していたんですが、そのテスト中に急にコマンドが叩けなくなってしまう現象が発生しました。

なんだ？と思って、サーバーに再度SSH接続しようとしたところ、SSH接続もできなくなってました。
（ここでサーバー抜けるなよという話ではありますが。。。）

バックアップデータはEC2の中だし、詰んだ。。。
と思ったのですが、なんとか復旧できたので備忘録として残しておきます。


# 何をやらかしたのか

EC2からS3へのファイル転送する際に一旦`/tmp/backups`ディレクトリにバックアップファイルを移動する処理にてバグがありました。
詳細は避けますが、以下のようなイメージです。

```shell
# 一時的にバックアップファイルを置く場所
TMP_DIR=/tmp/backups

# 前回の一時ファイルを削除
sudo rm $DIR/*

# 一時ディレクトリにコピー
sudo cp -a /data/xxxxx/backups/* $TMP_DIR/
```

rmコマンドの引数で`$TMP_DIR`を`$DIR`と存在しない変数を参照していました。。。
これにより、本来`rm /tmp/backups/*`となるべき処理で`rm /*`となってしまいました。

### 何が起きたか

というわけで、ルートディレクトリ直下にあるファイルが全て消えました。。。
（`-rf`オプション指定してなかったから最悪の事態にはならなかった）

ただ、普通のLinuxであればルート直下ってディレクトリしかないから問題ないはずじゃ？って思ったんですが、AmazonLinux2だと`bin`ディレクトリなどがシンボリックリンクとなっていることが分かりました。。。

↓正常なAmazonLinux2インスタンスでルートディレクトリを出力した場合

```shell
[ec2-user@ip-XXX-XXX-XXX-XXX ~]$ ll -a /
total 4194320
dr-xr-xr-x  18 root root        273 Aug 18 03:03 .
dr-xr-xr-x  18 root root        273 Aug 18 03:03 ..
-rw-r--r--   1 root root          0 Oct 10  2019 .autorelabel
lrwxrwxrwx   1 root root          7 Aug 18 03:03 bin -> usr/bin　　　⇒　消えた
dr-xr-xr-x   4 root root       4096 Oct 10  2019 boot
drwxr-xr-x  14 root root       2860 Aug 18 03:08 dev
drwxr-xr-x  82 root root       8192 Sep 15  2020 etc
drwxr-xr-x   3 root root         22 Oct 10  2019 home
lrwxrwxrwx   1 root root          7 Aug 18 03:03 lib -> usr/lib　　　⇒　消えた
lrwxrwxrwx   1 root root          9 Aug 18 03:03 lib64 -> usr/lib64　⇒　消えた
drwxr-xr-x   2 root root          6 Aug 29  2019 local
drwxr-xr-x   2 root root          6 Apr  9  2019 media
drwxr-xr-x   2 root root          6 Apr  9  2019 mnt
drwxr-xr-x   4 root root         27 Aug 29  2019 opt
dr-xr-xr-x 201 root root          0 Aug 18 03:08 proc
dr-xr-x---   3 root root        140 May 25  2020 root
drwxr-xr-x  28 root root       1060 Aug 18 03:08 run
lrwxrwxrwx   1 root root          8 Aug 18 03:03 sbin -> usr/sbin　　⇒　消えた
drwxr-xr-x   4 root root         41 Aug  5  2020 srv
-rw-------   1 root root 4294967296 Sep 15  2020 swapfile
dr-xr-xr-x  13 root root          0 Aug 18 03:13 sys
drwxrwxrwt  10 root root        266 Aug 18 03:31 tmp
drwxr-xr-x  13 root root        155 Aug 29  2019 usr
drwxr-xr-x  19 root root        269 Oct 10  2019 var
```

binとかlibへのパスが通らなくなったのでコマンドが使えなくなったようです。。

# 復元方法

以下の記事を参考に復元することが出来ました！ありがたやT^T

https://casualdevelopers.com/tech-tips/how-to-fix-ssh-problem-to-ec2/

【簡単な手順】
- 問題のEC2インスタンスを停止（終了させるとEBS消えるので絶対やらないこと！！！）
  - ストレージタブにてルートデバイスのパスをメモ（`/dev/xvda`とか）
- 問題のEC2インスタンスからボリュームをデタッチ
- 復旧用に新規でEC2インスタンスを作成（microインスタンスでボリュームも最小限で良い）
  - ネットワーク設定でアベイラビリティゾーンを上記ボリュームと同じにする必要あり
- 問題のボリュームをアタッチ
    - ルートデバイスはデフォルト（`/dev/sdf`）で良い
- 復旧用EC2にSSH接続
- 問題のボリュームをマウントする

```shell
# アタッチしたボリュームの確認
ll /dev/ | grep sdf
lsblk

# マウント
sudo mkdir /mnt/vol01
sudo mount /dev/xvdf1 /mnt/vol01
```

- シンボリックシンクの作成

```shell
cd /mnt/vol01
sudo ln -s usr/bin bin
sudo ln -s usr/lib lib
sudo ln -s usr/lib64 lib64
sudo ln -s usr/sbin sbin
```

- 復旧用EC2を停止
- 問題のボリュームをデタッチ
- 問題のボリュームを元のEC2インスタンスにアタッチ
  - 最初にメモっておいたルートデバイスを指定（`/dev/xvda`とか）
- 問題のEC2インスタンスを起動

これで、無事にSSH接続して元の状態に戻ったことが確認できました！！！

# 教訓

`rm`コマンドは気を付けましょう！
無事に復元できてよかったですが、まじで血の気が引きました。。。

# 参考

- [Amazon EC2インスタンスにSSHできなくなった時の対処法](https://casualdevelopers.com/tech-tips/how-to-fix-ssh-problem-to-ec2/)