こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

httpd.confに関して

apacheのhttpd.confに関して質問させていただきます。

ErrorDocumentで、自作したカスタムのエラーページを
表示できると思うのですが、
・ErrorDocument エラーコード "文字列"
は文字列がちゃんと表示されますが、
・ErrorDocument エラーコード /~/~/~.html
の場合は、デフォルトのエラーページが表示されてしまいます。

VirtualHosat内でも同じ動きです。

なぜデフォルトが出てしまうのかご意見よろしくお願いいたします。

投稿日時 - 2009-09-17 18:17:38

QNo.5298075

困ってます

このQ&Aは役に立ちましたか?

18人が「このQ&Aが役に立った」と投票しています

回答(12)

ANo.12

>(1)URLのドメインのあとのどこかに%をつけて叩く
>がカスタムエラーページを表示できるので、
>カスタムのエラーページが表示されていいと思うのですが。
%の件は、相対パスの一部がフォーマットエラーだから、
Host:は信頼してもいいけど、
POSTのBodyをheaderに結合すると、リクエストヘッダ自体が長くなりすぎて、リクエスト全体が信頼できないと判断しているようですね

今回の件はバッファオーバーフロー攻撃と判断されてもおかしくない状態なので、
クラッカーに対して真面目にErrorDocumentを返すと、余計な情報を提供してしまうので、読み込まれないのではないでしょうか?
基本的に、BadRequestは、リクエストが不正な攻撃のケースもあるので、
セキュリティの都合上、任意のカスタム400ファイルを返せないケースもありうると思いますよ

投稿日時 - 2009-09-29 09:25:55

お礼

お礼が大変遅くなりまして、申し訳ございませんでした。

今まで多くのご回答ありがとうございました。

ヘッダとbodyの間にの改行を除いてリクエストされたときに
カスタムの400ページを出力できる方法を
引き続き探ってみたいと思います。

ありがとうございました。

投稿日時 - 2009-10-07 10:54:46

ANo.11

>VirtualHost外のErrorDocument(つまりVirtualHostを設定していないところ)で拾えないのでしょうか。

これは、apacheのVirtualホストの説明を見ると解りますが、
VirtualHostを使用したら、全ての設定はいずれかのVirtualHostに属さなければなりません
よって、いずれのVirtualホストにも該当しないリクエストは
『最初に記述されたVirtualホストをデフォルトホストとして処理されます 』※1
つまり、デフォルトの設定を行いたいのであれば、最初に記述したVirtualHostに記述してください

>また、VirtualHostが決定できないとのことですが、
>私はドメインごとにエラーログを吐く様にしてありまして
>Hostを消しても、
>GET /index.html HTTP/1.1 のアクセスで
>アクセスしたいドメインのアクセスログは吐かれております。

このエラーログは※1に該当していませんか?
つまり、一番最初に記述されたVirtualHostの設定内にあるエラーログではないでしょうか?

以下、「名前ベースのバーチャルホスト」のmanual抜粋
「リクエストが来ると、サーバはまず最初に <NameVirtualHost> にマッチする IP アドレスかどうかをチェックします。マッチすれば マッチした IP アドレスの <VirtualHost> のそれぞれのセクションの中から ServerName か ServerAlias に要求されたホスト名があるか探します。 見つかればそのサーバ用の設定を使います。マッチするバーチャルホスト が見つからなければ、マッチした IP アドレスの リストの最初にあるバーチャルホスト が使われます。

結果として、リストの最初のバーチャルホストが デフォルト の バーチャルホストになります。IP アドレスが『 NameVirtualHost ディレクティブにマッチした場合は、<<メインのサーバ の DocumentRoot は決して使われません>>』 『どのバーチャルホストにもマッチしないリクエストに対して、 特別な設定をしたいのであれば、設定ファイル中の最初の <VirtualHost> コンテナにそれを記述してください。』」

投稿日時 - 2009-09-28 09:58:56

お礼

>このエラーログは※1に該当していませんか?
>つまり、一番最初に記述されたVirtualHostの設定内にあるエラーログではないでしょうか?

