locked
IIS5.0で構築されたWebサイトのHTTP キープアライブを無効にするにはどうすればよいのでしょうか? RRS feed

  • 質問

  • IIS5.0で構築されたWebサイトをセキュリティ関連の理由にてHTTP キープアライブを無効にしたいのですが、

    Microsoftのサイトに以下のような記述があり

    http://www.microsoft.com/windows/windows2000/ja/server/iis/htm/core/iitmout.htm

    1. インターネット インフォメーション サービス スナップインで、 Web サイトを選択し、そのプロパティ シートを開きます。
    2. [Web サイト] プロパティ シートの [HTTP キープアライブを有効にする] チェック ボックスをオフにします。

    を実行してマシンを再起動してみましたが、パケットキャプチャーで採取したパケットをみると

    Header : Connection: Keep-Alive \r\n

    となっていました。

    何かの不具合などで、このようなことになっているのでしょうか?

    また、「HTTP キープアライブを無効」にする方法があれば教えて下さい。

    • 移動 Wang Huang 2012年10月2日 1:45 (移動元:Internet Information Services 5.x, 6.0 - 全般)
    2007年10月31日 6:30

回答

  •  Matsubara Satoshi さんからの引用

    サーバーからクライアントへの応答がConnection: Keep-Aliveを送っています。

    クライアントは

        Request : GET /****/ HTTP/1.0\r\n
        Header : Accept: */*\r\n
        Header : Accept-Encoding: gzip, deflate\r\n
        Header : Accept-Language: ja\r\n
        Header : Connection: close\r\n
    のようにHTTP/1.0でConnection: closeでRequestをしているのですが、

     

    HTTP/1.0だったのですね。

    なら全然話が違いますね。

     

    とりあえず、クライアントが変です。

    HTTP/1.0にはConnection: closeヘッダーはありません。

    Connection: closeを使わずに、接続を閉じる必要があります。

    接続はきちんと閉じられていますか?

     

    サーバからの応答が、

      Hypertext Transfer Protocol
        Response : HTTP/1.1 200 OK\r\n
        Header : Server: Microsoft-IIS/5.0\r\n
        Header : Date: Tue, 30 Oct 2007 02:34:36 GMT\r\n
        Header : X-Powered-By: ASP.NET\r\n
        Header : Connection: Keep-Alive\r\n
        Header : Content-Length: 1473\r\n
        Header : Content-Type: text/html\r\n
        Header : Set-Cookie: ASPSESSIONIDASDQSDBS=CHBBMLEDCBDPINGCGJLGGDFK; path=/\r\n
        Header : Cache-control: private\r\n
    のようにKeep-Aliveで返しています。

     

    HTTP/1.1とHTTP/1.0では、プロキシとの接続などの関係で、

    Connection: Keep-Aliveの意味もKeep-Aliveヘッダーの意味も異なります。

     

    説明がめんどくさいので詳細は述べませんが、

    HTTP/1.0ではConnection: Keep-Aliveは持続的接続を意味し、

    一方HTTP/1.1ではConnectionヘッダー中のKeep-Aliveトークンの意味は定義されておらず、

    Connection: Keep-Aliveの意味はKeep-Aliveヘッダーを転送しない、という意味になります。

     

    HTTP/1.0にしろ1.1にしろ、

    クライアントが切断してしまえば接続は持続的になりませんし、

    HTTP/1.0なら明示的に持続的接続を要求しなければ常に切断します。

     

    今回は、クライアントがConnection: Keep-Aliveを送っていません。

    これはクライアントが持続的接続を用いないことを意味するため、

    クライアントはHTTP/1.0の既定の振舞い=切断をするべきです。

    リクエスト受信後、サーバーはクライアントが切断するつもりであると思っているはずです。

    サーバーはConnection: Keep-Aliveを返していますが、HTTP/1.1ではこれは持続的接続を意味しません。

    サーバーは応答を返した後、切断しているはずです。

    一方、クライアントは、サーバーからConnection: Keep-Aliveを受信しますが、

    Connection: Keep-Aliveを送らずにリクエストしていて、

    既に切断しているか、切断することが決まっています。

    サーバーから切断されていなかったとしても、追加でリクエストを送ってはいけません。

     

    このように、サーバーとクライアントの振舞いにはなにも問題ありません。

    これでは持続的接続が無効になっているのかどうかの確認もできていません。

     

    HTTP/1.0でConnection: Keep-Aliveして要求を送ってみたり、

    HTTP/1.1で普通に接続してみて接続がきちんと切れるか

    調べて確認したらいいと思います。

     

    >HTTP/1.1サーバーがConnection: Keep-Aliveを返すのは

    >Connection: Keep-Aliveを送ってきたHTTP/1.0クライアントだけのはずなんですが。

     

    そう思ってたんですが、間違いでした。

    HTTP/1.1のサーバーがConnection: Keep-Aliveを

    HTTP/1.1のクライアントやConnection: Keep-Aliveをリクエストしていないクライアントに返すのは

    動作上何の問題もないようです。

    意味上不親切ですし、無駄なので、送らないほうがいいとは思いますが。

    2007年11月5日 14:33

すべての返信

  •  Matsubara Satoshi さんからの引用

    IIS5.0で構築されたWebサイトをセキュリティ関連の理由にてHTTP キープアライブを無効にしたいのですが、

    ...

    を実行してマシンを再起動してみましたが、パケットキャプチャーで採取したパケットをみると

    Header : Connection: Keep-Alive \r\n

    となっていました。

     

    サーバーからクライアントへのパケットなのか、

    クライアントからサーバーへのパケットなのかがわかりません。

     

    クライアントからサーバーでしたら、

    Connection: Keep-Aliveが送られるのは普通です。

     

    サーバーの応答なのでしたら変ですね。

     

    HTTP/1.1サーバーがConnection: Keep-Aliveを返すのは

    Connection: Keep-Aliveを送ってきたHTTP/1.0クライアントだけのはずなんですが。

    2007年11月1日 13:19
  • サーバーからクライアントへの応答がConnection: Keep-Aliveを送っています。

    クライアントは

        Request : GET /****/ HTTP/1.0\r\n
        Header : Accept: */*\r\n
        Header : Accept-Encoding: gzip, deflate\r\n
        Header : Accept-Language: ja\r\n
        Header : Connection: close\r\n
    のようにHTTP/1.0でConnection: closeでRequestをしているのですが、

    サーバからの応答が、

      Hypertext Transfer Protocol
        Response : HTTP/1.1 200 OK\r\n
        Header : Server: Microsoft-IIS/5.0\r\n
        Header : Date: Tue, 30 Oct 2007 02:34:36 GMT\r\n
        Header : X-Powered-By: ASP.NET\r\n
        Header : Connection: Keep-Alive\r\n
        Header : Content-Length: 1473\r\n
        Header : Content-Type: text/html\r\n
        Header : Set-Cookie: ASPSESSIONIDASDQSDBS=CHBBMLEDCBDPINGCGJLGGDFK; path=/\r\n
        Header : Cache-control: private\r\n
    のようにKeep-Aliveで返しています。

    設定は

    [Web サイト] プロパティ シートの [HTTP キープアライブを有効にする] チェック ボックスをオフにしているのですが・・・

     

    以上

     

    2007年11月5日 1:54
  •  Matsubara Satoshi さんからの引用

    サーバーからクライアントへの応答がConnection: Keep-Aliveを送っています。

    クライアントは

        Request : GET /****/ HTTP/1.0\r\n
        Header : Accept: */*\r\n
        Header : Accept-Encoding: gzip, deflate\r\n
        Header : Accept-Language: ja\r\n
        Header : Connection: close\r\n
    のようにHTTP/1.0でConnection: closeでRequestをしているのですが、

     

    HTTP/1.0だったのですね。

    なら全然話が違いますね。

     

    とりあえず、クライアントが変です。

    HTTP/1.0にはConnection: closeヘッダーはありません。

    Connection: closeを使わずに、接続を閉じる必要があります。

    接続はきちんと閉じられていますか?

     

    サーバからの応答が、

      Hypertext Transfer Protocol
        Response : HTTP/1.1 200 OK\r\n
        Header : Server: Microsoft-IIS/5.0\r\n
        Header : Date: Tue, 30 Oct 2007 02:34:36 GMT\r\n
        Header : X-Powered-By: ASP.NET\r\n
        Header : Connection: Keep-Alive\r\n
        Header : Content-Length: 1473\r\n
        Header : Content-Type: text/html\r\n
        Header : Set-Cookie: ASPSESSIONIDASDQSDBS=CHBBMLEDCBDPINGCGJLGGDFK; path=/\r\n
        Header : Cache-control: private\r\n
    のようにKeep-Aliveで返しています。

     

    HTTP/1.1とHTTP/1.0では、プロキシとの接続などの関係で、

    Connection: Keep-Aliveの意味もKeep-Aliveヘッダーの意味も異なります。

     

    説明がめんどくさいので詳細は述べませんが、

    HTTP/1.0ではConnection: Keep-Aliveは持続的接続を意味し、

    一方HTTP/1.1ではConnectionヘッダー中のKeep-Aliveトークンの意味は定義されておらず、

    Connection: Keep-Aliveの意味はKeep-Aliveヘッダーを転送しない、という意味になります。

     

    HTTP/1.0にしろ1.1にしろ、

    クライアントが切断してしまえば接続は持続的になりませんし、

    HTTP/1.0なら明示的に持続的接続を要求しなければ常に切断します。

     

    今回は、クライアントがConnection: Keep-Aliveを送っていません。

    これはクライアントが持続的接続を用いないことを意味するため、

    クライアントはHTTP/1.0の既定の振舞い=切断をするべきです。

    リクエスト受信後、サーバーはクライアントが切断するつもりであると思っているはずです。

    サーバーはConnection: Keep-Aliveを返していますが、HTTP/1.1ではこれは持続的接続を意味しません。

    サーバーは応答を返した後、切断しているはずです。

    一方、クライアントは、サーバーからConnection: Keep-Aliveを受信しますが、

    Connection: Keep-Aliveを送らずにリクエストしていて、

    既に切断しているか、切断することが決まっています。

    サーバーから切断されていなかったとしても、追加でリクエストを送ってはいけません。

     

    このように、サーバーとクライアントの振舞いにはなにも問題ありません。

    これでは持続的接続が無効になっているのかどうかの確認もできていません。

     

    HTTP/1.0でConnection: Keep-Aliveして要求を送ってみたり、

    HTTP/1.1で普通に接続してみて接続がきちんと切れるか

    調べて確認したらいいと思います。

     

    >HTTP/1.1サーバーがConnection: Keep-Aliveを返すのは

    >Connection: Keep-Aliveを送ってきたHTTP/1.0クライアントだけのはずなんですが。

     

    そう思ってたんですが、間違いでした。

    HTTP/1.1のサーバーがConnection: Keep-Aliveを

    HTTP/1.1のクライアントやConnection: Keep-Aliveをリクエストしていないクライアントに返すのは

    動作上何の問題もないようです。

    意味上不親切ですし、無駄なので、送らないほうがいいとは思いますが。

    2007年11月5日 14:33
  • 有用な回答をありがとうございます。説明が足りていなくて申し訳ありませんでした。今回の接続ではServer←→Clientの間にセキュリティ関係のリバースプロキシがからんでいます。

    Clientからの送信パケットは、

      Hypertext Transfer Protocol
        Request : GET /sso1/dfw/BP_***/***/ HTTP/1.1\r\n
        Header : Accept: */*\r\n
        Header : Referer: http://********.co.jp/sso1/dfw/SSOCTRL/rp/menu\r\n
        Header : Accept-Language: ja\r\n
        Header : Accept-Encoding: gzip, deflate\r\n
        Header : User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\r\n
        Header : Host: ******.co.jp\r\n
        Header : Connection: Keep-Alive\r\n
        Header : Cookie: ASPSESSIONIDASDQTCBT=MLCPHJEDNIIKKIEBHKCHLIGG; IW_INFO=diei1mlaw5ea9xb26A6xt2Z4TeSRE7T0\r\n

    のようにHTTP1.1で送出されています。また、Connection: Keep-Aliveとサーバに送っています。

    これが、リバースプロキシ経由でサーバに到着すると

      Hypertext Transfer Protocol
        Request : GET /***/ HTTP/1.0\r\n
        Header : Accept: */*\r\n
        Header : Accept-Encoding: gzip, deflate\r\n
        Header : Accept-Language: ja\r\n
        Header : Connection: close\r\n
        Header : Host: *.*.*.*\r\n
        Header : Referer: http://********.co.jp/rp/menu\r\n
        Header : Sso-Auth-Class: 0\r\n
        Header : Sso-Location: 0\r\n
        Header : Sso-Org-Class: 0\r\n
        Header : User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\r\n

    のようにHTTP1.0となりConnection: close\と送られてきます。

    次にサーバ側では、このRequestに対するResponseを以下のように返しています。

      Hypertext Transfer Protocol
        Response : HTTP/1.1 200 OK\r\n
        Header : Server: Microsoft-IIS/5.0\r\n
        Header : Date: Tue, 30 Oct 2007 02:34:36 GMT\r\n
        Header : X-Powered-By: ASP.NET\r\n
        Header : Connection: Keep-Alive\r\n
        Header : Content-Length: 1473\r\n
        Header : Content-Type: text/html\r\n
        Header : Set-Cookie: ASPSESSIONIDASDQSDBS=CHBBMLEDCBDPINGCGJLGGDFK; path=/\r\n
        Header : Cache-control: private\r\n

    このResponseに対して、リバースプロキシは接続を常にcloseとするセキュリティ上の理由により以下のように書き換えてClientに送ります。

      Hypertext Transfer Protocol
        Response : HTTP/1.1 200 OK\r\n
        Header : Date: Tue, 30 Oct 2007 02:25:15 GMT\r\n
        Header : Server: Apache\r\n
        Header : Cache-control: private\r\n
        Header : Connection: Keep-Alive, close\r\n
        Header : X-Powered-By: ASP.NET\r\n

    このように、Connection: Keep-Alive, close\r\n となりClient側のプログラムがConnectionに対する判断が出来なくなって

    います。

     

    回避手段の1つとして、サーバ側(IIS5.0)のほうで、Connection: close で送出できないかとのことでした。

    もし、IIS5.0のほうで、Connection: close で送出できれば、リバースプロキシの方でCloseを付加しても

    Connection: close, close\r\n となりClient側のプログラムがConnectionに対する判断はcloseと判断できるとのことでした。

    もちろん、このConnection: close, close\r\nもおかしいことは重々わかっているのですが、

    リバースプロキシ(Apache)側の設定が、変えられないとの前提で、今回の質問となっています。

    非常に無理な、質問に対して、丁寧な回答をありがとうございます。

     

     

     

     

     

     

    2007年11月6日 4:39
  •  Matsubara Satoshi さんからの引用

    有用な回答をありがとうございます。説明が足りていなくて申し訳ありませんでした。今回の接続ではServer←→Clientの間にセキュリティ関係のリバースプロキシがからんでいます。

     

    なにー

    それじゃ全然話が違いますね。

     

    最初から、どういう状況で何がしたいのか、どこまで調べて何が問題なのか、

    きちんと言ったほうが問題も早く解決すると思いますよ。

     

    このように、Connection: Keep-Alive, close\r\n となりClient側のプログラムがConnectionに対する判断が出来なくなって

    います。

     

    なんか勘違いしているようですね。

     

    クライアントはConnection: Closeを送ってます。

    これは持続的接続を用いないという宣言です。

    サーバーが何を送ろうと、この接続では持続的接続は用いられません。

    クライアント側プログラムは接続が切れると考えて問題ありませんし、

    送信側も切っているはずです。

     

    順番に説明すると、

    サーバーは、Connection: Closeを受け取ります。

    ですので、必要なデータを送った後、送信側の接続を切っているはずです。

    サーバーの送信側が切れるということは、

    プロキシのサーバーからの受信側が切れます。

    受信側が切れたので、プロキシはクライアントへの送信側を切ります。

    で、クライアントの受信側が切れます。

     

    なにも問題ないですね。

     

    回避手段の1つとして、サーバ側(IIS5.0)のほうで、Connection: close で送出できないかとのことでした。

    もし、IIS5.0のほうで、Connection: close で送出できれば、リバースプロキシの方でCloseを付加しても

    Connection: close, close\r\n となりClient側のプログラムがConnectionに対する判断はcloseと判断できるとのことでした。

    もちろん、このConnection: close, close\r\nもおかしいことは重々わかっているのですが、

     

    「とのこと」とは、何でしょうか?

    誰かと話をしてるのですか?

    MSのサポートとかですか?

     

    誰かに話をしてるのでしたら、その人に詳しく聞くべきでしょう。

    何が問題で何をしたいのか分かりませんし。

    2007年11月6日 14:54
  • 回答をありがとうございます。

     

    「何が問題で何をしたいのか分かりませんし。」

    とのことですが、

     

    何をしたいか?ですが、IIS5.0で構築されたWebサイトのHTTP キープアライブを無効にする方法をしらべたいのです。

    IIS5.0の[Web サイト] プロパティ シートの [HTTP キープアライブを有効にする] チェック ボックスをオフにしても

    パケットキャプチャーを取得すると、Connection:Keep-Alive でサーバよりResponseを返しています。

     

    何が問題になっているか?ですが、

    中継装置(リーバオスプロキシ)の方で、常にConnection:Closeを付加してサーバからの通信をクライアントに中継しています。

    TCP上の通信はFINが送出されているので、終了しますが、

    クライアントのプログラムはHTTPヘッダのみしか参照できないので、Connection: Keep-Alive, close を受信してしまうと

    Connection:Keep-Aliveと判断してしまい、現在のポートで、要求を待ち続けてしまうことが、問題となっています。

    もちろん、TCP上でポートが閉じられているので、そのポートでの通信がこないことは、理解していますが、

    クライアントのプログラムがパッケージソフトなため、修正は出来ないとのことで、製作元からは、

    せめて、Connection: close、close でクライアント側に送出してほしいとのことでした。

    このクライアントプログラムがTCP上のFINを感知して、Connection:とは無関係に次の通信は別のポートで送受信するように

    なっていれば、よかったのでがそうでないために、

    IIS5.0側でTCPのキープアライブを無効にすることにしました。

     

    2007年11月9日 5:31
  • あいかわらず情報が小出しですね。

    最初から自分の考えた論理プロセスを省略無く全部書いたほうが早く解決するんですが。

     

    何をしたいか?ですが、IIS5.0で構築されたWebサイトのHTTP キープアライブを無効にする方法をしらべたいのです。

    IIS5.0の[Web サイト] プロパティ シートの [HTTP キープアライブを有効にする] チェック ボックスをオフにしても

    パケットキャプチャーを取得すると、Connection:Keep-Alive でサーバよりResponseを返しています。

    何回も言っていますが、

    Connection:Keep-Aliveは持続的接続を使うという意味ではありません。

    Connection:Keep-Aliveがあるからといって持続的接続であるということにはなりません

    また、前に説明しているように、書かれた内容には

    HTTP キープアライブが無効になっていないという証拠が一つもありません。

     

    TCP上の通信はFINが送出されているので、終了しますが、

    とあるので、たぶん、HTTP キープアライブはきちんと無効になっています

     

    このクライアントプログラムがTCP上のFINを感知して、Connection:とは無関係に次の通信は別のポートで送受信するように

    なっていれば、よかったのでがそうでないために、

    TCP接続が切れた時点でHTTP通信は終了であるというのは、

    HTTP1.0以前から一貫して守られている仕様であり、

    接続終了時の処理はTCPをつかったサーバークライアントシステムの基本です。

    サーバーが異常終了したり、経路が切れたりしたらクライアントも死んでしまうのでは、全く使えません。

     

    ですので、

    IIS5.0側でTCPのキープアライブを無効にすることにしました。

    この対応は全く意味がありません。

     

    いままでの投稿から判明している内容から類推すると、対応策はお勧め順に以下の通りですね。

     

    1

    まともなTCP通信のできないクライアントを捨てる。

    TCPが切れても待っているクライアントは正直全く使えません。

    何らかの事情でLAN/WANが死んだときに、エラーも出さずに止まるのでは話になりません。

    違うパッケージソフトを使うか、改良を依頼するか、です。

     

    2

    他の手法でTCP接続の切断を検知し、クライアントソフトを殺す。

    プロキシとかファイヤーウォールでTCP接続を監視できます。

     

    3

    クライアントにプロキシを立ててConnection: Closeを入れさせる。

    クライアントごとに専用のプロキシソフトを入れて、

    Connection: Closeを入れさせれば問題は一応解決します。

    他の通信に影響を与えないようにプロキシを入れられるか、

    パッケージソフトの仕様を確認する必要があります。

     

    4

    リバースプロキシにConnectionヘッダー改造させて、Closeだけ送るようにする。

    これだとネットが切れたときにクライアントが停止します。

     

    5

    サーバーにプロキシを入れて、Connection: Closeを入れさせる。

    これも同じ。ネットが切れたときにクライアントが停止します。

     

    そんなところですね。

    1以外の対応は手間がかかるうえ問題が多く、私でしたらやりません。

    TCP接続が切れても待ち続けるようなクライアントは、ダメと判断されても仕方ないと思います。

    他の部分の作りもまともでない可能性が高いですね。

     

    2007年11月9日 6:57
  • 色々な助言をありがとうございました。

     

    IIS5.0の[Web サイト] プロパティ シートの [HTTP キープアライブを有効にする] チェック ボックスをオフにしても

    パケットキャプチャーを取得すると、Connection:Keep-Alive でサーバよりResponseを返しています。

     

    クライアントにFINを返しているのは、中継装置(リバースプロキシ)が返しています。

    サーバのIISでは、ASPSESSIONを保持し続けています。

    従って、サーバにIIS5.0では、ASPSESSIONのTIMEOUTまで、セッションを保持していますが、

    今回はそのことでの問題は発生していません。

    プロパティでHTTP キープアライブを無効にしても、IIS5.0のサイトからは、TCPのFINは発行されていませんでした。

     

    今回の解決方法として、IIS5.0のサーバにクライアントプロキシを同居させ、そのクライアントプロキシで、

    HTTPヘッダの書換えを行うことにしました。

     

    但し、IIS5.0での上記「[Web サイト] プロパティ シートの [HTTP キープアライブを有効にする] チェック ボックス」の意味合いについては、以前としてわかりませんでした。

     

     

     

    2007年11月12日 6:49
  •  Matsubara Satoshi さんからの引用

    IIS5.0の[Web サイト] プロパティ シートの [HTTP キープアライブを有効にする] チェック ボックスをオフにしても

    パケットキャプチャーを取得すると、Connection:Keep-Alive でサーバよりResponseを返しています。

     

    もう何回も言ってるのですが、通じてないようですね。

    「HTTP キープアライブを有効にする」は持続的接続を使うという意味です。

    一方、HTTP/1.1におけるConnection:Keep-Aliveは持続的接続を使うという意味ではありません。

     

    サーバのIISでは、ASPSESSIONを保持し続けています。

    従って、サーバにIIS5.0では、ASPSESSIONのTIMEOUTまで、セッションを保持していますが、

    今回はそのことでの問題は発生していません。

     

    SessionとConnectionは全く別の概念です。

    関係ありません。

     

    プロパティでHTTP キープアライブを無効にしても、IIS5.0のサイトからは、TCPのFINは発行されていませんでした。

     

    んーと、これが変ですね。

    リバースプロキシが送信側の接続をきっていないので、

    IISの受信側の接続が切れておらず、そのために切れないのだと思います。

    リバースプロキシはHTTP/1.0を送信していますし、

    HTTP/1.1であってもConnection:Closeを送っているので、

    サーバーへの送信が終わったら接続を切らねばいけません。

     

    但し、IIS5.0での上記「[Web サイト] プロパティ シートの [HTTP キープアライブを有効にする] チェック ボックス」の意味合いについては、以前としてわかりませんでした。

     

    何回も説明してる通り、「持続的接続を使う」という意味です。

    これが動かないという話は今のところ聞いたことはありません。

    2007年11月12日 11:00
  •  

    こんにちは、鈴木裕子です。

     

    れい さん、大変詳細なアドバイスを投稿していただき、ありがとうございました!

     

    Matsubara Satoshi さん、

    その後、いかがでしょうか。

    ご希望の環境は構築できましたか?

    れい さんのアドバイスが、かなり参考になったようでしたので、回答済みチェックをつけさせていただきました。

    Matsubara さんは、チェックを外すこともできます。必要があった場合は、確認してくださいね。

     

    また何かありましたらぜひ投稿してください。

    お待ちしております。
    2007年12月21日 8:34
    モデレータ