コンテナの「玄関」に最強の鍵をかける:Seccompでシステムコールを制限しよう
こんにちは。現場で泥臭くインシデント対応をしていると、ふと思うことがあります。「なぜ、これほどまでに便利なコンテナが、これほどまでに無防備な状態で動かされているのか?」と。
Dockerコンテナは確かに便利ですが、中身はホストOSのカーネルを共有する「シェアハウス」のようなものです。もし、ひとつの部屋(コンテナ)に泥棒が入ったらどうなるでしょう? その泥棒が「家全体の鍵を開ける権利(システムコール)」を持っていたら、家中の部屋を自由に荒らされてしまいますよね。
今回は、そんな最悪の事態を防ぐための「Seccomp(セックコンプ)」という防犯技術について、専門用語を噛み砕いてお話しします。
—
1. なぜ「システムコール」が狙われるのか?
システムコールとは、簡単に言えば「アプリからカーネル(OSの心臓部)への命令」のことです。「ファイルを開け」「ネットワークにつなげ」「プロセスを殺せ」といった命令ですね。
実は、Linuxには数百種類ものシステムコールが存在しますが、普通のWebアプリがそのすべてを使うことはまずありません。
攻撃者は、この「使われていないはずの機能」を悪用します。例えば、Webサーバーが本来必要としない「カーネルの深い設定をいじる命令」を無理やり送り込み、ホストOSを乗っ取ろうとするわけです。泥棒が、本来使うはずのない「窓をこじ開ける道具」をわざわざ持ち込むのと同じですね。
2. Seccompは「玄関のオートロック」
Seccomp(Secure Computing Mode)は、コンテナがカーネルに対して「どの命令を出していいか」を制限するフィルタリング機能です。
イメージしてみてください。あなたの家の玄関に、「この人はリビングとキッチンには入れるけど、地下の金庫室(カーネルの重要機能)には絶対に入れない」という厳格なガードマンを立たせるようなものです。たとえアプリが乗っ取られても、ガードマンが「その命令は禁止リストに入っているので却下します!」と弾いてくれる。これがSeccompの役割です。
3. 実践:不要な呼び出しをブロックする
Dockerはデフォルトでも一定の制限をかけていますが、さらに安全にするには「ホワイトリスト方式」が最強です。「これだけは使っていい」と決めたもの以外、全部拒否する設定を作ってみましょう。
JSONプロファイルの作成例
まずは、必要なものだけを許可する簡単なプロファイル(profile.json)の例です。
{
"defaultAction": "SCMP_ACT_ERRNO", // デフォルトで拒否(エラーを返す)
"architectures": ["SCMP_ARCH_X86_64"],
"syscalls": [
{
"names": ["read", "write", "exit", "futex", "nanosleep"], // アプリが最低限使う命令だけ許可
"action": "SCMP_ACT_ALLOW" // これらは許可する
}
]
}
コンテナへの適用方法
作成したプロファイルをコンテナ起動時に指定するだけで、そのコンテナは劇的に硬くなります。
# --security-opt オプションでプロファイルを読み込ませる
docker run --rm \
--security-opt seccomp=profile.json \
nginx:latest
これだけで、たとえ攻撃者が悪意のあるコードを実行しようとしても、許可されていないシステムコール(例:reboot や mount など)を投げた瞬間に、コンテナ側はエラーを返し、攻撃は空振りに終わります。
—
4. 運用上の「ちょっとしたコツ」
「全部制限したらアプリが動かなくなるのでは?」と不安になりますよね。その通りです。だからこそ、以下の手順で進めるのがプロの鉄則です。
1. 監査モードで動かす: いきなりブロックせず、まずは「ログだけ出す」設定でアプリを動かし、どんな命令が使われているか洗い出します。
2. 必要なものだけ抽出: アプリのログを解析し、実際に使われた命令リストをプロファイルに書き写します。
3. 徐々に厳しくする: 最初は広めに許可し、安定稼働を確認してから不要な命令を一つずつ削っていきます。
最後に:完璧を目指さず、まずは「できることから」
セキュリティは、最初から100点を目指すと息切れしてしまいます。まずは、「自分のアプリが本当に必要としているシステムコールは何だろう?」と考えること。その好奇心こそが、最高のセキュリティ対策の第一歩です。
「泥棒が入る前提」で、最小限の権限しか与えない。この「疑う心」をコンテナの設計に組み込むだけで、あなたのサービスは格段に強固になります。ぜひ、今日からテスト環境で試してみてくださいね。
わからないことがあれば、いつでもまた聞きに来てください。一緒に安全なコードを書いていきましょう!
コメント