おっしゃる通りです。
一番最初のVirtualHostのログになっております。

>(1)Live HTTP Headersで、Hostを消してリプレイする(HTTP/1.1のとき)
に関してはデフォルトが表示されるのはよく分かりました。

>(2)telnetで、ヘッダとボディの間の改行を省いてリクエストする
に関しては、
>(1)URLのドメインのあとのどこかに%をつけて叩く
がカスタムエラーページを表示できるので、
カスタムのエラーページが表示されていいと思うのですが。
これがおかしいですよね。
Hostはしっかりと送られていますし、
不正構文で400になりますし。

投稿日時 - 2009-09-28 14:10:29

ANo.10

>最終的に決め手が欲しいです。
>証拠というのを証明したいですね

>【デフォルトのエラーページが出る場合】
>(1)Live HTTP Headersで、Hostを消してリプレイする(HTTP/1.1のとき)
理由:
まず、RFC2626「5.2 リクエストによって識別されるリソース(※1)」で
「もし、 Request-URI が absoluteURI でなく、リクエストが Host ヘッダフィールドを含んでいるならば、ホストは Host ヘッダフィールド値によって決定される。」とあります。

このケースだと、
VirtualHost(リソース)を決める要素(Host:)がサーバに送られていないから、リソースが決定できずデフォルトしか出しようがない

証拠:サーバへは下記のheaderでリクエストされているはずで、リソースを決定する情報が一切ありません。よって、デフォルト400ページです
------------------------------------------------
GET /index.html HTTP/1.1 
以下にはHost:を除くヘッダフィールド識別子が続く
------------------------------------------------

たぶんあなたは、
firefoxの上URLには[absoluteURI(絶対URI)]で表示されているので、
------------------------------------------------
GET http://hogehoge.jp/index.html HTTP/1.1 (※2)
以下にはHost:を除くヘッダフィールド識別子が続く
------------------------------------------------
上記のheaderが送信されていると思い込んでいるのではないのでしょうか?

では試しに※2を送信するとカスタム400ページが表示されるのか?ですが、「表示されない」です

しかし※1では、
「もし、 Request-URI が absoluteURI ならば、ホストは Request-URI の一部である。リクエストにおけるどんな Host ヘッダフィールド値も無視されなければならない。」※3
とあるので、Hostヘッダが無くてもリソースを解決できるので、カスタム400ページを出すべきだと私は考えます
よって、「apacheのバグじゃないの?」と思ってます

そして、※3の件から、
------------------------------------------------
GET http://実在のvirtualHost名/index.html HTTP/1.1
host:xyz.xyz ←実在しないホスト名
以下略
------------------------------------------------
のようなヘッダを送信すると、ちゃんとHost:を無視して
[absoluteURI]からリソース(実在のvirtualHost名の部分)を決定します


>(2)telnetで、ヘッダとボディの間の改行を省いてリクエストする
RFC2626でのBadRequestの説明は下記のとおりである
「リクエストは、不正な構文のためサーバに理解されなかった。」※4

このケースでは「ヘッダが構文エラーなので、これに含まれるHost情報はすべて信用することができない。
よって、デフォルトの400ページが表示される」と拡大解釈しました

>【カスタムのエラーページが出る場合】
>(1)URLのドメインのあとのどこかに%をつけて叩く
%の後には16進数でなければならないので、
16進数のフォーマットになっていなければ必然的に※4に該当するため、BadRequestが出ることには問題ないでしょう
当然ホスト名が送られている以上、リソースは解決できるので
カスタム400ページが表示されます
例:
http://hogehoge.jp/%index.html→カスタム400ページが表示される
http://hogehoge.jp/%12index.html→カスタム404ページが表示される

投稿日時 - 2009-09-26 23:45:18

お礼

分かりやすいご回答ありがとうございます。

>(1)Live HTTP Headersで、Hostを消してリプレイする(HTTP/1.1のとき)
HostがないためVirtualHostを解釈できず、デフォルトしか返せない

>(2)telnetで、ヘッダとボディの間の改行を省いてリクエストする
Host情報すべてを信用することができないため、デフォルトを返している

