Azure 上の Windows Server 2025 仮想マシンで Apache を動かし、静的パブリック IP と DNS 名ラベル(xxx.centralus.cloudapp.azure.com)も設定したのに、インターネット側から HTTP でアクセスできない――。DNS 解決が正しくても「通信の通り道」のどこかで止まっていると外部公開は成立しません。原因を最短で切り分け、確実に直す手順をまとめます。
症状の整理(今回の前提)
- Azure 上の Windows Server 2025 VM に 静的パブリック IP と DNS 名ラベル(例:
xxx.centralus.cloudapp.azure.com)を設定済み - NSG(ネットワーク セキュリティ グループ)で 80/TCP を許可済み
nslookupでは DNS 名が正しくパブリック IP に解決される- VM 内(ローカル)では
http://localhostなどで Apache にアクセスできる - しかし外部から
http://xxx.centralus.cloudapp.azure.comにアクセスすると「このページに到達できません」
外部から Apache に届くまでの“経路”を把握する
DNS が正しいのに外部から見えない場合、原因は Apache だけではなく、Azure と Windows 側の複数層に分かれます。まずは全体像を押さえると、切り分けが速くなります。
| 層 | ここで止まるとどう見えるか | 主な確認先 | 代表的な原因 |
|---|---|---|---|
| DNS | 名前解決できない/別 IP に解決 | nslookup、DNS 名ラベル | DNS ラベル未設定、キャッシュ、別 IP に紐づく |
| Azure パブリック IP | 外部から接続が開始されない | Public IP リソース、VM の NIC | 割り当て先が違う、VM 停止(割り当て解除) |
| Azure NSG/ルーティング | タイムアウトしやすい | NSG 受信ルール、有効なセキュリティ規則 | 許可がない/優先度で拒否に負ける/サブネット側 NSG |
| Windows Defender ファイアウォール | タイムアウト/接続できない | 受信規則、適用プロファイル | ポート/アプリが許可されていない、Public プロファイルでブロック |
| Apache(Listen/サービス) | 接続拒否/応答がない | httpd.conf、サービス状態、ポート待受 | 127.0.0.1 のみ待受、サービス停止、他サービスと競合 |
最短で切り分けるための“3つのテスト”
外部公開トラブルは「どの層で止まっているか」を短時間で確定させるのが重要です。以下は現場で再現性が高い順番です。
名前解決(DNS)が正しいか
これはすでに問題なさそうですが、念のため手順を固定しておきます。
nslookup xxx.centralus.cloudapp.azure.com
- 期待:返ってくる A レコードが VM に割り当てた静的パブリック IP と一致
- ズレる:別リソースに付いている、DNS キャッシュ、DNS ラベルの付け先違い
外部クライアントから 80/TCP が開いているか
ブラウザよりも「TCP でつながるか」を先に確認すると、切り分けが明確です。
curl -v http://xxx.centralus.cloudapp.azure.com/
Windows クライアントなら PowerShell でこちらも有効です。
Test-NetConnection -ComputerName xxx.centralus.cloudapp.azure.com -Port 80
- タイムアウト:NSG や Windows ファイアウォールで“落としている”可能性が高い
- Connection refused(拒否):Apache が待ち受けていない、別サービスが応答している等
- HTTP ステータス(200/301/403/404 等)が返る:ネットワークは通っており Apache まで到達
VM 内で“外向け IP(NIC)宛”でも応答するか
ローカルで localhost が表示できても、Apache が 127.0.0.1 のみ待受になっていると外から見えません。VM 内で NIC のプライベート IP を指定して確認します。
curl -v http://<VMのプライベートIP>/
- ここで応答できる:Apache の待受は比較的正常。疑うべきは NSG / Windows ファイアウォール
- ここで応答できない:Apache の Listen、サービス状態、ポート競合を優先して確認
Azure 側の基本チェック(外部公開の土台)
Azure 側は「設定したつもり」が一番起きやすいポイントです。特に NSG は“どこに紐づくか(NIC かサブネットか)”と“優先度”が罠になりがちです。
VM が稼働しているか(停止と割り当て解除に注意)
- Azure ポータルで対象 VM が 実行中 になっているか確認します。
- 停止(割り当て解除) になっていると、パブリック IP は割り当たっていても外部からの到達性が落ちたり、想定通りに応答しないケースがあります。
パブリック IP と DNS 名ラベルの紐づけが正しいか
よくあるミスは「DNS 名ラベルを付けた Public IP が、実際には別の NIC/別 VM に付いている」パターンです。
- Public IP リソースの画面で、割り当て先(Associated to) が対象 VM の NIC になっているか確認
- Public IP の DNS 名ラベル が
xxxで、FQDN がxxx.centralus.cloudapp.azure.comになっているか確認
NSG 受信ルール(80/TCP)が“効いている”か
NSG はルールが存在しても、優先度や紐づけ先の違いで効かないことがあります。以下の観点で確認します。
| 確認項目 | 見る場所 | 期待値 | ありがちな落とし穴 |
|---|---|---|---|
| 受信許可ルール | NSG > 受信セキュリティ規則 | TCP / 80 / Source: Any / Action: Allow | プロトコルが Any でない、宛先が違う、ポートが 8080 など |
| 優先度 | 同上 | Allow ルールが拒否より上(数値が小さい) | 先に Deny があり、Allow が“潰れている” |
| 紐づけ先 | NIC またはサブネット | 対象の NIC/サブネットに適用されている | 違うサブネットの NSG を見ている |
| 有効な規則 | NIC > 有効なセキュリティ規則 | 80/TCP が Allow として表示 | NIC とサブネットの複合で結果が変わる |
ポータル上で “有効なセキュリティ規則(Effective security rules)” を見ると、実際に最終的に適用されているルールが分かります。「ルールは作ったのに通らない」時はここを最優先で確認します。
追加で疑うべき Azure 側の要素(該当する場合)
- Defender for Cloud の JIT(Just-In-Time) を有効にしている場合、指定時間外は NSG 側で自動的に閉じられることがあります。短時間だけ通って、また通らなくなる場合は要注意です。
- 構成上、Azure Firewall / Application Gateway / NVA を経由している場合は、その機器側の許可ルールも別途必要です。
- ロードバランサー配下に置いている場合は、ロードバランサーのルール(LB ルール / NAT ルール) 側で 80 を流しているかも確認します。
今回の“オチ”になりやすい:Windows Defender ファイアウォール
Azure と Apache が正しく見えているのに外部から到達しないケースで、最後に残るのが Windows Server 側の受信制御です。特に Windows Server では、次の理由で盲点になりやすいです。
- NSG は通っているのに、OS で落ちると外からは「到達できない」に見える
- Azure 上の NIC は環境によって Public プロファイル と判定されやすく、Public では既定で厳しめ
- 「80 を開けた」つもりでも、適用プロファイルが違う/より強い拒否ルールがある/アプリ単位で許可が必要な運用になっていることがある
まず確認:ネットワーク プロファイル(Domain/Private/Public)
同じ受信ルールでも、どのプロファイルで有効かが違うと、想定通りに通りません。PowerShell で現在のプロファイルを確認します。
Get-NetConnectionProfile
結果の NetworkCategory が Public の場合、受信規則が Public で許可されていないとブロックされます。
受信規則に「80 番ポート」または「Apache」を許可するルールがあるか
GUI(Windows Defender ファイアウォールの詳細設定)でも確認できますが、運用や検証では PowerShell が速いです。例として “80 を許可するルール” の存在を検索します。
Get-NetFirewallRule | Where-Object { $_.DisplayName -match "HTTP|80|Apache" } |
Select-Object DisplayName, Enabled, Direction, Action, Profile
ここで重要なのは「ルールがあるか」だけではなく、次の 3 点です。
- Direction が Inbound になっている(受信規則である)
- Action が Allow になっている
- Profile に Public が含まれる(または Any)
解決策:Apache の受信許可を明示する(今回の決定打)
最終的な原因が Windows Defender ファイアウォールだった場合、手堅い修正は「80/TCP の受信許可」を OS 側で明示することです。ポート単位の許可は切り分けが簡単で、まず最初に適用しやすい方法です。
New-NetFirewallRule -DisplayName "Allow HTTP 80 for Apache" `
-Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow
環境によっては、Public でのみ通したい(または Any にしたい)などの要件があるため、必要ならプロファイルも指定します。
New-NetFirewallRule -DisplayName "Allow HTTP 80 for Apache (Public)" `
-Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow -Profile Public
さらに「このケースのオチ」として重要なのが、ポート 80 自体は開いているのに、Apache がポート 80 を使用することが許可されていない運用・設定があり得る点です。例えば次のような状況です。
- 既存のファイアウォール規則が「ポート」ではなく「プログラム単位」で許可する方針になっている
- より具体的な拒否ルール(Program 単位の Deny 等)が先に評価され、Apache だけ弾かれている
- セキュリティ製品や組織ポリシーで、アプリケーション単位の通信許可が必須になっている
この場合は、httpd.exe(Apache)をプログラム単位で許可するルールが効果的です。Apache のインストールパスに合わせて指定します(例は一般的なパスです)。
New-NetFirewallRule -DisplayName "Allow Apache httpd.exe (HTTP 80)" `
-Direction Inbound -Action Allow -Protocol TCP -LocalPort 80 `
-Program "C:\Apache24\bin\httpd.exe"
GUI で設定する場合は以下の流れです。
- 「Windows Defender ファイアウォールの詳細設定」
- 「受信の規則」→「新しい規則」
- まずは ポート を選び、TCP/80 を許可(切り分けが速い)
- 必要なら プログラム を選び、
httpd.exeを許可(運用ポリシーに合わせる) - プロファイル(Domain/Private/Public)を環境に合わせて選択
「受信は許可したのに…」の時に見るべきポイント
ルールを追加しても改善しない場合は、次の観点が効きます。
| チェック | 狙い | 確認方法 |
|---|---|---|
| ルールが無効になっていないか | 作ったが Disabled のままを防ぐ | 受信規則の「有効」列、または PowerShell で Enabled を確認 |
| Public プロファイルで適用されているか | Azure VM で Public 扱いになっているケース対応 | Get-NetConnectionProfile と規則の Profile |
| より優先度の高い “拒否” がないか | Allow を入れても Deny が勝つ状況を排除 | 同ポート/同プログラムの Deny 規則がないか検索 |
| サードパーティ製 FW/EDR の影響 | Windows FW 以外で止まるケース | 製品のログ、ポリシー、検疫状況を確認 |
Apache 側の設定確認(Listen と待受の確認が最重要)
VM 内で localhost だけ見えている状態は、Apache が “ローカル専用” の待受になっている可能性があります。外部公開なら、NIC 宛の通信を受けられるバインドが必要です。
Apache サービスが起動しているか
- サービス(
services.msc)で Apache が「実行中」か確認 - コマンドで確認するなら、インストール形態に合わせて
httpd -k statusやタスクマネージャーのプロセスを確認
Listen が 127.0.0.1 になっていないか
httpd.conf などの設定で、以下のように 127.0.0.1:80 のみになっていると外部から接続できません。
# NG例(ローカルからしか見えない)
Listen 127.0.0.1:80
外部公開を前提にするなら、次のようにすべてのインターフェイスで待受する設定が基本です。
# OK例
Listen 80
# または
Listen 0.0.0.0:80
IPv6 を使う環境なら、必要に応じてこちらも検討します。
Listen [::]:80
実際に 0.0.0.0:80 で待ち受けているか(決定的な確認)
設定を見ても不安なときは、OS が実際に待ち受けているかを確認するのが確実です。
netstat -ano | findstr :80
PowerShell ならこちらでも確認できます。
Get-NetTCPConnection -LocalPort 80 -State Listen
期待値は「LocalAddress が 0.0.0.0(または VM のプライベート IP)」で LISTEN になっていることです。もし LISTEN が出ない、または別プロセスが掴んでいる場合は、ポート競合を疑います。
ポート 80 の競合(IIS/HTTP.sys)に注意
Windows Server では IIS や別サービスが 80 を使用していて Apache が起動できていない(または別ポートに逃がしている)ケースがあります。netstat の PID を見て、どのプロセスが掴んでいるかを確認します。
- PID が Apache(httpd.exe)でない場合:IIS(World Wide Web Publishing Service)などが競合している可能性
- 対策:IIS を停止、または Apache を 8080 など別ポートに変更して検証(本番は要設計)
外部公開を復旧させるための手順(おすすめ順)
同様の「公開 DNS/IP なのにページに届かない」問題は、次の順でチェックすると無駄が少なく、原因の切り分けも早いです。
- VM が実行中であることを確認(停止・割り当て解除の除外)
- Public IP と DNS 名ラベルが 対象 VM の NIC に紐づいているか確認
- NSG の 80/TCP 受信許可 が “有効な規則” として適用されているか確認
- Windows Defender ファイアウォールで 受信(Inbound) を許可(ポート 80、必要なら Apache プログラム単位)
- Apache の Listen が 0.0.0.0:80 相当になっているか、実際に LISTEN しているか確認
実運用を意識した“安全な公開”の考え方
「とりあえず外から見える」まで直した後は、公開範囲と暗号化を整えると安心です。特に Windows Server 2025 を Azure で外部公開する場合、インターネットに直結するため、基本のセキュリティ設計が効きます。
HTTP(80) を開けるのは最小限にし、HTTPS(443) を主役にする
- 可能なら 80 は HTTPS リダイレクト用途に留め、実体は 443 に寄せる
- NSG でも 443/TCP を許可し、Apache 側で TLS 設定(証明書)を行う
NSG と Windows ファイアウォールの“二重ガード”を前提に設計する
Azure の NSG だけに頼るのではなく、OS 側でも最小許可にしておくと、意図しない公開が起きにくくなります。
| 設定方針 | メリット | 注意点 |
|---|---|---|
| NSG: Any から 80/443 を許可 | 構成がシンプルでトラブルが少ない | インターネット全体に公開されるため、別途防御が必要 |
| NSG: 特定 IP のみ許可 | 攻撃面を大幅に減らせる | 固定 IP の拠点や VPN が前提になりやすい |
| Windows FW: ポート単位で許可 | 切り分けが容易、運用も比較的単純 | アプリ単位で制限したい組織ポリシーでは不足する場合がある |
| Windows FW: プログラム単位で許可 | “Apache だけ許可”が明確 | インストールパス変更や更新で再調整が必要になることがある |
ログを残して「次の障害対応」を短縮する
- Apache: access_log / error_log を定期的に確認できる場所へ(ローテーションも検討)
- Windows: ファイアウォールのログを必要に応じて有効化(許可/破棄の記録)
- Azure: Network Watcher や NSG フローログを使える状態にしておくと原因追跡が速い
それでも直らない場合の追加チェック(深掘り)
基本を全部確認しても改善しない場合は、“どこで落ちているか”をさらに強く特定します。ここからは該当するものだけで構いません。
Azure Network Watcher で接続の成否を確認する
- 「接続のトラブルシューティング」を使うと、NSG・ルーティング・宛先 VM の到達性を観点別に見られます。
- 「IP フローの検証」を使うと、特定の送信元/宛先/ポートが許可されるかを確認できます。
外部回線側の制限(社内回線・プロキシ)を疑う
社内ネットワークや厳しいプロキシ環境では、外向けの HTTP 通信が制限されていることがあります。別回線(モバイルテザリング等)でも同じ結果になるかで切り分けできます。
DNS キャッシュの影響を疑う
DNS の紐づけを変更した直後は、クライアント側や中継 DNS のキャッシュで古い IP を参照していることがあります。nslookup で正しい IP が返るかを複数環境で確認すると確実です。
現場で使えるチェックリスト(そのままコピペ用)
| 項目 | 確認方法 | OK の目安 |
|---|---|---|
| VM は実行中か | Azure ポータル | 「実行中」 |
| DNS は正しい IP に解決されるか | nslookup xxx.centralus.cloudapp.azure.com | 静的パブリック IP と一致 |
| NSG で 80/TCP が許可されているか | NSG 受信規則/有効な規則 | Allow が Deny より優先 |
| Windows FW のプロファイルは何か | Get-NetConnectionProfile | Public なら Public で許可が必要 |
| Windows FW で 80 を許可しているか | New-NetFirewallRule ... -LocalPort 80 | Inbound/Allow/適切な Profile |
| Apache が 80 で LISTEN しているか | netstat -ano | findstr :80 | httpd.exe が 0.0.0.0:80 で待受 |
| 外部から TCP 接続できるか | curl -v / Test-NetConnection | HTTP 応答が返る |
まとめ
- DNS 解決や Apache のローカル動作が正常でも、Azure NSG と Windows Defender ファイアウォール の両方で 80/TCP を許可できていないと、外部公開は成立しません。
- 今回のケースでは、最終的な原因が Windows Defender ファイアウォール にあり、Apache が 80 番を使うこと(受信通信)が明示的に許可されていない状態でした。
- 対策は、VM 稼働→Public IP/DNS 紐づけ→NSG 80/TCP→Windows FW の受信許可(必要なら Apache プログラム許可)→Apache Listenの順で確認すると、同種トラブルを最短で解決できます。

コメント