こんにちは。現場で泥臭いインシデント対応を繰り返していると、「完璧なセキュリティ」なんて幻想だということがよく分かります。でも、「侵入された後に、いかに傷を浅くするか」という戦術は確実に存在します。
今日は、コンテナ環境における最強の守りの一つ、「ルートファイルシステムの読み取り専用化(Read-Only Root Filesystem)」について、お話しします。
—
家の鍵を閉めるだけでは足りない理由
想像してみてください。あなたは自分の家の玄関に最高級の鍵を取り付けました。これで安心……と言いたいところですが、もし泥棒が窓を割って侵入してきたらどうなるでしょう?
泥棒は家の中に堂々と居座り、壁に落書きをしたり、勝手に家具を運び込んだり、あるいは「いつでも戻ってこられるように」合鍵を作って置いていくかもしれません。
コンテナの世界も同じです。docker run でコンテナを起動したとき、デフォルトの状態は「家の中に自由に家具を配置できる」状態です。もしアプリの脆弱性を突かれて攻撃者が侵入したら、彼らはまず/tmpディレクトリにツールをダウンロードし、/binを書き換えてバックドアを仕込みます。
読み取り専用ルートファイルシステム(Read-Only Root FS)とは、家中の壁や床をすべて「絶対に書き込めない特殊な素材」でコーティングするようなものです。泥棒が侵入しても、何も設置できないし、何も書き換えられない。これだけで、被害を劇的に抑え込めるのです。
—
読み取り専用化の仕組み:Dockerでの設定方法
設定は驚くほど簡単です。Dockerで起動する際、あるいはKubernetesの定義ファイル(YAML)で指定するだけです。
Dockerの場合
コマンドラインから実行するなら、--read-onlyオプションを付けるだけです。
# ルートファイルシステムを読み取り専用にしてコンテナを起動
docker run --read-only nginx:latest
これだけで、コンテナ内のファイルシステムへの書き込みは全て拒否されます。
Kubernetesの場合
Kubernetesであれば、securityContextの設定で行います。開発者の方でもここさえ押さえておけば、インフラ担当者から「おっ、分かってるな」と思われるはずですよ。
apiVersion: v1
kind: Pod
metadata:
name: hardened-app
spec:
containers:
- name: my-app
image: my-app:v1
securityContext:
# ここをtrueにするだけで、書き込みが禁止されます
readOnlyRootFilesystem: true
—
「でも、アプリが動かなくなるのでは?」という懸念
ここで鋭い方はこう思うはず。「ログを書いたり、キャッシュを作ったりするアプリはどうすればいいの?」と。
おっしゃる通りです。全ての書き込みを禁止すると、多くのアプリケーションはエラーを吐いて停止します。そこで登場するのが、「必要な場所だけ書き込み許可を与える(tmpfs)」というテクニックです。
例えば、ログ出力先や一時ファイル置き場だけを「書き込み可能なメモリ領域(tmpfs)」としてマウントしてあげるのです。
volumeMounts:
- name: cache-volume
mountPath: /app/cache # アプリが必要な書き込み場所だけマウント
volumes:
- name: cache-volume
emptyDir:
medium: Memory # メモリ上に作成(再起動で消えるため非常に安全)
このように、「家全体は書き込み不可だけど、机の上(特定のディレクトリ)だけはメモ帳を置いていいよ」という運用にするのが、プロの技です。
—
最後に:なぜこれが「最強の防波堤」なのか
攻撃者は、侵入後に環境を整える時間を必要とします。
- マルウェアをダウンロードする
- 設定ファイルを書き換える
- パスワードファイルを改ざんする
これら全てが、「読み取り専用」の壁にぶつかって失敗します。攻撃者が「おや、ここには何も書き込めないぞ?」と気づいたとき、彼らは焦り、その隙に検知システムが彼らを追い出すことができます。
セキュリティとは、何も特別な魔法を使うことではありません。「本来、書き換える必要のない場所は、絶対に書き換えさせない」。この泥臭い積み重ねが、あなたの大切なシステムを守る最後の砦になります。
まずは、あなたのコンテナのDockerfileを見直してみませんか?「本当にここ、書き込みが必要だっけ?」という問いかけが、セキュリティ向上の第一歩ですよ!
コメント