rm -rf でファーストサーバ、データ消失!?

2012-06-20、日本国内の大手レンタルサーバー会社のファーストサーバが一部のレンタルサーバ上のデータを全て吹き飛ばし、バックアップデータも同時に抹殺しました。

クラウドの危険性云々という論調もありますが、影響があったのは専用サーバと共有サーバ、それと SaaS というか ASP が中心なので、プラットフォームの問題ではなく、単に管理・運用体制に穴があったんでしょう。

なんでも、サーバの脆弱性対策の更新プログラムに欠陥があったのと、更新対象のサーバの絞り込みに抜けがあったとか。管理コンソールから SSH か何かで更新対象のサーバ (i.e. 全サーバ) にバーッと欠陥プログラムを走らせちゃったんでしょうね。

ここからが本題です。その欠陥プログラムですが、例えば以下のようなものだったのでは、という推測があり (出所忘れました)、興味深いです:

#!/bin/sh

# 何らかの処理
rm -rf $DIRNAME/$BASENAME  # 変数は両方とも未定義
# 何らかの処理

上の2つの変数が未定義なら、”rm -rf /” が実行されることになります。恐ろしい。

$DIRNAME と $BASENAME は空でない文字列を期待しているはずです。ならば、以下のようにすればより安全でしょう:

#!/bin/bash
#
# "入門 bash" (オライリー) の第9章参照

trap_err () {
    exit_status="$?"
    line_number="$1"
    echo "command/function exited with exit status $exit_status at line $line_number"
}

trap 'trap_err $LINENO' ERR

# 変数のバリデーション。ここでは空でないか検査します。ひっかかると trap_err を実行して終了します。
test x"$DIRNAME" != x
test x"$BASENAME" != x

rm -rf "$DIRNAME/$BASENAME"

#trap - ERR  # 必要であれば、トラップをリセットします。

ERR 疑似シグナルは、関数や外部コマンドが 0 以外の終了ステータスを返すと発生します。これをトラップしてやれば、test コマンドで変数をチェックするだけで停止することができます。

※未定義の変数へのアクセス禁止するだけなら、set -o nounset を最初に実行すれば OK です。

また、以下のような rm -rf の悲劇が世界のどこかで実際にあったようです:

#!/bin/bash

rm -rf /foo  /bar/baz

“/foo/bar/baz ” を削除するつもりが、”/foo” と “/bar/baz” の2つのディレクトリを削除してしまう、というものです。これは文字列を常に引用する (i.e. “/foo /bar/baz”) 癖をつければ避けられるでしょう。

シェルスクリプトを侮る者はシェルスクリプトに泣く。精進しよう!

(コウヅ)

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中