はじめに
フューチャー Advent Calendar 2025 8日目は、姫路が担当します。
昨年の10月に入社し、現在は業務でAWSを利用しています。
利用前は、「AWSって複雑そうだけど、ユーザーが多くてマニュアルもしっかりしていそうだし、触ったら意外と簡単なんじゃないの?(←え?)」などと楽観的に考えておりました。
しかし、実際に利用していく中で、「ボタンの操作だけで完結しない」こと、そして「マニュアル通りの手順が通用しないケースがある」という現実を、今更ながら痛感しております。本記事は、そんなAWS駆け出しの私が直面した課題とその対応策、そしてそこから得た学びをまとめたものです。
今回のテーマは 「閉域網のWindowsサーバーへのSSM Agent導入」 です。
Amazon InspectorでWindowsサーバーのEC2に対して脆弱性スキャンをするにはSSM Agentが必要です。しかし、対象が閉域網にあり、S3への経路がない...そんな環境に直面しました。
アカウントも複数ありネットワーク設定の修正には時間がかかります。しかし、数十台あるサーバーにいち早くSSM Agentを導入しなければならない。
ネットワーク設定をしてから入れていくでしょうか?RDPでログインしてインストールでしょうか?
結論として私が選んだ手段は、「ネットワーク開通を無視し、WinRMで外部からSSM Agentを強制的にインストールする」アプローチです。本記事では、その具体的な手法と、その後に待ち受けていた「ネットワーク設定の重要性」に関する学びについて共有します。困っている誰かの選択肢の一つになれば幸いです。
直面した課題:閉域網の壁の出口がない
Amazon Inspectorを利用して脆弱性管理を行うためには、全WindowsサーバーにSSM Agentの導入が必須です。初めに、1つのサーバーに対して、SSM Agentの導入を進めてみました。
グローバルなURLからダウンロード
SSM Agentが稼働していないWindowsサーバーに対して、インストーラのダウンロードから始めました。Windowsサーバー用のSSM Agentの手動インストール手順に関する記事を参考にして、以下のコマンドを実行しました。
[System.Net.ServicePointManager]::SecurityProtocol = 'TLS12'
$progressPreference = 'silentlyContinue'
Invoke-WebRequest `
https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/windows_amd64/AmazonSSMAgentSetup.exe `
-OutFile $env:USERPROFILE\Desktop\SSMAgent_latest.exe
結果としては、Unable to connect to the remote serverの出力がありました。原因は、このURLがグローバルなエンドポイントであり、インターネット経由が必要だったにもかかわらず、環境がVPCで外部から隔離されていたからです。EC2が閉域網にする設定することは、セキュリティの観点で適切であり失敗して当然ではありました。
(参考: AWS セキュリティのベストプラクティス標準 (v1.0.0) )
リージョン固有のURLからダウンロード
続いて、Invoke-WebRequestのURLを、東京リージョン固有のものに変更して実行しました。
Invoke-WebRequest `
https://amazon-ssm-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/windows_amd64/AmazonSSMAgentSetup.exe `
-OutFile $env:USERPROFILE\Desktop\SSMAgent_latest.exe
結果として、Unable to connect to the remote serverが出力されました。通常であればこれで成功するはずでした。失敗の原因は、S3のエンドポイント設定が適切になされていないことでした。ルートテーブルにS3のエンドポイント(VPCエンドポイント)へのルートがなく、デフォルトルート(0.0.0.0/0)に従ってインターネットへ抜けようとしました。しかし、閉域網のためインターネットへの経路はなく、通信が破棄されていました。
課題の表出
- 閉域網の環境においてS3のゲートウェイエンドポイント設定が適切になされていなければ、インストーラをダウンロードできない
- SSM Agentを入れるためにネットワーク設定を直したいが、調査や申請に時間がかかるうえ、他のアカウント/サーバーでも同じ事象が発生する可能性がある
- でもAgentは今すぐ入れたい
戦略の転換:先にファイルを送ってインストールする
サーバー上でインストーラを直接ダウンロードする方針ではコストがかかりすぎることが分かりました。そのため、「サーバーにダウンロードさせる」方針から、「作業端末から送り込む」方針に戦略を変え、以下の流れでSSM Agentの導入を行うことができました。
- インターネット接続できる作業端末に、インストーラをダウンロード
- 作業端末から対象のサーバーにインストーラを転送する
- 対象のサーバーでインストーラを実行し、SSM Agentを起動する
作業環境
- Windows 11
- Windows PowerShell 5.1
採用した技術
- WinRM(ポート5985): Windowsの標準プロトコルであり、リモート操作を可能にする
WinRMは実行時に認証を行います。
AD配下ではない、またはIPアドレスを指定したサーバーへ接続する場合、Kerberosによる相互認証が行われません。この場合、対象サーバをTrustedHostsに登録することで、認証ができるようになります。
【参考】WinRM を使用した PowerShell リモート処理のセキュリティに関する考慮事項
サンプルコード
$cred = Get-Credential -Credential $userを実行すると、ポップアップウィンドウでユーザー名とパスワードを求められます。パスワードをスクリプト内に記載したい場合は、適宜プログラムを修正してください。
認証で利用するパスワードは、EC2 インスタンスへの RDP 接続用のコンソールからキーペアを利用して復号できます
# --- 1. 事前準備 ---
# [PC側] ファイルをダウンロードしておく
$localPath = "$env:TEMP\AmazonSSMAgentSetup.exe"
[System.Net.ServicePointManager]::SecurityProtocol = 'TLS12'
Invoke-WebRequest `
"https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/windows_amd64/AmazonSSMAgentSetup.exe" `
-OutFile $localPath
# --- 2. 接続情報の定義 ---
# 対象サーバーリスト(IPまたはホスト名)
$targets = @("10.1.1.10","10.1.1.11")
# 認証情報
$user = "Administrator"
$cred = Get-Credential -Credential $user
# プロキシ回避オプション
$opt = New-PSSessionOption -ProxyAccessType NoProxyServer
# --- 3. WinRMセッションの確立とファイル転送 ---
# 対象サーバとのセッションを確立
$sessions = New-PSSession -ComputerName $targets -Credential $cred -SessionOption $opt -ErrorAction SilentlyContinue
# WinRM経由で、SSM Agentのインストーラを転送
$remotePath = "C:\Windows\Temp\AmazonSSMAgentSetup.exe"
foreach ($sess in $sessions) {
Copy-Item -Path $localPath -Destination $remotePath -ToSession $sess
}
# --- 4. リモートインストール実行 ---
# セッションが確立した対象で並列にインストール
Invoke-Command -Session $sessions -ScriptBlock {
$installer = "C:\Windows\Temp\AmazonSSMAgentSetup.exe"
Start-Process -FilePath $installer -ArgumentList "/S" -Wait
Remove-Item -Force $installer -ErrorAction SilentlyContinue
Get-Service AmazonSSMAgent
}
# 後始末
Remove-PSSession $sessions
しかし、これで終わりではなかった ~真の学び~
インストール成功後、S3の設定不備のあるサーバーに対してAmazon Inspectorのスキャン状態を確認したところINACTIVEでした。原因を調査したところ、添付した画像の赤枠部分にあるInspectorDistributor-do-not-deleteの関連付けで失敗しておりました。
この関連付けは、S3から Amazon Inspector SSM プラグインをインストールする役割を担っています。
Windows インスタンスの Amazon Inspector スキャン要件の注記に以下の様にありますが、これはInspectorDistributor-do-not-deleteの関連付けを成功させるために必要な要件となっていました。
ホストがインターネットにアクセスできない Amazon VPC で動作している場合、Windows スキャンでは、ホストがリージョンの Amazon S3 エンドポイントにアクセスできる必要があります。
今回のケースでは、S3のエンドポイント設定を適切に行うことで、InspectorDistributor-do-not-deleteの関連付けはもちろん、次に実行されるInvokeInspectorSsmPlugin-do-not-deleteの関連付けも問題なく成功しました。
学び
- 「インターネットに出られない環境では、AWS内部通信(S3エンドポイント)の経路確保が必須」というAWSネットワークの基礎を認識
- Agent導入はできたが、Amazon Inspectorの継続的な運用には、結局正しいネットワーク構成が必要だった(関連付けのエラー原因の一つ)
- 「暫定対応(インストーラを転送してインストール)」と「恒久対応(S3エンドポイント修正)」の使い分け
まとめ
SSM Agentを先に入れても結局S3の設定が必要なら、どちらが先でもいいのでは?という意見もあるでしょう。しかし、SSM Agentを先に入れておくことで、設定不備のあるアカウントの特定やトラブルシュートを行う際に、大きなアドバンテージになります。そのため、私としては「暫定的なSSM Agentの導入」の次に「恒久的な環境整備」の流れでSSM Agentの導入を進めていくことが良いのではないかと考えます。
同じような環境で悩むエンジニアの一助となれば幸いです。