>(1)URLのドメインのあとのどこかに%をつけて叩く
Host名が送られていて、構文エラーのためカスタムが表示できる

と言ったところでしょうか。

質問ばかりで申し訳ないのですが、
最後にもう一つだけお願いいたします。

>(1)Live HTTP Headersで、Hostを消してリプレイする(HTTP/1.1のとき)
のときに、
VirtualHostが決められないならば、
VirtualHost外のErrorDocument(つまりVirtualHostを設定していないところ)で拾えないのでしょうか。

また、VirtualHostが決定できないとのことですが、
私はドメインごとにエラーログを吐く様にしてありまして
Hostを消しても、
GET /index.html HTTP/1.1 のアクセスで
アクセスしたいドメインのアクセスログは吐かれております。
これは、LiveHTTPHeadersが良いように解釈してる感じでしょうかw

投稿日時 - 2009-09-28 08:50:57

ANo.9

>それはどういうことなのかまったく分かりませんね。
改行を省いたので、
POSTのbody部がヘッダの一部とみなされてBadRequestになったと思われます

詳しくはerror_logに記録が残っているかもしれません

投稿日時 - 2009-09-26 00:13:31

お礼

>改行を省いたので、
>POSTのbody部がヘッダの一部とみなされてBadRequestになったと思われます
そういうことですね。

かなり話が見えてきたのですが、
最終的に決め手が欲しいです。

【デフォルトのエラーページが出る場合】
(1)Live HTTP Headersで、Hostを消してリプレイする(HTTP/1.1のとき)
(2)telnetで、ヘッダとボディの間の改行を省いてリクエストする

【カスタムのエラーページが出る場合】
(1)URLのドメインのあとのどこかに%をつけて叩く

どれも400を起こすアクセスなのに、
デフォルトとカスタムのページが出る違いは
(1)なぜで、こういう証拠というのを証明したいですね・・・。
それなら、デフォルトのエラーページが出てしまう方は、
(2)カスタムエラーページに置き換えられないということなのでしょうか。

投稿日時 - 2009-09-26 17:49:34

ANo.8

>「HTTP1.1準拠でHostnameを含む」ヘッダを含む場合の
>再現方法はどうなりますでしょうか。

telnetでポート80をたたく方法が簡単です
コマンドラインや、teraterm、等で「telnet テストサーバ 80」
あるいは、テストサーバ上で「telnet localhost 80」

繋がったら
GET & HTTP/1.1 [Enter1回押す]
Host: hogehoge.jp [Enter2回押す]

注1:teraterm等のターミナルソフトだとサーバからのレスポンスが全て返った瞬間に画面が閉じてしまうのでロギングしたほうがいいです。
パケットをキャプチャしてロギングしても可。
注2:teratermの場合、入力したコマンドが画面上にechoしないので、
サーバからレスポンスが返るまで画面は真っ黒です

HTTP/1.0準拠の場合
GET & HTTP/1.0 [Enter2回押す]

上記の方法でErrorDocumentのHTMLファイルの内容がtext表示されます
ErrorDocumentがhttp://で始まる場合は302が返ります

