🤮

sudoと*で本番サーバが空になりかけた

2021/12/29に公開

はじめに

今年の年始早々の出来事です。
タイトルの通りsudoコマンドと*で本番サーバが空になりかけました。
実際に実行されたコマンドが以下です。

sudo rm /*

本来実行される想定だったコマンドは以下です。

sudo rm /aaa/bbb/ccc/*

実装も実行もレビューもしたのは私ではないのですが、
想像以上に時間がかかっていたため気になり確認してみたところ、
以下のようなログに表示されていました。当然ですが急ぎ強制終了させました。

rm: `/ファイル名' を削除できません: 許可されていない操作です

sudoコマンド付きでも削除できないファイルが存在するようで、そのエラーで気づくことができました。
しかし何故このようなことが…

経緯

実行していたスクリプトではファイルの削除だけではなく、ビルドなども行っていました。
その処理過程で削除対象のパスを表す変数が空になってしまっていました。

dir_name=/aaa/bbb/ccc
## この間の色々な処理処理で変数が空になりました。
sudo rm ${dir_name}/*

原因

レビュー漏れ

きっちり行っていたのかもしれませんが、結果漏れがありこのようなことが起きてしまいました。

有識者がいない

Linuxの有識者がおらず少なくともsudoや*、rmを使うことの危険意識がありませんでした。
さらに言いますと、結構な数のファイルやディレクトリの権限に「777」が設定されているような状態でした。

検証漏れ

ステージング環境用で動作検証は行っていましたが、本番環境用では検証されていませんでした。
そのためステージング環境用と本番環境用スクリプトにあった差異の部分で発生してしまいました。

対策

ごみ箱の作成

基本的に削除は行わずに、ごみ箱(trushディレクトリ)へ移動させることを以て削除したとみなすことになりました。

rmコマンドの禁止

ごみ箱以外でのrmは全面的に禁止することになりました。

基本的にsudoコマンドの禁止

chownやchmodのような権限周りのコマンドを使うとき以外は禁止になりました。

*単体での使用禁止

以下例のように拡張子や日付などとセットで使用することになりました。

# ログファイルをごみ箱へ移動
mv *.log ~/trush
mv *_20211229 ~/trus

ステージング環境用と本番環境用を同じにする

そもそもサーバのポート周りなど本番固有の設定以外に違いがあってはいけないはずです(と思っています)。

本番環境用の検証を行う

本番固有の設定をステージング用に書き換えて検証することになりました。
他スクリプトはこの方法で検証を行っていたのですが、これは行われていなかったようです。

おわりに

基本的にはバックアップから復旧することができたのですが、
マウントしていたNFSはバックアップがなかったようで、長期間に及ぶ復旧作業が発生しました。

この一件があり、私としては色々学ぶことができました。
が…来年は何も起きませんように…🙏

Discussion