Windows 8 で 80番ポートが既に使われていてApache が起動しない

投稿日:2012年12月23日

Windows 7 から Windows 8 に、Windows をアップデートしたら、Apache が起動しなくなってしまいました・・・
Xampp のコントロール・パネルには、以下のようなログも出ています。

7:22:11  [main]     XAMPP Installation Directory: “c:\xampp\”
7:22:12  [main]     Checking for prerequisites
7:22:13  [main]     All prerequisites found
7:22:13  [main]     Initializing Modules
7:22:13  [Apache]     Problem detected!
7:22:13  [Apache]     Port 80 in use by “system”!
7:22:13  [Apache]     Apache WILL NOT start without the configured ports free!
7:22:13  [Apache]     You need to uninstall/disable/reconfigure the blocking application
7:22:13  [Apache]     or reconfigure Apache to listen on a different port
7:22:13  [mysql]     XAMPP MySQL Service is already running on port 3306
7:22:13  [filezilla]     XAMPP FileZilla FTP Server Service is already running on port 21
7:22:13  [filezilla]     XAMPP FileZilla FTP Server Service is already running on port 14147
7:22:13  [main]     Starting Check-Timer
7:22:13  [main]     Control Panel Ready

調べたところ、プロセスID 4番が既に 80番ポートを使っているようです。

C:\Windows\system32>netstat -oan | findstr -i “:80” | findstr -i “LISTEN”
TCP         0.0.0.0:80             0.0.0.0:0              LISTENING       4
TCP         [::]:80                [::]:0                 LISTENING       4

C:\Windows\system32>

このプロセスID 4番が何者かを調べるために、Process Expolere をダウンロードしてみました。
が、残念ながら 「System」になっており、これ以上何者かわからない状況でした。

image

検索してみると以下のような記事を見つけました。

windows – PID:4 using Port 80 – Super User

If it is System procress(PID 4), you need to disable HTTP.sys driver which is started on demand by other service, such as Windows Remote Management/Print Spooler on Windows 2008 or Windows 7.
(もし、それがプロセスID4のシステムプロセスなら、HTTP.sys を無効にする必要があります。HTTP.sys は、Windows 2008 や Windows 2007で、Windows Remote Managemetnや、Print Spooler サービス等の他のサービスからの要求によって起動します。

どうやら、 HTTP.sys というドライバーがこのポートを使用しているようです。個人的には Windows 7 でこの問題に遭遇した記憶はありませんでしたが、Windows 7 から導入されている仕組みのようです。

ドライバーなので、カーネルモードで動いているモジュールなので、止めて良いものが気になりますが、以下のような解説がありました。

First of all, the way http.sys works on newer Windows versions is a very useful feature. The reason behind http.sys is to have a single system service that listens on the all-important port 80 and be a mediator to different applications and services in the system that might like to handle incoming requests on port 80 but for different urls. What an integrated Windows application does, is use a Windows API for registering its own urls and then have them directed to itself. At the same time, there can be other applications also getting incoming requests to port 80 but for different registered urls.
(まずはじめに、新しい Windows に搭載されている http.sys はとても有用なサービスです。http.sys が導入された理由は、一つの http.sys というシステムサービスを使って、そのサービスに 80番ポートをLISTEN させる事で、その他の80番ポートを使用して自身のURLにアクセスするいろいろなアプリケーションの仲介役として機能させるためです。
Windows との統合を考えられたアプリケーションは、自分自身の URL を Windows API を使って Windows に登録し、80番ポートに来た自分の URL宛のリクエストを自分のプログラムに振り分ける。という動作をします。同時に、他のアプリケーションも、80番ポートを通して自分のURL に来たリクエストを自分のプログラムで受け取る事ができます)

参照元:Stop http.sys from listening on port 80 in Windows

自分でプログラムを書いてみないとピンと来ませんが、通常は一つのプログラムが80番ポートを占拠して他のプログラムが80番ポートを使えなくなってしまうのを、複数のプログラムで(少なくてもURLが違っていれば)シェアできるように仲介してくれるプログラムのようです。ただし、80番ポートを使うプログラムが、それように Windows APIを使って書かれていなければいけないようです。

対処方法1) HTTP.sys サービスを停止する。

追記)後述していますが、方法1では Windows 8 では、プリンターのスプーラーサービスが起動せず、印刷が使用できなくなる事がわかりました。結論は、「結局、最終的に意外な方法で解決」をお読み下さい。

レジストリを操作して、HTTP.sys のサービスを止めてしまいます。
ただし、この方法は HTTP.sys の仕組みを使用するサービスが居た場合、そのサービスに影響が出ますので、完璧ではありません。
この方法は以下に詳しいです。

windows – PID:4 using Port 80 – Super User

を参考にしてレジストリを変更します。

1. RegEdit を立ち上げます。
2. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP を開きます。
3. 「Start」の値を 「3」から「4」に変更します。

