Chapter-0
この記事の付録です。
https://qiita.com/koguchi_takao/items/82dda4952fb49a478b37
付録 A. Syslog フォワーダー / Logstash をオンプレミスに置く場合
本編では検証のために Syslog フォワーダーと Logstash を Azure VM 上に置きました。実際の導入では、ログを出す機器の近く(オンプレミスのデータセンターや拠点)にこれらのサーバーを置く構成がよく使われます。この付録では、そのときに 本編から何が変わるのか、何に注意すべきか、具体的にどう設定するか をまとめます。
この付録は本編の「0. 変数の定義」と「3. Logstash 収集環境」で作成したリソース(ワークスペース、DCE、DCR)があることを前提にしています。オンプレミス側のサーバーは Ubuntu 22.04 を例にしています。
A-1. 本編(Azure VM)との違い
| 項目 | Azure VM に置く場合(本編) | オンプレミスに置く場合(付録) |
|---|---|---|
| Syslog フォワーダーの AMA 導入 | DCR を作ると自動で入る | 先に Azure Arc に接続 してから DCR を関連付ける |
| Logstash の認証 | VM のマネージド ID | アプリ登録(サービス プリンシパル)+ クライアント シークレット |
| Azure への通信経路 | VNet → NAT Gateway | 社内ネットワーク → ファイアウォール / プロキシ → インターネット(または専用線) |
| プロキシ | 不要 | Arc エージェント、AMA、Logstash プラグインで それぞれ別に設定 |
| 秘密情報 | 不要(マネージド ID) | クライアント シークレットを Logstash キーストアで保護、期限管理が必要 |
| 送信できないときの退避 | 意識しなくてよい | Logstash は永続キューを有効にしておくと安心 |
A-2. 注意点
1. 通信はすべて「オンプレミス → Azure」の HTTPS 443 だけ
Azure からオンプレミスへの受信は不要です。ファイアウォールでは、オンプレミスのサーバーから次の宛先への 送信 TCP 443 を許可します(主なもの)。
| 用途 | 宛先 |
|---|---|
| Microsoft Entra ID(認証) |
login.microsoftonline.com、login.windows.net、*.login.microsoft.com、pas.windows.net
|
| Azure Resource Manager | management.azure.com |
| Azure Arc エージェント |
*.his.arc.azure.com、*.guestconfiguration.azure.com、guestnotificationservice.azure.com、*.guestnotificationservice.azure.com、azgn*.servicebus.windows.net、*.blob.core.windows.net
|
| Arc エージェントの入手 |
gbl.his.arc.azure.com、download.microsoft.com、packages.microsoft.com
|
| Azure Monitor Agent |
global.handler.control.monitor.azure.com、japaneast.handler.control.monitor.azure.com、<ワークスペース ID>.ods.opinsights.azure.com
|
| Logstash(Logs Ingestion API) | <DCE 名>.japaneast-1.ingest.monitor.azure.com |
| Logstash とプラグインの入手 |
artifacts.elastic.co、rubygems.org(オフライン導入する場合は不要) |
Azure Monitor Agent の通信先には HTTPS インスペクション(SSL 復号)をかけない でください。公式ドキュメントでも無効化が求められています。正確な宛先一覧は環境によって変わるため、A-3 の azcmagent check と、末尾の参考リンクの公式ドキュメントで必ず確認してください。
2. Syslog フォワーダーは Azure Arc への接続が必須
Azure Monitor Agent(AMA)は Azure のリソースにしか入れられません。オンプレミスのサーバーは Azure Arc 対応サーバー として登録すると Azure 上のリソースとして扱えるようになり、DCR の関連付けと AMA の導入ができます。
3. Logstash はマネージド ID ではなくアプリ登録で認証する
プラグインの README では、マネージド ID は「Azure VM 上で動かす場合」の方式として説明されています。オンプレミスでは アプリ登録(サービス プリンシパル)とクライアント シークレット を使い、DCR に「Monitoring Metrics Publisher」ロールを付与します。シークレットには有効期限があるので、期限切れで取り込みが止まらないよう更新予定を管理してください。
4. プロキシは 3 か所で別々に設定する
社内プロキシを経由する場合、設定は共有されません。
-
Azure Arc エージェント:
azcmagent config set proxy.url -
Azure Monitor Agent:拡張機能の設定(
settingsのproxy)。Arc エージェントの設定は引き継がれません。 -
Logstash プラグイン:出力設定の
proxy(必要に応じてproxy_aad、proxy_endpoint)。この設定はプラグインの新しいバージョン(README では v2.5 系で記載)で追加されたものなので、導入したバージョンの README を確認してください。
5. 止まったときにログを失わない工夫
回線やプロキシの障害で Azure に送れない時間帯があっても、ログを失いにくくしておきます。
-
Logstash:永続キュー(
queue.type: persisted)を有効にし、ディスクに退避させる。 - Syslog フォワーダー:ディスクの空き容量を監視する。受信量が多い場合は、Microsoft の「Azure Monitor Agent Performance Benchmark」を参考にサイズを決め、複数台をロードバランサーの後ろに並べる。
6. 時刻同期とタイムゾーン
TimeGenerated がずれると、分析ルールの検知漏れや調査時の混乱につながります。フォワーダー、Logstash、ログを送る機器のすべてで NTP による時刻同期を有効にしてください。
7. 閉域で接続したい場合
ExpressRoute や VPN で Azure とつながっていて、インターネットを経由させたくない場合は、Azure Monitor Private Link Scope(AMPLS)とプライベート エンドポイントで構成できます。この付録では扱いませんが、その場合は DCE もプライベート側を使う必要があります。
A-3. 手順:オンプレミスの Syslog フォワーダー(Azure Arc + AMA)
A-3-1. 追加の変数とリソース プロバイダーの登録
Cloud Shell で、本編の「0. 変数の定義」を貼り付けたうえで次を実行します。ARC_MACHINE は Azure 上での表示名です(オンプレミスのホスト名にそろえるのがおすすめです)。
ARC_MACHINE=onprem-syslog01
SUB_ID=$(az account show --query id -o tsv)
TENANT_ID=$(az account show --query tenantId -o tsv)
az provider register --namespace Microsoft.HybridCompute
az provider register --namespace Microsoft.GuestConfiguration
az provider register --namespace Microsoft.HybridConnectivity
az provider register --namespace Microsoft.AzureArcData
az extension add -n connectedmachine --upgrade --yes
A-3-2. 通信先の確認用リストを作る
自分の環境のワークスペース ID を入れた通信先リストを出力します。ネットワーク担当者への申請にそのまま使えます。
WS_ID=$(az monitor log-analytics workspace show -g "$RG" -n "$LAW" --query customerId -o tsv)
cat <<EOF
global.handler.control.monitor.azure.com:443
${LOC}.handler.control.monitor.azure.com:443
${WS_ID}.ods.opinsights.azure.com:443
management.azure.com:443
login.microsoftonline.com:443
gbl.his.arc.azure.com:443
EOF
A-3-3. Arc エージェントのインストール(オンプレミスのサーバー)
プロキシなし の場合:
wget -O /tmp/install_linux_azcmagent.sh https://gbl.his.arc.azure.com/azcmagent-linux
sudo bash /tmp/install_linux_azcmagent.sh
プロキシあり の場合(http://proxy.example.local:8080 は自社のプロキシに置き換え):
export https_proxy=http://proxy.example.local:8080
wget -O /tmp/install_linux_azcmagent.sh https://gbl.his.arc.azure.com/azcmagent-linux
sudo bash /tmp/install_linux_azcmagent.sh --proxy "http://proxy.example.local:8080"
sudo azcmagent config set proxy.url "http://proxy.example.local:8080"
A-3-4. Azure Arc への接続
Cloud Shell で、オンプレミスのサーバーに貼り付ける接続コマンドを生成します。
cat <<EOF
===== ここから下をオンプレミス Syslog フォワーダーに貼り付け =====
sudo azcmagent connect --resource-group "${RG}" --tenant-id "${TENANT_ID}" --subscription-id "${SUB_ID}" --location "${LOC}" --resource-name "${ARC_MACHINE}" --cloud AzureCloud --use-device-code
===== ここまで =====
EOF
罫線の間の行をオンプレミスのサーバーで実行すると、ブラウザーで開く URL とコードが表示されます。作業端末のブラウザーでサインインすると接続が完了します。
接続に使うアカウントには、リソースグループに対する「Azure Connected Machine Onboarding」以上の権限が必要です。複数台をまとめて登録する場合は、サービス プリンシパルを使ったスクリプト登録が便利です(Azure ポータルの Azure Arc > マシン > 追加 から生成できます)。
接続できたかと、必要な通信先に届くかを確認します。
sudo azcmagent show
sudo azcmagent check --location japaneast
azcmagent show の Agent Status が Connected になっていれば OK です。
A-3-5. AMA のインストール(プロキシありの場合のみ)
プロキシを使わない場合は、この手順を飛ばして A-3-6 に進んでください(DCR を関連付けると AMA が自動で入ります)。
プロキシを使う場合は、DCR を関連付ける前に、プロキシ設定付きで AMA を入れておきます。
az connectedmachine extension create \
--resource-group "$RG" \
--machine-name "$ARC_MACHINE" \
--location "$LOC" \
--name AzureMonitorLinuxAgent \
--publisher Microsoft.Azure.Monitor \
--type AzureMonitorLinuxAgent \
--enable-auto-upgrade true \
--settings '{"proxy":{"mode":"application","address":"http://proxy.example.local:8080","auth":"false"}}'
プロキシに認証が必要な場合は、"auth":"true" にしたうえで --protected-settings '{"proxy":{"username":"<ユーザー名>","password":"<パスワード>"}}' を追加します。
A-3-6. DCR にオンプレミスのサーバーを関連付ける
本編で作った Syslog 用 DCR(dcr-syslog-demo)と CEF 用 DCR(dcr-cef-demo)に、Arc サーバーを追加します。
ARC_ID=$(az connectedmachine show -g "$RG" -n "$ARC_MACHINE" --query id -o tsv)
for DCR_NAME in dcr-syslog-demo dcr-cef-demo; do
DCR_RID=$(az monitor data-collection rule show -g "$RG" -n "$DCR_NAME" --query id -o tsv)
az monitor data-collection rule association create \
--name "assoc-${ARC_MACHINE}-${DCR_NAME}" \
--rule-id "$DCR_RID" \
--resource "$ARC_ID"
done
CEF 用の DCR を作っていない場合、dcr-cef-demo の行はエラーになりますが問題ありません。ポータルで行う場合は、データ コネクタ > Syslog via AMA > コネクタ ページを開く で対象の DCR を編集し、リソース タブでオンプレミスのサーバー(種類が Azure Arc のマシン)を追加します。
数分後、AMA が入ったことを確認します。
az connectedmachine extension list -g "$RG" --machine-name "$ARC_MACHINE" --query "[].{name:name, state:provisioningState}" -o table
A-3-7. フォワーダーの構成と OS ファイアウォール
本編の 2-4 と同じスクリプトを、オンプレミスのサーバーで実行します。
cd ~
wget -O Forwarder_AMA_installer.py https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/DataConnectors/Syslog/Forwarder_AMA_installer.py
sudo python3 Forwarder_AMA_installer.py
OS のファイアウォールが有効な場合は、514 番ポートの受信を許可します。
sudo ufw allow 514/tcp
sudo ufw allow 514/udp
sudo firewall-cmd --permanent --add-port=514/tcp
sudo firewall-cmd --permanent --add-port=514/udp
sudo firewall-cmd --reload
時刻同期ができているかも確認します。System clock synchronized: yes なら OK です。
timedatectl status
A-3-8. 機器側の送信先を変更して確認する
ネットワーク機器やセキュリティ製品の Syslog 送信先を、オンプレミスのフォワーダーの IP アドレス(TCP または UDP 514)に変更します。Linux サーバーから試す場合は次のとおりです(192.0.2.10 はフォワーダーの IP に置き換え)。
logger -n 192.0.2.10 -P 514 -T -p auth.warning -t sshd "Failed password for invalid user demo from 192.0.2.50 port 50001 ssh2"
数分後、ログ画面で確認します(onprem-syslog01 は自分のホスト名に置き換え)。
Syslog
| where TimeGenerated > ago(30m)
| where Computer has "onprem-syslog01"
| summarize Count = count() by Computer, Facility, SeverityLevel
A-4. 手順:オンプレミスの Logstash(アプリ登録で認証)
A-4-1. アプリ登録の作成と権限付与
Cloud Shell で、Logstash 用のサービス プリンシパルを作り、DCR に「Monitoring Metrics Publisher」ロールを同時に付与します。シークレットの有効期間は 1 年にしています。
DCR_RESOURCE_ID=$(az monitor data-collection rule show -g "$RG" -n "$DCR_LOGSTASH" --query id -o tsv)
SP_JSON=$(az ad sp create-for-rbac \
--name sp-logstash-sentinel-poc \
--role "Monitoring Metrics Publisher" \
--scopes "$DCR_RESOURCE_ID" \
--years 1 -o json)
AZ_CLIENT_ID=$(echo "$SP_JSON" | jq -r .appId)
AZ_CLIENT_SECRET=$(echo "$SP_JSON" | jq -r .password)
AZ_TENANT_ID=$(echo "$SP_JSON" | jq -r .tenant)
echo "client_id: $AZ_CLIENT_ID"
ロールの反映には最大 30 分程度かかることがあります。反映前に送信すると 403 エラーになります。
A-4-2. Logstash と出力プラグインのインストール
インターネットに出られる場合は、本編の 3-1(Logstash のインストール)と 3-2(プラグインのインストール)を オンプレミスの Logstash サーバーで そのまま実行します。プロキシ経由の場合は、先に次を実行してから同じ手順を行います。
export http_proxy=http://proxy.example.local:8080
export https_proxy=http://proxy.example.local:8080
echo 'Acquire::http::Proxy "http://proxy.example.local:8080";' | sudo tee /etc/apt/apt.conf.d/95proxy
echo 'Acquire::https::Proxy "http://proxy.example.local:8080";' | sudo tee -a /etc/apt/apt.conf.d/95proxy
プラグインのインストール(logstash-plugin install)は sudo で実行するため、export した変数が引き継がれないことがあります。その場合は sudo -E /usr/share/logstash/bin/logstash-plugin install microsoft-sentinel-log-analytics-logstash-output-plugin のように -E を付けて実行してください。
インターネットに出られない(閉域) 場合は、インターネットに出られる別の Logstash 環境(同じバージョン)でオフライン パックを作り、ファイルを持ち込んでインストールします。
sudo /usr/share/logstash/bin/logstash-plugin install microsoft-sentinel-log-analytics-logstash-output-plugin
sudo /usr/share/logstash/bin/logstash-plugin prepare-offline-pack --output /tmp/sentinel-plugin.zip microsoft-sentinel-log-analytics-logstash-output-plugin
/tmp/sentinel-plugin.zip をオンプレミスの Logstash サーバーの /tmp にコピーしてから実行します。
sudo /usr/share/logstash/bin/logstash-plugin install file:///tmp/sentinel-plugin.zip
sudo /usr/share/logstash/bin/logstash-plugin list --verbose | grep microsoft
A-4-3. 接続情報を渡す(貼り付け用コマンドの生成)
本編の 3-7 と同じ考え方で、Cloud Shell から貼り付け用コマンドを生成します。秘密情報ではない値は環境変数ファイルに入れ、クライアント シークレットだけは次の A-4-4 でキーストアに入れます。
DCE_URI=$(az monitor data-collection endpoint show -g "$RG" -n "$DCE" --query logsIngestion.endpoint -o tsv)
DCR_IMMUTABLE_ID=$(az monitor data-collection rule show -g "$RG" -n "$DCR_LOGSTASH" --query immutableId -o tsv)
STREAM_NAME=$(az monitor data-collection rule show -g "$RG" -n "$DCR_LOGSTASH" --query "keys(streamDeclarations)[0]" -o tsv)
cat <<EOF
===== ここから下をオンプレミス Logstash に貼り付け =====
sudo tee /etc/default/logstash > /dev/null <<'EOT'
DCE_URI="${DCE_URI}"
DCR_ID="${DCR_IMMUTABLE_ID}"
STREAM_NAME="${STREAM_NAME}"
AZ_TENANT_ID="${AZ_TENANT_ID}"
AZ_CLIENT_ID="${AZ_CLIENT_ID}"
EOT
sudo chmod 600 /etc/default/logstash
===== ここまで =====
次の手順でキーストアに入力するクライアント シークレット:
${AZ_CLIENT_SECRET}
EOF
罫線の間の行をオンプレミスの Logstash サーバーに貼り付けて実行します。表示されたクライアント シークレットは、次の手順で使ったら画面から消し、どこにも保存しないでください。
Cloud Shell のセッションが切れて AZ_CLIENT_SECRET などが消えた場合は、AZ_CLIENT_ID に client_id を設定してから az ad app credential reset --id "$AZ_CLIENT_ID" --years 1 でシークレットを再発行します。
A-4-4. クライアント シークレットをキーストアに保存
sudo /usr/share/logstash/bin/logstash-keystore --path.settings /etc/logstash create
パスワードなしで続けるか聞かれたら y を入力します(キーストアにパスワードを付ける場合は、そのパスワードを /etc/default/logstash に LOGSTASH_KEYSTORE_PASS="..." として追記します)。続けてシークレットを登録します。
sudo /usr/share/logstash/bin/logstash-keystore --path.settings /etc/logstash add AZ_CLIENT_SECRET
Enter value for AZ_CLIENT_SECRET: と表示されたら、A-4-3 で表示されたシークレットを貼り付けます。最後に、Logstash サービスが読めるよう所有者を変更します。
sudo chown logstash:logstash /etc/logstash/logstash.keystore
sudo chmod 600 /etc/logstash/logstash.keystore
sudo /usr/share/logstash/bin/logstash-keystore --path.settings /etc/logstash list
A-4-5. 永続キューの有効化
Azure に送れない間のイベントをディスクに退避させます。4gb は退避に使う最大サイズで、ディスクの空きに合わせて調整してください。
sudo tee -a /etc/logstash/logstash.yml > /dev/null <<'EOF'
pipeline.ecs_compatibility: disabled
queue.type: persisted
queue.max_bytes: 4gb
EOF
grep -E 'ecs_compatibility|queue\.' /etc/logstash/logstash.yml
本編の 3-1 で pipeline.ecs_compatibility: disabled を追記済みの場合は、同じ行が 2 回入りますが動作に問題はありません。気になる場合は /etc/logstash/logstash.yml から重複行を削除してください。
A-4-6. 出力設定
プロキシなし の場合:
sudo tee /etc/logstash/conf.d/sentinel.conf > /dev/null <<'EOF'
input {
tcp {
port => 5000
codec => json_lines
}
}
output {
microsoft-sentinel-log-analytics-logstash-output-plugin {
data_collection_endpoint => "${DCE_URI}"
dcr_id => "${DCR_ID}"
stream_name => "${STREAM_NAME}"
tenant_id => "${AZ_TENANT_ID}"
client_id => "${AZ_CLIENT_ID}"
client_secret => "${AZ_CLIENT_SECRET}"
}
}
EOF
プロキシあり の場合(http://proxy.example.local:8080 は自社のプロキシに置き換え):
sudo tee /etc/logstash/conf.d/sentinel.conf > /dev/null <<'EOF'
input {
tcp {
port => 5000
codec => json_lines
}
}
output {
microsoft-sentinel-log-analytics-logstash-output-plugin {
data_collection_endpoint => "${DCE_URI}"
dcr_id => "${DCR_ID}"
stream_name => "${STREAM_NAME}"
tenant_id => "${AZ_TENANT_ID}"
client_id => "${AZ_CLIENT_ID}"
client_secret => "${AZ_CLIENT_SECRET}"
proxy => "http://proxy.example.local:8080"
}
}
EOF
構文をチェックしてから起動します。Configuration OK と表示されれば構文は正しいです。
sudo -u logstash bash -c 'set -a; . /etc/default/logstash; /usr/share/logstash/bin/logstash --path.settings /etc/logstash -t'
sudo systemctl enable logstash
sudo systemctl restart logstash
/etc/logstash/conf.d/ にある .conf ファイルはすべて 1 つのパイプラインとして読み込まれます。本編で作った demo.conf などが残っていると、同じポートを二重に待ち受けて起動に失敗するため、不要なファイルは削除してください。
OS のファイアウォールが有効な場合は、5000 番ポートの受信を許可します。
sudo ufw allow 5000/tcp
A-4-7. 疎通と取り込みの確認
DCE に届くかを確認します。000 以外の HTTP ステータス(404 など)が返れば通信は届いています。000 の場合は、ファイアウォールかプロキシで止まっています。
sudo bash -c '. /etc/default/logstash; curl -sS -o /dev/null -w "%{http_code}\n" "$DCE_URI"'
プロキシ経由の場合:
sudo bash -c '. /etc/default/logstash; curl -sS -x http://proxy.example.local:8080 -o /dev/null -w "%{http_code}\n" "$DCE_URI"'
テストイベントを 10 件送ります。
for i in $(seq 1 10); do
echo '{"EventType":"LoginFailed","UserName":"alice","SrcIp":"192.0.2.50","App":"demo-web","Severity":"High"}' | nc -q 1 127.0.0.1 5000
done
sudo tail -n 50 /var/log/logstash/logstash-plain.log
数分後、ログ画面で確認します。
LogstashDemo_CL
| where TimeGenerated > ago(30m)
| where SrcIp == "192.0.2.50"
| project TimeGenerated, EventType, UserName, SrcIp, App, Severity
A-5. トラブルシューティング(オンプレミス特有)
| 事象 | 主な原因 | 確認・対処 |
|---|---|---|
azcmagent connect が失敗する |
通信先がブロックされている、プロキシ未設定、権限不足 |
sudo azcmagent check --location japaneast で届かない宛先を確認。azcmagent show でプロキシ設定を確認。接続ユーザーの権限を確認 |
Arc は接続済みだが AMA が Failed
|
AMA の通信先がブロック、プロキシが AMA に設定されていない | A-3-5 のプロキシ設定付きで AMA を入れ直す。HTTPS インスペクションの対象から外す |
| Syslog テーブルにオンプレミスのデータが出ない | DCR の関連付け漏れ、OS ファイアウォールで 514 番が閉じている | A-3-6 の関連付けを確認。sudo ss -lntup | grep ':514' と ufw / firewalld の設定を確認 |
| Logstash の送信で 401 / 403 | シークレットの誤り・期限切れ、ロール未反映 | キーストアの値を登録し直す。az ad app credential list --id "$AZ_CLIENT_ID" で期限を確認。ロール反映まで最大 30 分待つ |
| Logstash の送信でタイムアウト | DCE やログイン先への通信がブロック、プロキシ未設定 | A-4-7 の curl で疎通確認。出力設定の proxy を確認 |
TimeGenerated がずれる |
サーバーや機器の時刻ずれ |
timedatectl status で同期状態を確認し、NTP を設定 |
| 回線障害後にイベントが欠ける | 永続キュー未設定、キュー容量不足 | A-4-5 の永続キューを有効化し、queue.max_bytes を見直す |
A-6. 後片付け(オンプレミス側)
オンプレミスのサーバーを Azure Arc から外し、エージェントを削除します。disconnect を実行すると Azure 上の Arc リソースも削除されます。
sudo azcmagent disconnect --use-device-code
sudo apt-get remove -y azcmagent
Logstash 用のアプリ登録を削除します。1 行目の値は A-4-1 で表示された client_id に置き換えてください(同じ Cloud Shell セッションが続いている場合は 1 行目は不要です)。
AZ_CLIENT_ID=00000000-0000-0000-0000-000000000000
az ad app delete --id "$AZ_CLIENT_ID"
A-7. 参考(付録)
- Connected Machine agent network requirements(Microsoft Learn)
- Manage and maintain Azure Connected Machine agent proxy settings(Microsoft Learn)
- Azure Monitor Agent network configuration(Microsoft Learn)
- Ingest syslog and CEF messages to Microsoft Sentinel with the Azure Monitor Agent(Microsoft Learn)
- Microsoft Sentinel Logstash 出力プラグイン(Java 版 README、GitHub Azure/Azure-Sentinel)
- Logstash Offline Plugin Management(Elastic)
- Logstash Persistent Queues(Elastic)
- Logstash Secrets Keystore(Elastic)