あと
GET & HTTP/1.1 [Enter2回押す]
だと、Hostnameが無いためデフォルトの400画面のtextが返ります
この件は#7で「RFC2616の14.23に該当するため~」と回答しましたが、
「ErrorDocumentが /hogehoge/hoge.html」
と定義してある場合(http://で始まらない場合)はhoge.htmlを返すべきなのでは?
実はapacheのバグでは?と思う次第です
セキュリティ上なにか都合が悪いことでもあるのでしょうかね。

投稿日時 - 2009-09-24 23:57:38

補足

Hoatを消す以外にも
POSTで送信したときにヘッダ部分とボディの部分に
空白行を入れないでリクエストすると
400のデフォルトのエラーページが表示されてしまいますね・・・。

それはどういうことなのかまったく分かりませんね。

投稿日時 - 2009-09-25 16:38:02

お礼

Dos窓からtelnetと、該当サーバ上で「telnet localhost 80」
をしましたところ

GET & HTTP/1.1 [Enter1回押す]
Host: hogehoge.jp [Enter2回押す]

HTTP/1.0準拠の場合
GET & HTTP/1.0 [Enter2回押す]

で400カスタムエラーページが、

GET & HTTP/1.1 [Enter2回押す]
でデフォルトのエラーページが返ってきました。


なんだか変な気分ですw
GET & HTTP/1.1 で400返すんであれば
拾ってくれればいいのにと思いますが・・・

文字列以外のhttp://~やパスだと302のリダイレクトになってしまうから
無視されてデフォルトが表示されてしまうということなんですね。

それならURLに%を付けて200が返ってきて
400のカスタムエラーページが表示されるのが
イマイチよくわかりませんが・・・w

長々とご回答いただきまして、ありがとうございました。

投稿日時 - 2009-09-25 10:05:26

ANo.7

>(1)Host(1行目)を消してリクエスト
>確かに、GET /~ HTTP/1.1 となっていました。

このテスト方法では、
apacheは、RFC2616の14.23に該当するため、「ステータスコード:400のHTMLファイルへのURI」をリダイレクト(ステータス:302)せず、直接ステータスコード400を返さざるを得ない状況でした
よって、ErrorDocumentが文字列ならば「リダイレクトしない」で「直接ステータスコード400を返す」ので、「ErrorDocumentで指定した文字列」を返すことが出来たのです

また、version 2.2.11のapacheのソースコードでは、
server/protcol.c Line:988

r->status = HTTP_BAD_REQUEST;
とした後、
同ファイル Line:1005
にて
ap_send_error_response(r, 0);
関数を呼び出して、「直接ステータスコード400の送信レスポンスデータを作成」していますので、
「ErrorDocumentにHTMLファイルパスを指定していても無視」されます

上記のことから、
「ErrorDocument 400」に対してHTMLファイルを表示させたいのであれば、
「「HTTP1.0準拠」もしくは「HTTP1.1準拠でHostnameを含む」ヘッダを送信してテストしてください」
となります

参考URL:http://www.studyinghttp.net/cgi-bin/rfc.cgi?2616#Sec14.23

投稿日時 - 2009-09-24 19:57:06

お礼

詳しいご説明まことにありがとうございます。

>上記のことから、
>「ErrorDocument 400」に対してHTMLファイルを表示させたいのであれば、
>「「HTTP1.0準拠」もしくは「HTTP1.1準拠でHostnameを含む」ヘッダを送信してテストしてください」
>となります

「HTTP1.1準拠でHostnameを含む」ヘッダを含む場合の
再現方法はどうなりますでしょうか。
下記にも書かせていただきましたが
%をつけると400のカスタムページが表示されるので
それが再現方法になるということでしょうか。
(ただし、Live HTTP Headersを見ると200となっていますが)

投稿日時 - 2009-09-24 20:15:45

ANo.6

まず、「400以外のコード」は「あなたが指定したHTMLが正常に表示」されるのですね???

問題なのは、ステータスコード400に対する「あなたが指定したHTML」が
「直接URLで指定すると表示できる」けど、
「実際にエラーコード400を発生させて表示させようとする」と、
「デフォルトの400が表示される」または「あなたが指定した文字列が表示される」のですね?

>デフォルトが表示されてしまいます。
ここでのデフォルトとは「ステータスコード400(Bad Request)」のデフォルト画面が表示されるのですね??
決して、404(Not Found)の画面ではありませんね???

さらに確認ですが、
400のエラーはどのように発生させてテストされているのでしょうか?
HTTP1.1準拠のHTTPヘッダを送信していませんか?

HTTP1.0準拠のGETメソッド等をテストで使用しているならば、HTTPヘッダにHostnameを含まなくても、「あなたがErrorDocumentで指定した400のHTMLが表示される」ますが、
HTTP1.1準拠のGETメソッド等をテストで使用しているならば、HTTPヘッダにHostnameが含まれないと「あなたがErrorDocumentで指定した400のHTMLは表示されない」です

あなたのエラー400のHTMLを表示させたいのであれば、
「HTTP1.0準拠」もしくは「HTTP1.1準拠でHostnameを含む」ヘッダを送信してテストしてみてください

投稿日時 - 2009-09-24 14:05:40

お礼

>まず、「400以外のコード」は「あなたが指定したHTMLが正常に表示」されるのですね???
すべてではないですが、表示されます。

>「実際にエラーコード400を発生させて表示させようとする」と、
「デフォルトの400が表示される」または「あなたが指定した文字列が表示される」のですね?
その通りです。

>ここでのデフォルトとは「ステータスコード400(Bad Request)」のデフォルト画面が表示されるのですね??
決して、404(Not Found)の画面ではありませんね???
はい、Bad Requestです。

>400のエラーはどのように発生させてテストされているのでしょうか?
FireFoxのアドオンのLive HTTP Headersでリプレイしています。
(1)Host(1行目)を消してリクエスト
(2)JSESSIONIDを果てしなく長い値でリクエスト
しています。

>あなたのエラー400のHTMLを表示させたいのであれば、
「HTTP1.0準拠」もしくは「HTTP1.1準拠でHostnameを含む」ヘッダを送信してテストしてみてください
確かに、GET /~ HTTP/1.1 となっていました。

再現方法がおかしいのかもしれませんね・・・。
ドメインの後に%を指定をしましたら、400が効きました。

投稿日時 - 2009-09-24 16:12:14

ANo.5

>これは、どういったことでしょうか?
たとえば、エラーファイルは
/var/www/htdocs/errors/403.html
等になっているのかどうかをお聞きしたかったのですが、

>DocumentRoot /usr/local/A/B
>ErrorDocument エラーコード /C/error.html
>error.htmlの置いてある場所は
>/usr/local/A/B/C/error.html
とのことですので、
気にしないでください

あと、
>(3)http://ドメイン/~/~/~.html
>の3つを設定しましたが、表示されませんでした。
>ちなみに(3)は直接ブラウザで叩くと表示されます。
>これは一番の謎なんですw
の件ですが、
やはり動きがおかしいですね
ErrorDocumentにhttp://から記述すると
apacheはまず、ブラウザにHTTPコード301(リダイレクト)で(3)のURLを通知し、
ブラウザは、(3)のURLへ再接続するのですが、
これはURLを直接入力して接続することと同じことですので、
直接入力が成功する以上、リダイレクトさえ正しくブラウザに返ってきていれば必ず成功するはずです
でも、成功していないとなると、
virtualHostディレクティブ自体が機能していないと思います

じゃあ、どこが間違っているのかとなりますと、
現状では伏字の部分的な抜粋のみしか拝見しておりませんので、
具体的にはお答えできないです

なので、まず最初にお聞きしたいことは、
virtualHost自体機能しているのか?ということになります
virtualHostのdocumentRoot直下のindex.html等は正しくブラウザでご覧になれますでしょうか?

投稿日時 - 2009-09-21 13:39:21

お礼

>なので、まず最初にお聞きしたいことは、
>virtualHost自体機能しているのか?ということになります
>virtualHostのdocumentRoot直下のindex.html等は正しくブラウザでご覧になれますでしょうか?

VirtualHost自体は機能しております。
DocumentRoot直下のindex.htmlもブラウザで確認できます。

やはりErrorDocumentが正しく動作してくれません。
遅くなりましたが、ステータスコードで言いますと400です。
その他の404などは動作いたします。
400だけ、文字列は表示できますが、
カスタムエラーページへのパスを指定すると
デフォルトが表示されてしまいます。

投稿日時 - 2009-09-24 09:53:18

ANo.4

>vartualHost:443がよくわからないのですが。
HTTPSの要求に対しての処理を記述するディレクティブのことです
こちらに記述してありながら、
テストはHTTPで行っているのではと考えた次第です
大丈夫だとは思いますが。

もしかしてvirtualHostがうまく機能していないのかな?
例えば
http://ドメイン/index.html
等の普通のhtmlは問題なく見れていますでしょうか?

次に、errorDocumentはvirtualHostのdocumentRootの外においてありますでしょうか?

次に、
>(3)http://ドメイン/~/~/~.html

http://ホストのIPアドレス/~/~/~.html
に変更してvirtualHost経由で存在しないHTMLを呼び出した場合
errorDocumentは表示されないでしょうか?

あと、ありえないと思いますが、
ご使用のブラウザが、HTTPヘッダのHost識別子を送信していないとか・・・

投稿日時 - 2009-09-19 08:54:18

お礼

まだ未確認で恐縮ですが、
確認させてください。

>次に、errorDocumentはvirtualHostのdocumentRootの外においてありますでしょうか?

これは、どういったことでしょうか?

ちなみに、
DocumentRoot /usr/local/A/B
ErrorDocument エラーコード /C/error.html

error.htmlの置いてある場所は
/usr/local/A/B/C/error.html
となっております。

投稿日時 - 2009-09-20 20:51:39

ANo.3

>VirtualHost内でErrorDocumentを設定
ですが、vartualHost:443のディレクティブに対して
ErrorDocumentの設定をしていて、
一生懸命ポート80でアクセスしているなんてことはないですよね?

投稿日時 - 2009-09-18 14:34:08

お礼

度々のご回答まことにありがとうございます。

>vartualHost:443のディレクティブに対して
>ErrorDocumentの設定をしていて、
>一生懸命ポート80でアクセスしているなんてことはないですよね?

知識不足で申し訳ありません。
vartualHost:443がよくわからないのですが。
----------------------------------------------------
NameVirtualHost *:80
<VirtualHost *:80>
DocumentRoot /usr/local/~/~/~
ServerName ~.~.~

ErrorDocument エラーコード 【ファイルへのパス】

JkMount ~
 ・・・
</VirtualHost>
----------------------------------------------------
となっております。

上記でmarimari01さんがおっしゃってることに
なってしまっているのでしょうか?

投稿日時 - 2009-09-18 15:31:22

ANo.2

>・ErrorDocument エラーコード "文字列"
>直接URLをたたくと表示されることは確認しております。
これで出るならば、httpd.confでのパスのタイプミスぐらいしか
思いつかないですね
あと、ファイルが実態ではなくリンクになっているとか。

>そのファイルは誰に対してのアクセスを許せばいいのでしょうか?
apahceの実行ユーザに対してです
777ならば問題ないですが

投稿日時 - 2009-09-18 11:02:19

お礼

ご回答まことにありがとうございます。

>これで出るならば、httpd.confでのパスのタイプミスぐらいしか

・ErrorDocument エラーコード 【ファイルへのパス】

とした時に、
ここでの【ファイルへパス】は、
VirtualHost内でErrorDocumentを設定しているならば、

(1)VirtualHost内のDocumentRootからの相対パス(/~/~.html)
(2)ローカルでの絶対パス(/usr/local/~/~/~.html)
(3)http://ドメイン/~/~/~.html

の3つを設定しましたが、表示されませんでした。

ちなみに(3)は直接ブラウザで叩くと表示されます。
これは一番の謎なんですw

直接叩くと表示されるのに、ErrorDocumentディレクティブだと
表示されない・・・。

どうかご教授よろしくお願いいたします。

投稿日時 - 2009-09-18 11:52:44

ANo.1

単純に
/~/~/~.html
にファイルが無いかアクセス権限がないとおもいます

直接
http://hogehoge/~/~/~.html
で該当のエラーページが表示されますか?

投稿日時 - 2009-09-17 19:35:12

補足

ご回答ありがとうございます。

直接URLをたたくと表示されることは確認しております。

アクセス権限に関してですが、
そのファイルは誰に対してのアクセスを許せばいいのでしょうか?
ちなみに、パーミッションは777になっております。

何卒よろしくお願いいたします。

投稿日時 - 2009-09-17 20:06:36

お礼

引き続き、ご回答よろしくお願いいたします。

投稿日時 - 2009-09-18 09:03:49

あなたにオススメの質問