オフライン環境のWindows Serverで脆弱性診断を実施すると、「.NET Framework / .NET Core / ASP.NET Core のセキュリティ更新(2020年1月・7月)が未適用」と指摘されることがあります。Windows Update が使えない場合でも、更新の種類を切り分けて入手先を辿れば、スタンドアロンで適用できます。
オフライン環境で「.NET の未適用更新」が出やすい理由
脆弱性診断ツールの指摘は大きく分けて、次のどちらか(または両方)を見ています。
- .NET Framework:Windows の更新として配布されることが多く、更新は主に KB(.msu/.cab)で管理されます。
- .NET Core / ASP.NET Core(モダン .NET):Windows に紐づかない独立製品で、Runtime/Hosting Bundle(IIS用)/SDKなどの配布物を更新します。
この違いを理解せずに「オフラインインストーラーが見つからない」と迷うケースが多いです。たとえば、診断結果に「Microsoft .NET Framework / .NET Core Security Updates(2020年7月)」と出ていても、実際には .NET Framework はKB更新、.NET Core はランタイム更新という“別ルート”で入手します。
まず最初にやるべき切り分け(ここが最短ルート)
オフライン適用で迷子にならないために、次の3点を先に揃えます。
| 確認項目 | なぜ重要か | 確認方法の例 |
|---|---|---|
| Windows Serverのバージョン(2012 R2/2016/2019/2022など) | .NET Framework更新はOSごとにKBが変わる | winver、systeminfo |
| .NET Frameworkの有無とバージョン | KBの対象(3.5/4.6.2/4.8など)を絞る | レジストリ、PowerShell |
| .NET Core / ASP.NET Core の実行環境(IIS/自己ホスト/コンテナ)とバージョン | Hosting BundleかRuntimeか、またはアプリ再デプロイかが変わる | dotnet --list-runtimes |
.NET(Core/ASP.NET Core)側の確認コマンド
サーバーで次を実行し、インストール済みのランタイムを一覧化します(オフラインでも可)。
dotnet --info
dotnet --list-runtimes
dotnet --list-sdks
診断ツールが「2020年1月」「2020年7月」の更新未適用と言っている場合、該当メジャー/マイナー(例:2.1系、3.1系)のパッチレベルが古いことが多いです。
.NET Framework 側の確認(代表例)
.NET Framework 4.x 系はレジストリで確認できます。例:
reg query "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" /v Release
数値(Release値)はバージョンの目安になります。ただし、脆弱性対応は「バージョン」より「KBが当たっているか」で判定されるため、最終的にはインストール済み更新(KB)も確認します。
結論:入手先は「更新の種類」で2つに分かれる
質問の2つの指摘(2020年7月/2020年1月)は、以下のように入手先が変わります。
| 指摘される名称(例) | 実体 | オフライン入手先の王道 | 適用イメージ |
|---|---|---|---|
| Microsoft .NET Framework Security Updates(2020年7月など) | Windows更新(KB、.msu/.cab) | Microsoft Update Catalog / WSUS | wusa / DISM |
| Microsoft .NET Core Security Updates(2020年7月など) | .NET Runtime/SDK の更新 | 公式ブログ+GitHubリリースノート+ダウンロードページ | Runtime/Hosting Bundleをインストール |
| Microsoft ASP.NET Core Security Update(2020年1月など) | ASP.NET Core Runtime/Hosting Bundle の更新 | 公式ブログ+GitHubリリースノート+ダウンロードページ | Hosting Bundle(IIS)または Runtime 更新 |
Windows Update と Microsoft Update の違いを押さえる(混乱ポイントを先に潰す)
更新の入手先を探すとき、似た名前が複数出てきて混乱しがちです。ざっくり以下の理解を持つと、検索ワードも絞れて作業が速くなります。
| 名前 | 主に扱うもの | オフラインで関係するもの |
|---|---|---|
| Windows Update(WU) | OSコンポーネント(例:.NET Framework、累積更新など) | KB(.msu)をUpdate Catalogから入手して適用 |
| Microsoft Update(MU) | OS以外のMicrosoft製品の更新も含む(モダン .NET など) | WSUS/Microsoft Update Catalog経由の管理、または配布物(.exe)で更新 |
| Windows Server Update Services(WSUS) | 組織内で更新を集約・配布 | “オンライン側WSUS”で取得し、“オフライン側”へ展開する設計が組める |
| Microsoft Update Catalog | 更新パッケージの検索・ダウンロード | インターネット接続PCでダウンロード→サーバーへ持ち込み |
特に .NET Framework は WU 側の更新として扱われやすく、モダン .NET は MU 側の配布やインストーラー更新として扱われやすい点がポイントです。モダン .NET のインストーラーがサイレント対応(/install /quiet /norestart)であることも含め、Microsoft Learn の「Install .NET on Windows」に整理されています。
.NET Framework(KB更新)をオフラインで入手して適用する手順
.NET Framework のセキュリティ更新は、多くの環境で「Security and Quality Rollup」などの KB更新として提供されます。オフライン環境では、基本的に Microsoft Update Catalog で該当KBを入手し、.msu を適用します。
手順0:インターネット接続PCでの「持ち込み手順」を型化する
オフライン運用では、ダウンロードのたびに手順がブレると事故に繋がります。最低限、次の流れを固定すると安全です。
- インターネット接続PCで「該当KB」または「該当バージョンのインストーラー」をダウンロード
- ダウンロードしたファイルの署名/ハッシュ(SHA512など)を確認し、記録
- USBや中継サーバーでオフライン環境へ搬入
- サーバーで適用(サイレント適用ならログと終了コードも記録)
- 再起動が必要なら計画的に実施→再スキャン
ハッシュ確認は、Windows標準コマンドでもできます。
certutil -hashfile C:\Temp\package.msu SHA256
(Get-FileHash C:\Temp\package.msu -Algorithm SHA256).Hash
手順1:診断結果から「対象OS」「対象Framework」「月」を読み取る
- OS:Windows Server 2012 R2/2016/2019/2022 など
- .NET Framework:3.5/4.6.2/4.8 など(サーバーに入っているもの)
- 更新月:今回の例では 2020年7月、2020年1月
診断レポートにKB番号が出ていれば最速です。KB番号が出ない場合は、公式の月次記事から辿るのが確実です。たとえば 2020年7月の.NET Framework Security and Quality Rollupは、.NET公式ブログの記事内で「Catalog」への導線が用意されています(OSごとのリンクが載っているため、KB特定にも使えます)。
- .NET Framework July 2020 Security and Quality Rollup Updates
- .NET Framework January 2020 Security and Quality Rollup
補足として、.NET Framework の更新には「Rollup(累積)」と「Security Only(セキュリティのみ)」がある月もあります。運用ポリシーによりますが、迷う場合はまず Rollup 側で揃えると、品質修正も含めて取りこぼしが減ります。
手順2:Microsoft Update Catalog でKBを検索して .msu をダウンロード
Update Catalog では、検索窓に「KB番号」または「2020-07 Security and Quality Rollup .NET Framework」などを入れて探します。候補が複数出る場合は、次で絞り込みます。
- 対象OS(Windows Server 2016向け、2019向け、など)
- 対象アーキテクチャ(多くは x64)
- .NET Framework の対象(4.8向け、3.5向け、など)
ダウンロードページに辿り着くコツは「更新名で探す」よりも、OS+KB番号で確定させることです。公式ブログの記事内にある Catalog リンクや、Update Catalog の検索結果でKBが見えたら、それをキーに運用しましょう。
手順3:wusa.exe で .msu を適用(サイレント可)
ダウンロードした .msu をサーバーにコピーし、管理者権限のコマンドプロンプト/PowerShell で実行します。
wusa.exe C:\Temp\WindowsServer-KBxxxxxxx-x64.msu /quiet /norestart
/quiet はUI無し、/norestart は自動再起動を抑制します。再起動が必要な更新も多いので、メンテナンス時間を確保して最後に再起動まで行うのが安全です。wusa.exe のスイッチや動作は Microsoft の解説記事でも確認できます。
手順4:DISM での適用(.cab/.msu)という選択肢
状況によっては DISM でパッケージを適用したいケースもあります(オフラインイメージへの適用、適用可否チェックを含めた運用など)。Microsoft Learn の DISM パッケージ適用オプションを参照すると、/Online と /Add-Package の使い分けが整理できます。
手順5:適用後の確認(診断が消えるかの最重要ポイント)
パッチ適用後は、少なくとも次を確認します。
Get-HotFixで KB が入っているか(または「インストールされた更新プログラム」)- 必要に応じて再起動を実施したか
- 脆弱性診断ツール側の再スキャンで「未適用」が解消されるか
PowerShell例:
Get-HotFix | findstr KBxxxxxxx
診断が残る場合、KBの対象違い(OS違い、.NET Framework の対象違い)が多いので、適用したKBが「そのサーバーに適用されるもの」だったかを見直します。
.NET Core / ASP.NET Core をオフラインで更新する手順(Hosting Bundle / Runtime)
次に、診断で「.NET Core Security Updates」「ASP.NET Core Security Update」と出る場合の対処です。ここは 公式ブログ → GitHub リリースノート → ダウンロードページの順で辿ると迷いにくく、質問文で挙げられている参照先がまさにその導線です。
公式ブログで「その月に出た更新バージョン」を把握する
2020年1月・7月の更新は、.NET 公式ブログにまとまっています。まずはここで「2.1系/3.0系/3.1系のどのバージョンが出たか」を押さえます。
- .NET Core January 2020 Updates – 2.1.15, 3.0.2, and 3.1.1
- .NET Core July 2020 Updates – 2.1.20 and 3.1.6
ブログでバージョンを把握したら、次に「自分のサーバーがどの系統を使っているか」を照合します。例:
- .NET Core 3.1 のアプリ → 3.1.1(2020年1月)、3.1.6(2020年7月)など、3.1系のサービス更新を適用する
- .NET Core 2.1 のアプリ → 2.1.15(2020年1月)、2.1.20(2020年7月)など、2.1系のサービス更新を適用する
GitHub のリリースノートで「該当バージョンの配布物」を確認する
公式ブログからリリースノートへ進むと、ランタイム/SDK/Hosting Bundle のまとまりで情報が確認できます。例として、.NET Core 3.1 系のリリースノートの入口は以下です。
ここで重要なのは、脆弱性診断が指している「対象の製品・対象バージョン」と一致する配布物を選ぶことです。IISでホストしているなら Hosting Bundle、コンソールやWindowsサービスなら Runtime、といった具合に選択が変わります。
ダウンロードページから「オフライン用インストーラー(.exe)」を入手する
Windows Server で「インストーラーが見つからない」と感じる最大の原因は、“KB(.msu)を探すべきもの”と“.exeインストーラーを探すべきもの”が混在していることです。.NET Core/ASP.NET Core は、基本的に dotnet.microsoft.com のダウンロードページにインストーラーがあります。
ダウンロードページでは、同じバージョンでも用途ごとに行が分かれます(ASP.NET Core Runtime / .NET Runtime / Desktop Runtime / Hosting Bundle / SDK)。オフラインサーバーでWebアプリを動かす場合は、特に次のどちらかが多いです。
| サーバーの役割 | まず候補になる配布物 | 理由 |
|---|---|---|
| IISで ASP.NET Core アプリをホスト | Hosting Bundle(Hosting Bundle installer) | .NET Runtime と IIS用モジュール(ASP.NET Core Module)をまとめて更新できる |
| 自己ホスト(Kestrel)/ バッチ/ Windowsサービス | .NET Runtime または ASP.NET Core Runtime | IIS用のモジュールが不要。必要なランタイムだけ更新しやすい |
また、自己完結型(Self-contained deployment)でアプリを配布している場合、サーバーに共有ランタイムを入れなくても動作します。この場合は「ランタイム更新」ではなく、アプリ側をビルドし直して再デプロイする方が本質的な対策になることもあります。Hosting Bundle でも、自己完結型だけをホストする場合にランタイム等をスキップするオプションが用意されています。
インストーラーをサーバーで実行(サイレント適用の例)
.NET のインストーラー(Runtime/SDK)は、コマンドラインオプションでサイレント実行できます。代表的なオプションは次の3つです。
/install:インストール/quiet:UI無し/norestart:自動再起動しない
例(Runtime/SDK/Hosting Bundleで共通の考え方):
dotnet-xxx-win-x64.exe /install /quiet /norestart
サイレント適用では、終了コードもログとして残すとトラブルシュートが楽になります。再起動が必要な場合は 3010 が返ることがあります(環境差があるため、必ず /? でも確認してください)。
Hosting Bundle 特有の注意点(IISの場合はここで詰まりやすい)
IISホストの場合、Hosting Bundle が入れば終わり……と思いがちですが、運用では次の点で詰まりやすいです。
- IISより先にHosting Bundleを入れていた:IIS導入後に「修復(Repair)」が必要になる場合があります。
- インストール後にIIS再起動が必要:
dotnetのPATH反映やモジュール反映で再起動が必要なケースがあります。 - x86ランタイムが不要でも、将来32bitアプリを載せる可能性:むやみにスキップすると後で詰まります。
Hosting Bundle の構成要素、オプション(ANCMを入れない等)、IIS再起動、ログの場所などは Microsoft Learn にまとまっています。
適用後の確認(.NET Core/ASP.NET Core)
更新後は、次の2系統で確認すると確実です。
- ランタイムが更新されたか:
dotnet --list-runtimesで新しいパッチが入っているか - IIS用モジュールが更新されたか:
%PROGRAMFILES%\IIS\Asp.Net Core Module\V2のaspnetcorev2.dllのファイルバージョン
dotnet --list-runtimes
iisreset
具体例:診断で「2020年7月の .NET Core 更新が未適用」と出たら
実務でよくあるパターンを、手順に落とし込みます。
| 状況 | 例 |
|---|---|
| サーバー | Windows Server 2019 + IIS |
| アプリ | ASP.NET Core(.NET Core 3.1系) |
| 診断の指摘 | Microsoft .NET Core Security Updates(2020年7月) |
dotnet --list-runtimesで 3.1.x のインストール状況を確認- 公式ブログで「2020年7月は 3.1.6 が出ている」ことを確認
- .NET Core 3.1 のダウンロードページから、該当バージョンの Hosting Bundle(IISなら)または ASP.NET Core Runtime を入手
- オフラインサーバーへ持ち込み、
/install /quiet /norestartで適用 - IIS再起動(またはサーバー再起動)→再スキャン
この流れで「インストーラーが見つからない」という状態はほぼ解消できます。逆に、ここで詰まる場合は “そもそもサーバーが 3.1系ではない”、または “自己完結型アプリで、共有ランタイム更新では直らない”など、前提が違う可能性が高いです。
脆弱性診断で指摘が消えないときのチェックポイント
オフラインで更新を当てたのに、再スキャンで「未適用」のまま残る場合は、次の原因が多いです。
- 対象の取り違え:.NET Framework のKBを当てるべきところで .NET Runtime を更新していた(または逆)。
- サイドバイサイドで古いランタイムが残っている:ツールによっては「存在するだけでNG」と判定することがあります。
- 再起動不足:KB適用は再起動が絡むことが多い。
- 診断ツール側のシグネチャが古い:判定ロジックが新しい配布形態(MU配布など)に追従していない。
また、モダン .NET はサポートライフサイクルが明確なので、脆弱性診断によっては「サポート外のバージョン」という理由で指摘されることもあります。修正の第一歩は「指摘が出た“月”に合わせる」ですが、長期的にはサポート中のLTSへ計画的に上げるのが安全です。
オフライン運用で再発させないための「資材化」
オフライン環境は、どうしても「その場しのぎ」で更新を当てると次回また同じ悩みに戻りがちです。運用としては、更新資材を次のように棚卸ししておくと、診断対応が速くなります。
| 資材 | 保管のおすすめ | 更新タイミング | メモ |
|---|---|---|---|
| .NET Framework のKB(.msu) | 月ごと・OSごとのフォルダ | 月例パッチのたび | Update Catalog / WSUS で取得 |
| .NET Runtime / ASP.NET Core Runtime / Hosting Bundle(.exe) | メジャー系統ごとのフォルダ(例:3.1/6/8) | サービス更新のたび | GitHubリリースノートとセットで保存 |
| 検証手順書(チェックコマンド、再起動要否) | チケット/社内Wiki | 更新ごとに追記 | 再スキャン条件も書く |
| ハッシュ(SHA256/SHA512など) | 同フォルダにテキストで保存 | ダウンロード時 | 持ち込み改ざん対策 |
最短で解決するためのチェックリスト
- 診断が指すのは .NET Framework(KB)か、.NET Core/ASP.NET Core(Runtime/Hosting Bundle)かを切り分ける
- .NET Core/ASP.NET Core は
dotnet --list-runtimesで現状バージョンを把握する - 2020年1月・7月の更新は、公式ブログで「該当する更新バージョン」を確定する(例:3.1.1/3.1.6、2.1.15/2.1.20)
- .NET Framework は Update Catalog で該当KB(.msu)を取得し、wusa で適用する
- IISホストなら Hosting Bundle を優先し、必要に応じて IIS 再起動(またはサーバー再起動)まで行う
- 再スキャンで残る場合は、対象取り違え・古いランタイム残存・再起動不足を疑う

コメント