はじめに
チューニング、CVE・パッチ適用、サイジングなどプロフェッショナルな気持ちになりたいが、なかなか経験と知識が追い付かずどうしたらいいんだろうというヒントになれば幸いです。
Tips 2 :
- AIを利用する。 それぞれの適用の必要性と、理由をAIに回してもらう。
- 最終的に吐き出された内容をやっぱりチームごとに確認も駆使してもらう。
- 担当者が全チームに「みたか」「確認」「声掛け確認」が責務持ってOpen/Closeする。(ここは自動化と信頼性と SREという継続性を実現させるための近道:人力は大事です)
脆弱性情報を確認していると、次のようなコンポーネント名が大量に並ぶことがあります。しかも・・・セキュリティチームから、サービスちーむからの頻繁な牽制でたじろぐ・焦る・脂汗になることがあります。
- kernel
- OpenSSL
- zlib
- ImageMagick
- cmake
- Firefox
- jq
- vim
- Tomcat
- Docker
- JDK
- Grafana
- libsndfile
このとき、すべてを「危険なので即対応」と扱うと、現場の運用は回りません。
一方で、根拠なく「使っていないはず」「関係なさそう」と判断すると、本当に重要な脆弱性を見落とす可能性があります。
この記事では、現場で脆弱性情報を確認するときの考え方として、以下を整理します。
- 脆弱性情報の見分け方
- 対象外と判断するための根拠の作り方
- Kernel / OS パッチ適用が難しい理由
- ECS / Fargate のローリングアップデートがパッチ適用判断にどう効くか
- AWSマネージドサービスを理解することの価値
この記事の目的は、単に「パッチを当てましょう」と言うことではありません。
必要な脆弱性を見分け、必要なものを、安全に、継続的に適用できる運用に変えることです。
1. 脆弱性情報を見るときに、最初に確認すること
脆弱性情報を見たとき、いきなり「対象 / 対象外」を判断するのではなく、まず次の観点で整理します。
これは何のソフトウェアか?
何に利用されるものか?
自分たちのシステムに入っているか?
入っている場合、実際に使っているか?
外部から攻撃可能な経路にあるか?
該当する機能を有効化しているか?
対象外と言える根拠は何か?
特に重要なのは、「インストールされている」と「実際に使っている」を分けて考えることです。
OSイメージやコンテナイメージに含まれていても、該当機能を使っていなければ影響は限定的な場合があります。
逆に、普段意識していない便利ツールが、構築手順や運用スクリプトに含まれていることもあります。
図解俺流脆弱性判断フロー
2. まずは脆弱性を分類する
脆弱性情報は、まず分類すると判断しやすくなります。
図解:脆弱性コンポーネントの分類
2-1. OS / Kernel / 標準ライブラリ系
例:
- Linux kernel
- glibc
- OpenSSL
- zlib
- systemd
OSやKernelに関する脆弱性は、影響範囲が広くなりやすいです。
特にKernelは、アプリケーションやコンテナより下のレイヤにあるため、簡単に「使っていない」と判断しづらい領域です。
ただし、Kernel脆弱性でも攻撃成立条件はさまざまです。
- ローカル権限が必要
- 特定のKernel機能を使っている場合のみ影響
- 特定のネットワーク機能が有効な場合に影響
- 権限昇格につながる
- コンテナ脱出につながる
- DoSにつながる
そのため、Kernelと書かれているから即停止して対応、ではなく、
攻撃成立条件と自分たちの構成を照らし合わせることが重要です。
2-2. ミドルウェア系
例:
- Tomcat
- JDK
- Apache HTTP Server
- Nginx
- Docker
- containerd
- Grafana
ミドルウェア系は、実際に通信を受ける経路にいるかが重要です。
たとえば Tomcat の脆弱性であれば、次を確認します。
Tomcatを使っているか?
対象バージョンか?
該当する機能を使っているか?
ALBやWAFの背後にいるか?
HTTP/2を有効にしているか?
RewriteValveなど特定機能を使っているか?
セッション管理をTomcat側で行っているか?
アプリケーションはStateless構成か?
同じTomcatでも、単に含まれているだけなのか、外部通信を受けるアプリケーションサーバとして使っているのかでリスクは変わります。
2-3. ライブラリ系
例:
- zlib
- libsndfile
- OpenSSL
- ImageMagick
ライブラリ系は、そのライブラリを使う処理がシステムに存在するかを確認します。
たとえば zlib は、ZIP、gzip、HTTP圧縮、ファイル展開などで使われる可能性があります。
一方、libsndfile のような音声処理ライブラリは、音声ファイルの読み込みや加工を行っていなければ、影響は限定的と考えられます。
ImageMagick の場合は、次を確認します。
画像アップロード機能があるか?
サムネイル生成があるか?
PDFや画像変換処理があるか?
バッチ処理で画像加工していないか?
APIチームやアプリチームが使っていないか?
インフラチームだけでは判断できない場合は、アプリケーション側に確認するのが安全です。
2-4. 運用・便利ツール系
例:
- jq
- nkf
- vim
- cmake
- Firefox
こうしたツールは、アプリケーション本体では使っていなくても、構築手順や運用スクリプトで使われている場合があります。
たとえば jq は、AWS CLI の出力結果を加工するためによく使われます。
aws ecs list-tasks | jq .
cmake は C / C++ のビルドツールです。
ソースコードからビルドしていなければ関係しない可能性がありますが、CI/CDや構築手順に含まれていないかは確認が必要です。
vim は踏み台サーバに入っていることがあります。
外部から直接攻撃されるケースは限定的でも、踏み台は管理経路に関わるため、軽視しすぎない方がよいです。
3. 「対象外」と判断するための書き方
脆弱性対応でよくないのは、次のような書き方です。
使っていないため対象外。
これだけでは、なぜ対象外なのかが分かりません。
対象外と判断する場合は、次のように書くと説明しやすくなります。
### 対象コンポーネント
ImageMagick
### 用途
画像変換や画像加工に利用されるソフトウェア。
### 本システムでの利用状況
インフラ領域では画像変換処理を実施していない。
コンテナイメージ、構築手順、運用スクリプト上での利用実態も確認されていない。
### 判断
対象外。
### 補足
APIやアプリケーション側で画像アップロード、サムネイル生成、画像加工が存在する場合は別途確認する。
ポイントは、対象外の理由を「用途」と「利用実態」で説明することです。
4. 個別コンポーネントの見分け方Tips
4-1. ImageMagick
ImageMagick は画像変換や画像加工に使われるツールです。
確認ポイント:
- 画像アップロード機能があるか
- サムネイル生成をしているか
- PDF / 画像変換をしているか
- バッチ処理で画像加工していないか
- APIチームで利用していないか
インフラ基盤として画像処理をしていない場合は対象外と判断しやすいですが、アプリケーション側で使っていないかは確認した方が安全です。
4-2. cmake
cmake は C / C++ のビルドツールです。
確認ポイント:
- ソースコードからビルドしているか
- READMEや構築手順にcmake導入があるか
- yum / rpm / dnf で既成パッケージを導入しているだけか
- CI/CDパイプラインで使っていないか
既成パッケージを利用しており、ビルド処理をしていない場合は対象外にしやすいです。
4-3. Firefox
Firefox はブラウザです。
サーバ環境や踏み台でGUIを持たない構成であれば、通常は利用しません。
ただし、次の用途がないかは確認します。
- 画面自動テスト
- ヘッドレスブラウザ
- 帳票や画面キャプチャ生成
- GUIベースの管理操作
4-4. Grafana
Grafana は監視データの可視化ツールです。
確認ポイント:
- Grafanaサーバを構築しているか
- Amazon Managed Grafanaを利用しているか
- コンテナ内にGrafanaが含まれているか
- エージェントやプラグインを入れていないか
本システム内にGrafanaを導入していない場合は対象外です。
4-5. jq
jq はJSONを加工するCLIツールです。
確認ポイント:
- 構築手順にjqのインストールがあるか
- 運用スクリプトでjqを使っていないか
- CI/CDパイプラインで使っていないか
- メンバーが個別に入れていないか
jq は便利なため、誰かが手作業や運用補助で入れていることがあります。
そのため、あえて確認することが大事です。
4-6. vim
vim は踏み台やサーバ上で利用される可能性があります。
確認ポイント:
- 踏み台にインストールされているか
- 外部から直接到達できるか
- 管理者のみが利用する閉域環境か
- 対象脆弱性がリモート攻撃可能か、ローカル操作前提か
踏み台でのみ利用し、アクセス制御されている場合はリスクは限定的です。
ただし、踏み台は管理経路の入口になるため、定期的な更新対象には含めるべきです。
4-7. Kernel
Kernel はOSの中核です。
確認ポイント:
- 対象OSは何か
- 対象バージョンか
- 攻撃成立にローカル権限が必要か
- 外部ネットワークから悪用可能か
- コンテナ環境で影響するか
- 権限昇格やコンテナ脱出につながるか
- 修正には再起動が必要か
Kernel脆弱性は、影響判断が難しい領域です。
そのため「対象外」と簡単に言うよりも、リスクを確認し、適用時期を計画するという扱いが現実的です。
4-8. Tomcat
Tomcat はJavaアプリケーションサーバです。
確認ポイント:
- Tomcatを使っているか
- 対象バージョンか
- 脆弱性に関係する機能を使っているか
- HTTP/2を有効にしているか
- RewriteValveなど特定機能を使っているか
- セッション管理をTomcat側で行っているか
- ALBやApacheが前段にいるか
たとえば、アプリケーションがStateless構成で、セッションを外部ストアで管理している場合、Tomcat側のセッション機能の影響は限定的なことがあります。
ただし、HTTP/2やDoS系の脆弱性は通信経路に関係するため、前段のALB設定やバージョン確認も含めて判断します。
5. Kernel / OS パッチが難しい理由
KernelやOSのパッチ適用が難しい理由は、技術的な適用方法ではなく、再起動と影響調整にあります。
よくある悩み:
- 再起動が必要
- 業務時間中に停止できない
- バッチや外部連携が動いている
- セッションが切れる可能性がある
- 流量が多く、瞬断が怖い
- 障害時の切り戻しが不安
- 再起動後に同じ状態で戻る保証が弱い
その結果、パッチ適用が後回しになります。
しかし、Kernel脆弱性を長期間放置すると、権限昇格、コンテナ脱出、DoS、横展開などのリスクが残ります。
重要なのは、
「再起動が怖いから延期」ではなく、「どうすれば安全に更新できるか」へ議論を変えることです。
6. 適用・延期・回避を判断する考え方
図解:適用・延期・回避の判断
6-1. 適用を急ぐべきケース
以下に該当する場合は、優先的な対応を検討します。
- 外部公開されている
- 攻撃成立条件が軽い
- PoCや攻撃コードが流通している
- 権限昇格につながる
- コンテナ脱出につながる
- 認証・認可・鍵管理に影響する
- 代替策で十分に抑えられない
この場合は「延期できるか」よりも、どうやって安全に適用するかを考えるべきです。
6-2. 延期を検討できるケース
以下のような場合は、期限付きで延期する判断もあり得ます。
- 攻撃成立にローカル権限が必要
- 外部から到達できない
- 管理経路が制限されている
- 該当機能を使っていない
- 代替策を実施できる
- 適用予定日を明確にできる
延期する場合は、必ず次をセットにします。
延期理由
代替策
監視・検知
適用予定日
再確認日
期限のない延期は、実質的な放置です。
6-3. 回避策として考えられるもの
即時パッチ適用が難しい場合は、次のような回避策を検討します。
- 不要なポートを閉じる
- セキュリティグループを絞る
- WAF / ALB側で防御する
- 該当機能を無効化する
- 管理経路を踏み台経由に限定する
- sudoやroot権限を制限する
- 重要ワークロードを分離する
- 監視やログ検知を強化する
これらは恒久対策ではありません。
ただし、パッチ適用までのリスクを下げる補完策になります。
7. OS / コンピュート基盤のローリングアップデートがパッチ適用に効く
Kernelパッチは、どうしても再起動を伴うことがあります。
そのため、単一サーバに直接パッチを当てる運用では、停止調整が重くなります。
ここで重要なのが、OSやコンピュート基盤をローリングアップデートできる設計にしておくことです。
考え方は次の通りです。
古い環境にその場でパッチを当てる
↓
パッチ済みの新しい環境へ段階的に置き換える
この方式にすると、再起動そのものを完全に避けるのではなく、
再起動の影響をサービス全体から切り離すことができます。
8. EC2 / ECS on EC2 での考え方
ECSのEC2起動タイプでは、コンテナの下にEC2ホストがあります。
Kernelパッチの対象は、このホストOSになることが多いです。
この場合、古いノードに直接パッチを当てて再起動するより、
パッチ済みAMIで新しいノードを作り、古いノードを退役する方式が有効です。
流れの例:
1. パッチ済みAMIを作成する
2. 新しいEC2ノードをECSクラスタに追加する
3. 新ノードにタスクを配置できる状態にする
4. 古いノードをDrainする
5. タスクが新ノードへ移動する
6. 古いノードを削除する
このようにすると、Kernelパッチを「サーバに当てて再起動する作業」ではなく、
ノードを入れ替える作業として扱えます。
図解:EC2 / ECS on EC2 のノード入替イメージ
9. ECS / Fargate のローリング置換を理解する
ECSサービスのデプロイ設定では、デプロイ中に何個のタスクを起動・停止するかを制御できます。minimumHealthyPercent と maximumPercent は、ローリング更新時のタスク数や開始・停止順序に関係する代表的な設定です。
たとえば、ALB配下で以下のコンテナが動いているとします。
#1, #2, #3
新しいイメージ、または新しいタスク定義を適用すると、新しいタスクが裏側で起動し、ヘルスチェックを通過したものから置き換わっていきます。
概念的には以下のような流れです。
初期状態:
#1, #2, #3
新しいタスク #A が起動:
#1, #2, #3, #A
#A が正常になったため、古い #1 を停止:
#2, #3, #A
次に #B が起動:
#2, #3, #A, #B
古い #2 を停止:
#3, #A, #B
次に #C が起動:
#3, #A, #B, #C
古い #3 を停止:
#A, #B, #C
最終的には、希望台数を維持しながら、古いタスクから新しいタスクへ置き換わります。
Before:
#1, #2, #3
After:
#A, #B, #C
この間、以下のような処理が仕組みとして行われます。
- 新しいタスクを起動する
- ヘルスチェックを確認する
- ALBターゲットとして登録する
- 古いタスクを切り離す
- 必要なタスク数を維持する
- 異常時にはデプロイ失敗やロールバックを検討できる
ECSのデプロイ設定では、maximumPercent によりデプロイ中に RUNNING または PENDING 状態で許容されるタスク数の上限を定義できます。たとえば desired count が4で maximumPercent が200%なら、リソースが許す限り新しい4タスクを起動してから古い4タスクを止める、といった動きが可能です。
図解:ECS / Fargate のローリング置換
10. Fargate の場合に考えること
Fargateの場合、ホストOSやKernelは基本的にAWS側の管理です。
利用者が直接ホストOSへログインしてKernelパッチを当てるものではありません。
Fargateで利用者が考えるべきことは、主に以下です。
- コンテナイメージ内のOSパッケージを更新する
- ベースイメージを最新化する
- 新しいタスク定義で再デプロイする
- platform version の追従方針を決める
- ALB / WAF / SG / IAM などで露出面を抑える
- ログやメトリクスで異常を検知する
- タスクリタイア通知を運用に組み込む
ECSサービスのタスクについては、Fargateのタスクリタイア時にもECSスケジューラが desired count を維持するように新しいタスクを起動します。一方、Standalone Task は自動で代替タスクが起動されないため、必要に応じて利用者側で置き換えロジックを用意する必要があります。
つまりFargateでは、Kernelを直接触るのではなく、
自分たちが管理するコンテナイメージ、タスク定義、サービス設定、通知対応を継続的に整備することが重要になります。
図解:Fargate における責任範囲の整理
11. 手作り運用とマネージドサービスの違い
同じローリングアップデートを自前で作ろうとすると、かなり大変です。
必要になるものは、たとえば以下です。
- 新旧サーバの台数管理
- ヘルスチェック
- ロードバランサからの切り離し
- セッションや通信中リクエストの考慮
- 失敗時のロールバック
- ログ監視
- 作業履歴
- 手順書
- 人による判断
これをシェルスクリプトや手順書で全部作り込むと、更新のたびに作業リスクが残ります。
一方で、ECS / Fargate / ALB のような仕組みを使うと、この多くをサービスの標準機能として扱えます。
もちろん設計や設定は必要です。
しかし、「毎回人が頑張って安全に置き換える」のではなく、
安全に置き換える仕組みの上に運用を乗せることができます。
これが、AWSのコンテナやマネージドサービスを使う大きな利点の一つです。
12. Kubernetes との比較で考える
Kubernetesでも、当然ローリングアップデートは可能です。
Deploymentによるローリング更新や、Argo CDなどを使ったGitOps運用も一般的です。
一方で、Kubernetesは自由度が高い分、周辺設計や運用コンポーネントも増えやすいです。
- クラスタ管理
- ノード更新
- Ingress
- Service Mesh
- GitOps
- 監視
- 権限設計
- アドオン管理
これらをしっかり運用できる組織には強力です。
一方で、小さく始めたい場合や、AWSのVPC / ALB / IAM / CloudWatch と自然につなげたい場合、ECSは非常に現実的な選択肢になります。
ECSは、VPC上に直接コンテナ実装を置く感覚で使いやすく、ALBやIAM、CloudWatchと連携しやすい点が魅力です。
13. 脆弱性対応を「個別判断」から「運用設計」に変える
脆弱性対応で一番つらいのは、毎回ゼロから判断することです。
これは対象?
急ぐべき?
止めてよい?
誰に確認する?
延期してよい?
いつ当てる?
この判断を毎回アドホックに行うと、現場に負荷がかかります。
そのため、次のような型を持っておくとよいです。
脆弱性確認の型
1. 対象コンポーネントを確認する
2. 用途を確認する
3. 利用有無を確認する
4. 外部露出を確認する
5. 攻撃成立条件を確認する
6. 代替策を確認する
7. 適用要否を決める
8. 適用できない場合は期限付き例外にする
9. 最終的な適用予定日を決める
パッチ適用の型
1. 直接パッチ適用でよいか
2. 再起動が必要か
3. ローリング更新できるか
4. 新しいイメージ・AMIに置き換えられるか
5. ALB配下で段階切替できるか
6. ロールバックできるか
7. 作業後に状態確認できるか
このように標準化しておくと、脆弱性対応が「毎回の火消し」ではなく、運用プロセスになります。
図解:脆弱性を見る力と更新できる設計
14. まとめ:脆弱性を見る力と、更新できる設計をセットで持つ
脆弱性情報を見たときに大切なのは、すぐに「対象外」や「即対応」と決めることではありません。
大事なのは、以下を整理することです。
- 何のソフトウェアか
- 何に使われるものか
- 自分たちのシステムで使っているか
- 外部から攻撃可能か
- 攻撃成立条件は何か
- 対象外と言える根拠は何か
- パッチ適用が必要な場合、どう安全に適用するか
特にKernelやOSパッチは、再起動を伴うため後回しになりがちです。
しかし、再起動が怖いから延期するのではなく、ローリングアップデートやノード入替によって、サービス影響を抑える設計にしておくことが重要です。
ECS / Fargate / ALB のようなAWSマネージドサービスを理解すると、コンテナの置き換え、ヘルスチェック、段階的な切り離し、希望台数の維持といった仕組みを標準機能として利用できます。
これは単に「便利」という話ではありません。
脆弱性対応を、継続可能な運用に変えるための重要な選択肢です。
最終的に目指すべきは、
「パッチを当てるかどうか」で毎回悩む状態ではなく、
必要なパッチを、必要なタイミングで、安全に当て続けられる状態です。
脆弱性の見分け方を持ち、
対象外の根拠を説明でき、
必要なものはローリングアップデートで適用できる。
この状態を作ることが、現場エンジニアにとって一番現実的で強い脆弱性対応だと考えます。
そんなときのためにW-Aを見ておこう
準備や対処が必要です。その時にどういう指針になるか難しいなと思う前に、思い出す癖をつけるのはお勧めです。
- それがwell architected framework: パッチ適用の章などを参考に、どうしたらいいんだろうよりも「僕らはこうします」をまず定義しチーム間で共有することが大事。
たのしい24/365ライフを♪