これは、ユーザーモードのアプリにたとえると、Windows 起動時に自動でサービスを起動させない設定になります。
カーネルモードで動作するドライバは、レジストリで起動制御をする必要があるので、こういう作業が必要になります。

ちなみに、この「Start」の値については、以下のように定義されています。

Start     REG_DWORD     Start constant
Specifies the starting values for the service as follows:

START TYPE     LOADER     MEANING

0x0            Kernel     Represents a part of the
(Boot)                    driver stack for the boot
                          (startup) volume and must
                          therefore be loaded by the
                          Boot Loader.

0x1            I/O        Represents a driver to be loaded
(System)       subsystem  at Kernel initialization.

0x2            Service    To be loaded or started
(Auto load)    Control    automatically for all startups,
               Manager    regardless of service type.

0x3            Service    Available, regardless of type,
(Load on       Control    but will not be started until
demand)        Manager    the user starts it (for example,
                          by using the Devices icon in
                          Control Panel).

0x4            Service    NOT TO BE STARTED UNDER ANY
(disabled)     Control    CONDITIONS.
               Manager

CurrentControlSet\Services サブキー エントリ」より

4. Windows を再起動します。

httpd.conf のポートの変更を元に戻して Apache を再起動させたら、通常通りにアクセスできるようになりました。
めでたし、めでたし。 ではありませんでした。(追記を参照ください)

追記:ある日、Webページの印刷を使用とした所、印刷ができなくなっている事に気づきました。
Printer Spooler」サービスを起動するようにエラーメッセージが出ていたので、「Printer Spooler」を起動させよとしても、サービスの画面からは起動できませんでした。

http.sys のサービスは、「Printer Spooler」サービスの関連サービスとなっていて、http.sys を留めるとプリンターが使えなくなってしまうようです・・・うーむ。

対処方法2) Apache の LISTEN ポートを 80 → 8080 へ変更 を試す。

追記)これも後述していますが、「WordPress を動かす」という目的だとApache のポートを変更すると WordPress の制約にひっかかる事がわかりました。結論は「結局、最終的に意外な方法で解決」をお読み下さい。。

最近の Windows は、IPv4 と IPv6 の 2つのIPアドレスがあるので、HTTP.sys80番ポートを IPv6 のアドレスにバインド、その他の80番ポートを使うアプリ(Apache)の80番ポートを、IPv4のアドレスに割り当てる。localhost のようなアドレス指定をした場合は、IPv6 のアドレスに流すように hosts を定義し、それ以外の local のような特殊な文字列を定義して、local でアドレス指定をした場合は、IPv4 のアドレスに流れるように hosts を定義する。Apache を使いたい場合は、http://local  のようなアドレス指定をする。

ただし、これでももし HTTP.sys の仕組みを使うアプリケーションが、IPv4 のアドレスべた書きで、http://127.0.0.1/xxx のようなアクセスをするように書かれていたら、IPv4 のアドレスで LISTEN しているのは Apache ですのでリクエストは失敗します。(理解正しいかな・・・)この方法は、以下のリンク先で挑戦しています。

Stop http.sys from listening on port 80 in Windows

Apache の httpd.conf を開き

「Listen 80」を「Listen 8080」に変更します。
「ServerName localhost:80」を「ServerName localhost:8080」に変更します。

#
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 0.0.0.0:80
#Listen [::]:80
Listen 8080

# Default charset UTF8
# AddDefaultCharset utf-8

<省略>

#
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If your host doesn’t have a registered DNS name, enter its IP address here.
#
ServerName localhost:8080

すごく簡単でした。が、Apache と一緒にWordPress を使おうとしたのですが、 WordPress は、80や443以外のポートが使われている場合は、現時点では、うまく動作しないという制約があるようです。
WordPress を動かすのが最終目的だったので、この方法は個人的には諦めました。

image

ネットワークの作成 – WordPress Codex 日本語版」より

結局、最終的に意外な方法で解決

何気なく、Apache を手動で起動では無く、Windows のサービスに登録して起動するようにしたのですが、その状態で Windows を再起動するとあーら不思議。何も変更していないのに、Apache が80番ポートで起動してくるようになりました。何故?

理由がよくわからないですが、とりあえずWindows のサービスとして Apache を動かすと大丈夫のようなので、これで解決としてます。Windowsが何か制御をしているのでしょうか・・・・

image
Apache は、単体で導入しているのでは無く、XAMPPの一部として導入されているのですが、Windows 8 (64bit) と XAMP v3.1.0.3.1.0 とは相性が悪いのか、Windows サービスとして登録したモジュールは、XAMPPのコントロールパネルから操作ができない?ようです。

具体的には、Apache を止めようと「Stop」ボタンを押すと・・・・
image

のように XAMPPのコントロールパネルがクラッシュします。
Windows が 80番ポートをコントロールしているので、80番を使用するサービスのコントロールは Windows OS に任せなさい。という仕様なのかもしれません。

サービスを止めたい場合は、Windows のサービスから操作すれば良く、大きな問題は無いので、とりあえず良しとします・・・・