コンテナのセキュリティはベース・イメージから始まります。
しかし、ここからが問題だ:
- ベースイメージを「最新」バージョンにアップグレードするだけで、アプリケーションが壊れてしまうことがあります。
- 既知の脆弱性を出荷するか、互換性の問題の修正に何日も費やすかの選択を迫られる。
- そして、アップグレードする価値があるのかどうかさえわからないことも多い。
この投稿では、ベースイメージのアップデートが見た目以上に難しい理由を探り、実際の例を見ながら、アプリを壊すことなく安全でインテリジェントなアップグレードを自動化する方法を紹介します。
問題:「ベースイメージを更新するだけ」-言うは易く行うは難し
これを読んでいるということは、おそらく「コンテナの安全性を確保する方法」などでググったことがあるのだろう。そして、AIが作成したドロドロした記事の最初のポイントは、ベースイメージを更新することだ。簡単だろう?しかし、そうはいかない。
もしベース・イメージに脆弱性があれば、アプリケーションはその脆弱性を抱え込むことになります。このシナリオを演じてみよう。
コンテナ・イメージに対してスキャンを実行したところ、深刻度の高いCVEが見つかりました。ベース・イメージをアップグレードすることをお勧めします。
⚠️ CVE-2023-37920発見 でubuntu:20.04
深刻度:高
固定 で: 22.04
推奨:ベースイメージのアップグレード
...しかし、あなたは問題を発見する。
からやみくもにアップグレードすることで ubuntu:20.04
への ubuntu:22.04
あなたのアプリケーションは砕け散る。
ベース画像をバンプする例と、現実に起こることを見てみよう。
例1:アップグレード後に壊れるDockerfile
最初のDockerfile:
FROM python:3.8-busterから。
RUN apt-get update && apt-get install -y libpq-dev
RUN pip install psycopg2==2.8.6 flask==1.1.2
COPY./appCMD ["python", "app.py"].
チームは次のようにアップグレードする:
FROMパイソン:3.11-bookworm↪Cf_200D
RUN apt-get update && apt-get install -y libpq-dev
RUN pip install psycopg2==2.8.6 flask==1.1.2COPY ./appCMD ["python", "app.py"].
結果
psycopg2==2.8.6
より新しいlibpq
ヘッダーの本の虫だ。
フラスコ==1.1.2
をサポートしていない。パイソン3.11
ランタイム機能(非推奨のAPIが壊れる)。- CIでビルドが壊れる。
- 開発チームは怒っているし、ランチも台無しだ。
例2:微妙なランタイムバグを引き起こすベースイメージのアップグレード
オリジナルだ:
FROM node:14-busterCOPY./アプリ
RUN npm ci
CMD ["node", "server.js"] を実行する。
にアップグレードする:
FROM node:20-ブルズアイ
COPY。/アプリ
RUN npm ci
CMD ["node", "server.js"] を実行する。
ランタイムの問題:
ノード:20
より新しいオープンSSL
バージョン - 厳密なTLS検証は、古いaxios設定を破壊する。- アプリは次のようにスローする。
リーフ署名の検証不能
実行時のエラーHTTP
レガシー・サービスへの呼び出し。
最新」が罠である理由
Dockerエコシステムでは、最新のタグやトップライン・リリースを使うことを推奨しています。しかし、これは月曜日に動いていたアプリケーションが火曜日に突然失敗することをしばしば意味します。これはしばしば頭痛の種となり、停止し、バグ修正に時間を費やして開発が遅くなる罠です。
となると、解決策は当然、テスト済みのマイナーバージョンに固定することなのだが......。しかしそうもいかない。セキュリティのモグラたたきゲームに入り込んでしまったのだから、脆弱性を残す可能性のある新しいCVEを永遠に発見し続けることになる。
決断の麻痺:アップグレードすべきか否か?
セキュリティチームがアップグレードを推進。
開発者が安定性を理由に反発。
誰が正しい?それは場合による
しかし、その決断を理解するためには、すべての選択肢を検討する必要がある。つまり、すべてのバージョン、セキュリティリスク、安定性リスク、可用性に関する膨大なスプレッドシートを作成する必要がある。
それがどんなものかを見てみよう。
これでは、複雑で、くだらない、不可能な選択肢が残されている。
- 古いイメージのままで脆弱性を受け入れる
- アプリをアップグレードして壊してしまい、本番稼動がダウンするリスクがある。
- 手作業による互換性テストの試み - 作業日数
手動アップグレードのワークフロー:
手作業でやるなら、こんな感じだ:
- CVEをチェックする:
trivyイメージ python:3.8-buster
- 各CVEを調査する:アプリケーションのコンテキストで到達可能か?
- アップグレード候補の決定
- 新しいイメージをテストする:
- ビルド
- ユニットテストの実行
- 統合テストの実行
- 失敗した場合は、コードにパッチを当てるか、ライブラリをアップグレードする。
- コンテナごとに繰り返す。
疲れるよ。
じっとすることの代償
壊れていないなら直さなくていい」と思うかもしれない。
しかし、パッチが適用されていないコンテナのCVEは、セキュリティ侵害の大きな原因となっている。
また、人気のあるベース画像には、既知の悪用がたくさん存在する。
- Unzip パストラバーサルの脆弱性 (
CVE-2020-27350
)-何百万ものコンテナに何年も放置されていた。 - ハートブリード
CVE-2014-0160
)は、公式の修正後もずっとレガシーコンテナに残っていた。 PHP-FPM RCE
(CVE-2019-11043
を使用したコンテナ・ベース・イメージでは、リモートの攻撃者が細工した HTTP リクエストを介して任意のコードを実行する可能性があります。プリインストールされたPHP-FPM
パッチ適用前
自動修正機能がどのように役立つか
まさにこのシナリオを解決するために、Aikido Securityはコンテナの自動修正機能を展開した。
この機能は次のように動作します。あなたのイメージ、Aikido あなたのコンテナに脆弱性がないかスキャンします。もし脆弱性が見つかったら(あるいは見つかったら)、いつものように警告を発し、ベース・イメージを更新するよう怒鳴る代わりに、さまざまなオプションを提供します。ベースイメージのどのバージョンでどのCVEが解決されるかを知ることができるテーブルを作成します。こうすることで、マイナーバンプで高CVEのすべて、または大部分が削除される可能性があること、つまりベースイメージの適切なアップグレードであることがすぐにわかります。
アップグレードがマイナーバンプの場合は、自動的にプルリクエストを作成してバージョンを上げることができます。
何時間も節約できる
結論
- コンテナのベースイメージをアップグレードするのは本当に難しい。
- ただアップグレードすればいい」というアドバイスは、複雑でリスクを伴うプロセスを単純化しすぎている。
- しかし、セキュリティと安定性のどちらかを選ぶ必要はない。
- Aikidoコンテナオートフィックスは、あなたが十分な情報を得た上で決断できるよう、あなたのために難しい作業を行います。
- だから、次にベース画像の脆弱性アラートを見たとしても、慌てることはない。PRするのだ。