.htaccess - コア機能

AcceptPathInfo ディレクティブ

AcceptPathInfo ディレクティブは、ファイル名の後ろに続く "パス名の情報" (PATH_INFO) のリクエストを受け付けるか、拒否するかを制御します。例えば、https://murashun.jp/index.html/hoge の場合は、/hoge が環境変数 PATH_INFO に格納されます。/hoge は、存在しないパスであるため、HTTP ステータス 404 エラー (Not Found) が返されると思うかもしれませんが、通常通り指定したファイルが返されます。もしも、存在しないパスに対して HTTP ステータス 404 エラー (Not Found) を返したい場合は、明示的に Off または Default を設定します。以下は 本ディレクティブの構文となります。

# AcceptPathInfo ディレクティブの構文
AcceptPathInfo On|Off|Default
AcceptPathInfo ディレクティブの構文
# AcceptPathInfo の設定例
AcceptPathInfo Off
AcceptPathInfo の設定例

AcceptPathInfo ディレクティブに指定可能な値は以下の通りです。

AcceptPathInfo ディレクティブに指定可能な値
説明
Off存在しないパスのリクエストは受け付けません。そのため、index.html/hoge にリクエストがあった場合は HTTP ステータス 404 エラー (Not Found) エラーを返します。
On前方のディレクトリが存在するリクエストを受け付けます。そのため、index.html/hoge などは受け付けられます。
Default後方のパス情報はリクエストのハンドラによって決まります。CGI などで環境変数 PATH_INFO を扱う場合はリクエストを受け付け、扱わない場合は受け付けず HTTP ステータス 404 エラー (Not Found) を返します。

Apache サーバの仕様では実際には存在しない URL でもページが表示される場合があります。例えば、ファイルを保存しているディレクトリ名がネストしている場合や、ディレクトリに 1 ファイルしか存在しない場合に発生します。

具体的には https://murashun.jp/top/example.html というファイルパスがあった場合、以下の存在しない URL でもページが表示されます。

  • https://murashun.jp/top/top/top/example.html
  • https://murashun.jp/top/top/top/
  • https://murashun.jp/top/example/
  • https://murashun.jp/top/example

上記のような存在しない URL に対して HTTP ステータス 404 エラー (Not Found) エラーを返すには、明示的に AcceptPathInfo ディレクティブで Off または Default を設定します。

# AcceptPathInfo の設定例
AcceptPathInfo Default
AcceptPathInfo の設定例

AddDefaultCharset ディレクティブ

AddDefaultCharset ディレクティブは、レスポンスの MIMEタイプ(Content-Type) が text/plain または text/html の場合に文字エンコーディングのデフォルト値を指定できます。HTML の meta タグで charset を設定していても、本ディレクティブが設定されている場合は、本ディレクティブの設定が優先されます。そのため、ファイルのエンコーディングと、本ディレクティブの設定が異なっている場合、文字化けの原因になります。

% curl -I https://murashun.jp/
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8 # charset が utf-8 に設定されている
AddDefaultCharset の確認例

Webサイトで使用する文字エンコーディングは、(例えば UTF-8 で)固定しておくと良いでしょう。AddDefaultCharset ディレクティブをコメントアウト、または Off の設定で無効化しておくのも一つの方法です。すべてのテキストリソースが正しくエンコーディングされていて、charset が適切にされている場合は設定する必要はありません。ただし、クロスサイトスクリプティングを利用した攻撃を防止する上でも、設定することを推奨します。

# AddDefaultCharset の設定例
AddDefaultCharset utf-8
AddDefaultCharset の設定例

AddDefaultCharset ディレクティブに指定可能な値は以下の通りです。

AddDefaultCharset ディレクティブに指定可能な値
説明
OffMIMEタイプ(Content-Type) が text/plain または text/html の charset を無効化します。Offはデフォルト値であるため、このディレクティブ自体をコメントアウトした場合も同様です。
OnApache 内部のデフォルト文字セット iso-8859-1 に設定されます。
(任意の文字コード)IANAに登録されている文字セットを設定できます。

AddDefaultCharset ディレクティブを使うことで、文字化け対策を行うことができます。文字化け対策を行うためには .htaccess で設定を行う他にもいくつかの注意点があります。まずテキストエディタで HTML ファイルを作成しますが、ここで保存するときに文字エンコーディングを選択します。この保存時の文字エンコーディングがベースの文字コードとなります。一般的には、"UTF-8" (BOMなし) を選択します。

次に .htaccess で以下のようにデフォルトの文字コードを設定します。

# AddDefaultCharset の設定例
AddDefaultCharset utf-8
AddDefaultCharset の設定例

通常は、上記までの設定でも問題ありませんが、AddType ディレクティブの設定で、extension (拡張子) に指定された MIME-type (MIME タイプ(Content-Type)) の関連付けを行うことができます。

# AddType の設定例
AddType "text/html; charset=UTF-8" .html
AddType の設定例

Web サイトで使う文字コードは統一した上で、上記の設定を行うと文字化けを回避できます。テキストエディタによっては、通常の文字コードが Shift_JIS で保存するものもあるため、気付かずに文字コードが異なる場合があります。その場合は .htaccess の設定とあわせて、ファイルの文字コードも確認してみて下さい。

文字コードが設定は非常に重要です。文字化けを発生させないことはもちろん、正しく設定されていない場合は、クロスサイトスクリプティング (XSS) 攻撃のリスクを抱えることになります。

例えば、Google の HTTP 404 エラー (Not Found) のページには、リクエストされた URL のパス名を画面に表示するようになっており、そのパス名に HTML タグが埋め込まれた場合、"<"">" にエスケープして出力するように実装されています。しかし、2005 年までは HTTP 404 エラーページの文字エンコーディングを指定していませんでした。そのため、Internet Explorer などのブラウザでは、ページのエンコーディングが指定されていない場合、自動的にエンコーディングする機能が働くため、例えば自動的に UTF-7 エンコードされる XSS 攻撃文字列を URL に含めて Google の HTTP 404 エラーページを表示させる攻撃の場合、任意の JavaScript コードが実行されてしまう問題点が過去にありました。

本ディレクティブは 1 行で完了するため、クロスサイトスクリプティングを利用した攻撃を防ぐ上でも設定することを推奨します。

AddOutputFilterByType ディレクティブ

AddOutputFilterByType ディレクティブは MIMEタイプ(Content-Type) に応じて出力フィルターを使用できます。フィルターとは、サーバが送受信したデータに適用する処理のことを言います。出力フィルターは、Webサーバからクライアントにレスポンスを返すデータに処理を行うフィルターを指します。ただし、Apache 2.0.33 以降で使用可能ですが、Apache 2.1 以降で本ディレクティブは非推奨となり、代わりに同等の機能を持つ mod_filter を使用することが推奨されています。

非推奨の理由は、MIMEタイプ(Content-Type)が不明な場合はフィルターが部分的、または完全に有効にならないためです。AddOutputFilterByType ディレクティブはまだ機能していますが、可能な限り使用は避けた方が良いでしょう。

以下の例では、特定の MIMEタイプ(Content-Type) をクライアントに送る前に圧縮 (DEFLATE) しています。ただし、さくらインターネットのレンタルサーバーでは、以下の方法では圧縮されません。詳細は、"gzip圧縮によるサイトパフォーマンスを向上させる方法"を参考にして下さい。

# AddOutputFilterByType の設定例
SetOutputFilter DEFLATE

# gzip をサポートしていないレガシーブラウザを除外
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html

# 圧縮済みの画像は再圧縮しない
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|ico)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI _\.utxt$ no-gzip

# html や css などのテキストは圧縮する
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/atom_xml
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/x-httpd-php
AddOutputFilterByType の設定例

AuthName ディレクティブ

AuthName ディレクティブは、Basic認証などを行う際に出力される、ダイアログに表示されるメッセージを指定できます。このメッセージは、利用者がどのユーザ名とパスワードを入力すれば良いかを教えるために利用します。日本語も設定可能ですが、サーバやブラウザによって文字化けを起こす可能性があるため、半角英字で設定した方が無難です。また、メッセージにスペースが含まれる場合は " で囲む必要があります。

ただし、厳密な意味でのAuthName ディレクティブは、認可領域の名前となります。ブラウザで認証が必要なページに初めてアクセスした場合、サーバはブラウザに対して認証が必要であることを通知します。通知を受けると、ブラウザは認証ダイアログを表示し、ユーザにユーザ名とパスワードの入力を求めます。入力されたユーザ名とパスワードを元に、"Authorization" というヘッダーが作成されてリクエストが投げられます。サーバは Authorization ヘッダーを元に認証を行います。ブラウザは認証が必要な他のページにリクエストを投げる場合も、AuthName が同じである場合は Authorization ヘッダーを付けてリクエストを投げるようになります。そのため、AuthName が同じで、一度認証が完了している場合は、改めて認証することなくページの閲覧が可能になります。つまり、AuthName ディレクティブの厳密な使い方としては、認可する領域ごとに異なる名前を付けるべきだと考えます。

本ディレクティブは単体では利用できません。利用するには、AuthType ディレクティブ、Require ディレクティブ、AuthUserFile や AuthGroupFile のディレクティブと一緒に利用する必要があります。

# AuthName の設定例(他のディレクティブとセット)
AuthType Basic
# ダイアログに Top Secret と表示します
AuthName "Top Secret"
AuthUserFile "/home/murashun/passwords"
Require valid-user
AuthName の設定例
AuthName ディレクティブのダイアログ例
AuthName ディレクティブのダイアログ例

AuthType ディレクティブ

AuthType ディレクティブは、ユーザー認証の種類を指定できます。使用できる認証方式は Basic または Digest です。

Basic 認証は最も基本的なユーザ認証方式です。認証を必要とするページにアクセスすると、ユーザ名とパスワードの入力が求められます。アクセスを許可しているユーザである場合は、ページを閲覧できます。ただし、ユーザ名とパスワードは暗号化されていないため、プレーンテキストとしてサーバと送受信されるため、盗聴や改ざんのセキュリティリスクがあります。Basic 認証方式はどのブラウザでも対応しており、簡単に利用できる反面、セキュリティリスクが高く重要なデータの保護に向いていない特徴があります。

Digest 認証は、ユーザ名やパスワードの認証情報をハッシュ化してサーバと送受信する認証方式です。Basic 認証と比べてセキュリティリスクが低く、盗聴や改ざんを防止できます。

# AuthType の設定例(他のディレクティブとセット)
# 認証方式を Basic 認証方式に設定
AuthType Basic
AuthName "Top Secret"
AuthUserFile "/home/murashun/passwords"
Require valid-user
AuthType の設定例

本ディレクティブは単体では利用できません。利用するには、AuthName ディレクティブ、Require ディレクティブ、AuthUserFile や AuthGroupFile のディレクティブと一緒に利用する必要があります。

AuthType ディレクティブに指定可能な値
説明
BasicBasic 認証方式(mod_auth_basicで実装)となります。
DigestDigest 認証方式(mod_auth_digestで実装)となります。

CGIMapExtension ディレクティブ

CGIMapExtension ディレクティブは、Apache が CGI スクリプトを実行するためのインタープリタのパスと拡張子を指定できます。例えば、CGIMapExtension sys:/perl.nlm .cgi と指定すると、.cgi という拡張子のすべての CGI スクリプトが perl インタープリタに渡されます。ただし、本ディレクティブは、NetWare という Nobell社が開発したネットワークOSのみ互換性があるため、一般的に UNIX 系にインストールされている Apache では使用できません。

# NetWare 固有の設定例
# (sysボリュームのパスも.nlmの拡張子もNetWare固有のものです)
CGIMapExtension sys:/perl.nlm .cgi
CGIMapExtension の設定例

ContentDigest ディレクティブ

ContentDigest ディレクティブは、Content-MD5 ヘッダーの生成を有効にします。Content-MD5 ヘッダーとは、HTTP ヘッダーに含まれており、コンテンツが通信途中で改ざんされていないかをチェックするためのデータ(128 bit の MD5 ダイジェストを BASE64 エンコードしたもの)を表します。そのため、コンテンツが途中で改ざんされた場合に検知することが可能になります。

# ContentDigest の設定例
ContentDigest On
ContentDigest の設定例
% curl -I https://murashun.jp/
HTTP/1.1 200 OK
Content-MD5: AuLb7Dp1rqtRtxz2m9kRpA==  # Content-MD5 ヘッダーの例
Content-MD5 ヘッダーの例

ただし、本ディレクティブはリクエスト毎にメッセージダイジェストを計算するため、サーバパフォーマンスが低下する点に注意して下さい。メッセージダイジェストの値はキャッシュされないため、純粋にパフォーマンスが低下します。さくらインターネットのレンタルサーバーで試しましたが、本ディレクティブは許可されていないようです。

ContentDigest ディレクティブに指定可能な値
説明
OnContent-MD5 ヘッダーの生成を有効にします。
OffContent-MD5 ヘッダーの生成を無効にします。

DefaultType ディレクティブ

DefaultType ディレクティブは、サーバがリクエストされたファイルの MIMEタイプ(Content-Type)を決定できない場合に、送る MIMEタイプ(Content-Type)を指定できます。Apache は、拡張子から mime.types という一覧を参照し、MIMEタイプ(Content-Type)を判断しています。しかし、mime.types に存在しない未定義のファイルがリクエストされた場合は、指定された MIMEタイプ(Content-Type)をクライアントに通知します。デフォルトでは text/plain が選択されています。

また、mime.types は AddType ディレクティブにより、MIMEタイプ(Content-Type)の追加・変更(上書き)が可能です。ただし、DefaultType が指定されていても MIMEタイプ(Content-Type)が決定できる場合は、DefaultType の指定された値は上書きされます。強制的に MIMEタイプ(Content-Type)指定する場合は、ForceType ディレクティブを使用します。

# DefaultType の設定例
DefaultType text/plain
DefaultType の設定例

もしも、MIMEタイプ(Content-Type)が決定できない場合に、誤った MIMEタイプ(Content-Type)を指定するぐらいであれば、むしろ無いほうが良いという場合は None を指定できます。ただし、None の指定は httpd-2.2.7 以降で使えます。

DefaultType ディレクティブに指定可能な値
説明
(MIMEタイプ)MIMEタイプ(Content-Type)が決定できない場合に、指定された MIMEタイプ(Content-Type)を返します。
noneMIMEタイプ(Content-Type)が決定できない場合に、空を返します。

EnableMMAP ディレクティブ

EnableMMAP ディレクティブは、ファイルの転送中に内容を読み込む必要がある場合、httpd がメモリマッピングを使用するかを制御します。httpd とは UNIX系のOSの常駐プログラムのひとつであり、外部からのHTTPリクエストを受け付けファイルを転送したりします。その際に、転送するファイルの内容を読み込むためにメモリマッピングを使用するかどうかを制御します。

デフォルトの設定値はメモリマッピングを使用する設定になっています。例えば、SSIファイルなどを転送する場合、ファイルの中のコメント部分にサーバの実行コマンド結果を埋め込む必要があるため、ファイルにアクセスする際にメモリにマッピングします。

ただし、ファイルシステムが NFS でマウントされたボリュームに DocumentRoot がある場合、ファイルの削除や、ファイルサイズの変更に伴うセグメンテーションフォールトが原因で httpd がクラッシュする可能性があります。この問題が発生するサーバの設定の場合は、メモリマッピングを使用不可に設定することもできます。

# EnableMMAP の設定例
EnableMMAP Off
EnableMMAP の設定例
# httpd.conf で NFS マウント部分のみ使用不可にする例
<Directory "/nfs-files">
  EnableMMAP Off
</Directory>
httpd.conf で NFS マウント部分のみ使用不可にする例
EnableMMAP ディレクティブに指定可能な値
説明
Onファイル転送時にメモリマッピングを行います。
Offファイル転送時にメモリマッピングを行いません。

EnableSendfile ディレクティブ

EnableSendfile ディレクティブは、ファイルの転送中に httpd がカーネルの sendfile サポートを使用するかを制御します。カーネルの sendfile は、ファイルディスクリプタ間でデータを転送するために使われます。この転送方法は、カーネル空間上でデータのやりとりが行われているため、通常のユーザ空間上でデータをやりとりしている read と write を組み合わせるよりも効率が良くなります。また、本ディレクティブは、Apache 2.0.44 以降で使用可能です。

デフォルトの設定値はsendfile のサポートを使用する設定になっています。例えば、リクエストの処理を行う際に、データにアクセスの必要がない静的なファイルを転送する場合、ファイルを読み込むことなく sendfile を使ってファイルを転送します。

ただし、ファイルシステムが NFS や SMB でマウントされたボリュームに DocumentRoot がある場合、カーネルはキャッシュを使ってネットワークからファイルを転送できない場合があります。この問題が発生するサーバの設定の場合は、sendfile のサポートを使用不可に設定することもできます。

# EnableSendfile の設定例
EnableSendfile Off
EnableSendfile の設定例
# httpd.conf で NFS マウント部分のみ使用不可にする例
<Directory "/nfs-files">
  EnableSendfile Off
</Directory>
httpd.conf で NFS マウント部分のみ使用不可にする例
EnableSendfile ディレクティブに指定可能な値
説明
Onsendfile のサポートを使用可能にします。
Offsendfile のサポートを使用不可にします。

ErrorDocument ディレクティブ

ErrorDocument ディレクティブは、問題やエラーが発生したときの動作を指定できます。指定できる動作は、以下の 4 つがあります。デフォルトの動作は 1 番目の動作になります。

  1. Apache 標準のエラーメッセージを表示する
  2. 指定した任意のメッセージを表示する
  3. 内部サーバの別の URL にリダイレクトする
  4. 外部サーバの別の URL にリダイレクトする

2 番目から 4 番目は、HTTPのレスポンスコードとメッセージ、または URL を指定することで設定します。メッセージの場合は、" を付けて指定します。URL の場合は、/ で始まる DocumentRoot からの相対パス、または http などで始まる完全な URL を指定します。

# ErrorDocument の構文
ErrorDocument error-code document
ErrorDocument の構文
# Apache 標準のエラーメッセージを表示する
ErrorDocument 503 default
# 指定した任意のメッセージを表示する
ErrorDocument 403 "Sorry. 403 Forbidden."
# 内部サーバの別の URL にリダイレクトする
ErrorDocument 404 /error/404error.html
# 外部サーバの別の URL にリダイレクトする
ErrorDocument 500 http://example.com/error.html
ErrorDocument の設定例

4 番目の別の URL にリダイレクトする方法は、内部サーバのドキュメントを指定する場合であっても、リダイレクトをクライアントに通知する点に注意して下さい。その場合、クライアントはエラーステータスコードを受け取らずに、リダイレクトのステータスコードを受け取ります。ステータスコードを使って URL を有効であるか判断するプログラムに混乱を与える可能性があります。

また、エラーステータスコード 401(Unauthorized:認証失敗)をリダイレクト指定する場合、クライアントは 401 のステータスコードを受け取らないため、パスワードをユーザに入力要求しなければならないことが分かりません。そのため、401 を指定する場合は、3 番目のような内部サーバのドキュメントを参照するようにしなければなりません。

Microsoft Internet Explorer は、エラーメッセージが 512 Byte より小さい場合、エラーメッセージを無視してオリジナルのエラーメッセージを表示します。エラーメッセージが 512 Byte より大きい場合は、そのまま表示します。詳しい情報は Microsoft Knowledge Base の記事 Q294807 にあります。

Google Chrome で 404エラーが発生した場合
Google Chrome で 404エラーが発生した場合
Microsoft Internet Explorer で 404エラーが発生した場合
Microsoft Internet Explorer で 404エラーが発生した場合

本ディレクティブでは、ほとんどのエラーメッセージを上書きできますが、不正な形式のリクエストが検出された場合は、Apache オリジナルのエラーメッセージが返されます。この処理は、不正なリクエストによって引き起こされる、セキュリティの問題から守るための措置です。

FileETag ディレクティブ

FileETag ディレクティブは、HTTP レスポンスヘッダに ETag(エンティティタグ)フィールドを作成するために指定します。ETag フィールドは、HTTP におけるキャッシュの有効性を確認するために使われます。例えば、ETag が同じ値である場合、コンテンツに変更がないと判断できるため、レスポンスをすべて返す必要がなくなります。そのため、キャッシュの効率化、および回線帯域の節約ができるようになります。

Apache 1.3.22 以前では、ETag の値は常に inode、ファイルサイズ、最終更新時刻から作成されていましたが、本ディレクティブによって以下の 5 つから選択できるようになりました。複数指定する場合は、半角スペースで区切って指定します。デフォルトの設定では FileETag INode MTime Size となっており、HTTP リクエスト・レスポンスの ETag フィールドでは - で連結されています。

  1. INode:ファイルの inode 番号を使います。
  2. MTime:ファイルの最終更新時刻を使います。
  3. Size:ファイルの Byte 数を使います。
  4. All:上記の 3 つをすべて使います。
  5. None:ETag フィールドをレスポンスに付加しません。

また、ETag は +- を上記のキーワードに付けることでディレクトリ毎の設定を変更できます。例えば、上位ディレクトリで FileETag MTime Size を指定し、下位ディレクトリで FileETag -Size を指定すると、上位ディレクトリから継承した設定から Size が削除され、下位ディレクトリは FileETag MTime の設定になります。

# All は以下と同じです。
FileETag INode MTime Size
FileETag の設定例
# ETag フィールドが付与されているレスポンス例
% curl -I https://murashun.jp/img/logo.png
HTTP/1.1 200 OK
Last-Modified: Wed, 15 Jul 2015 11:33:13 GMT
ETag: "acf9ef9-7ea-51ae851f07040"  # ETag が付与されている
Content-Length: 22761
ETag フィールドが付与されているレスポンス例

ETag は、コンテンツが一致するかを決定する方法のひとつです。ブラウザがコンテンツ(例えば logo.png など)の ETag をキャッシュ後、改めて有効性を確認したい場合は、If-None-Match ヘッダを使ってサーバに ETag を送り返します。ETag が一致すると 304 ステータスコードが返され、レスポンスサイズが小さくなります。

# HTTP Request
GET https://murashun.jp/img/logo.png
Host: murashun.jp
If-Modified-Sine: Wed, 15 Jul 2015 11:33:13 GMT
If-None-Match: "acf9ef9-7ea-51ae851f07040"

# HTTP Response
HTTP/1.1 304 Not Modified
コンテンツに変更がなかった場合のリクエスト/レスポンス

ただし、ETag の問題点として、負荷分散をするために Web サーバが複数台ある場合は、同じ内容のファイルであっても inode がサーバ毎で異なってしまうため、デフォルトの設定では 200 ステータスコードを返す可能性があります。その場合、パフォーマンスが低下し、サーバの負荷が高くなることになります。そのため、Web サーバが複数台ある場合は inode を使わないか、ETag 自体を使わない設定を検討する必要があります。

Files ディレクティブ

<Files> ディレクティブは、指定したファイル名にディレクティブを適用させることができます。指定するファイル名は、完全なファイル名、または部分ファイル名や拡張子などでも問題ありません。適用される範囲は、<Files> ディレクティブで囲まれたブロック内となります。

# 画像ファイルに対して ETag ディレクティブを適用する
<Files ~ "\.(gif|jpe?g|png)$">
  FileETag None
</Files>
<Files> ディレクティブの例

ファイル名には、ワイルドカード文字列を使用できます。ワイルドカード文字列では ? は一つの文字、* は任意の文字列にマッチします。~ の文字を使うことで正規表現も使用可能です。ただし、本ディレクティブよりも <FilesMatch> ディレクティブを使う方が推奨されています。

FilesMatch ディレクティブ

<FilesMatch> ディレクティブは、正規表現で指定したファイル名にディレクティブを適用させることができます。<Files> ディレクティブで正規表現を使う場合と異なり、~ を使用しないことに注意して下さい。

# 画像ファイルに対して ETag ディレクティブを適用する
<FilesMatch "\.(gif|jpe?g|png)$">
  FileETag None
</FilesMatch>
<FilesMatch> ディレクティブの例

ForceType ディレクティブ

ForceType ディレクティブは、そのディレクトリにあるファイルの MIMEタイプ(Content-Type)を強制的に指定した値で通知します。例えば、gif 画像を格納しているディレクトリがある場合、以下のように指定すると MIMEタイプ(Content-Type) は image/gif で通知されます。もしも、gif 画像以外の拡張子を持つ画像が含まれていても image/gif で通知されます。

# MIMEタイプ(Content-Type) を強制的に image/gif にする例
ForceType image/gif
ForceType ディレクティブの例

DefaultTypeディレクティブと似ていますが、本ディレクティブは拡張子から MIMEタイプ(Content-Type)が決定できる・できないに関わらず、MIMEタイプ(Content-Type)を上書きする点が異なります。

IfDefine ディレクティブ

<IfDefine> ディレクティブは、Apache の起動時に条件を満たした場合にディレクティブを適用させることができます。起動時の条件とは、httpd のコマンドラインにパラメータを"指定する"、または"指定しない"のいずれかの条件を設定できます。パラメータを指定しない条件の場合、! をパラメータ名の前に付与すると、そのパラメータが指定していない場合に処理されます。

# 起動時にパラメータを指定する場合
<IfDefine parameter-name>
  ...
</IfDefine>

# 起動時にパラメータを指定しない場合
<IfDefine !parameter-name>
  ...
</IfDefine>
<IfDefine> ディレクティブの例

上記の parameter-name に起動時のパラメータを指定します。例えば、下記の例では、起動時に "maintenance" というパラメータ名を付けることで、常にメンテナンスページにリダイレクトする処理が有効になる例になります。

# "maintenance" パラメータ付きで起動した場合、メンテナンスページにリダイレクトする例
<IfDefine maintenance>
  RewriteEngine On
  RewriteRule ^(.*)$ https://murashun.jp/maintenance.html [L]
</IfDefine>
<IfDefine> ディレクティブの例

本ディレクティブの設定は、httpd サービスをコマンドラインオプション [-D name] を付与して起動することで有効になります。ただし、レンタルサーバでは利用者に再起動権限がないため、あまり有用ではありません。

# コマンドラインオプション [-D name] で起動する
[root@ ~]# service httpd -D maintenance
httpdを停止中:                       [ OK ] 
httpdを起動中:                       [ OK ] 
[root@ ~]# 
パラメータ付きで起動する例

IfModule ディレクティブ

<IfModule> ディレクティブは、モジュールが存在する、または存在しない場合に処理されるディレクティブを指定できます。モジュールが存在しない条件の場合、! をモジュールのファイル名の前に付与すると、そのモジュールが存在しない場合に処理されます。また、指定する名前はモジュールのファイル名(module-file)の他に、モジュール識別子(module-identifier)も指定できます。例えば、mod_rewrite.c はファイル名、rewrite_module は識別子です。ただし、モジュール識別子は Apache 2.1 以降で使用可能です。

# モジュールが存在する場合
<IfModule module-file|module-identifier>
  ...
</IfModule>

# モジュールが存在しない場合
<IfModule !module-file|module-identifier>
  ...
</IfModule>
<IfDefine> ディレクティブの例

本ディレクティブでは、モジュールのテストや、1 つの設定ファイルを様々な環境で使いまわすために使用されます。そのため、通常は本ディレクティブを使用しなくても問題ありません。

Limit ディレクティブ

<Limit> ディレクティブは、指定した HTTP メソッド(GET や POST など)に処理されるディレクティブを指定できます。HTTP メソッドは、大文字小文字を区別するため、GET と get は異なるメソッドであると判定されます。ただし、アクセス制御は、すべての HTTP メソッドに対して処理を行うことが望ましい挙動です。 そのため、通常はアクセス制御に関するディレクティブを、本ディレクティブ内に設定するべきではありません。

HTTP/1.0 HTTP/1.1 のメソッド一覧
メソッドHTTP/1.0HTTP/1.1説明
GETサーバに対してファイルの取得を要求するメソッドです。また、サーバに情報を伝えるために URL に ? を付けて "パラメータ名=値" として送信することもできます。
HEADヘッダのみの情報を要求するメソッドです。
POST入力フォームなどのクライアントからデータを送信するメソッドです。
PUTファイルをサーバにアップロードするメソッドです。
DELETE指定したファイルを削除することをサーバに要求するメソッドです。
CONNECTプロキシサーバを経由して SSL 通信などを行うメソッドです。
OPTIONSサーバがサポートしているメソッドを調べるためのメソッドです。
TRACEHTTP リクエストをトレースするためのメソッドです。クライアントが送信したリクエストメッセージをそのまま返します。
LINK指定した URL とリソース間にリンク関係を結びます。
UNLINK指定した URL とリソース間のリンク関係を解除します。
 (-:必須、◯:サポート、✕:未サポート)

本ディレクティブでは上記のメソッドが指定できます。複数のメソッドを指定する場合は、半角スペースで区切って指定します。指定されなかったメソッドは、アクセス制御されません。

# POST、PUT、DELETE に対してアクセス制御を行う例
<Limit POST PUT DELETE>
  Require valid-user
</Limit>
<Limit> ディレクティブの例

本ディレクティブのアンチパターンとして、以下のような書き方があります。

# GET に対してアクセス制御を行う例
<Limit GET>
  Require valid-user
</Limit>
<Limit> ディレクティブのアンチパターン

上記の例では、GET メソッドでリクエストされた場合のみアクセス制限を行っています。しかし、Apache 2 では通常のドキュメントに対して POST メソッドでアクセスしても、GET メソッドと同じようにコンテンツを返します。以下は、Telnet を使用して POST メソッドでアクセスした場合のログです。

# telnet を使用して murashun.jp にアクセスする
% telnet murashun.jp 80

Trying 49.212.243.33...
Connected to murashun.jp.
Escape character is '^]'.

# POST メソッドでアクセスする
POST / HTTP/1.1
Host: murashun.jp
Content-Length: 0

# HTTP ステータスコード 200 OK が返ってきてしまう
HTTP/1.1 200 OK
・・・(中略)・・・

%
<Limit> ディレクティブのアンチパターン

上記のように、POST メソッドでもコンテンツを取得できるため、本ディレクティブは特別な事情がない限りは使用は避けた方が無難です。どうしても使用したい場合は、下記の <LimitExcept> ディレクティブも検討して下さい。

LimitExcept ディレクティブ

<LimitExcept> ディレクティブは、指定した HTTP メソッド(GET や POST など)以外に処理されるディレクティブを指定できます。つまり、<Limit> ディレクティブとは逆に、指定されなかった HTTP メソッドに対して処理を行います。指定できる HTTP メソッド一覧は、<Limit> ディレクティブを参照して下さい。

# GET、POST 以外に対してアクセス制御を行う例
<LimitExcept GET POST>
  Require valid-user
</LimitExcept>
<LimitExcept> ディレクティブの例

LimitRequestBody ディレクティブ

LimitRequestBody ディレクティブは、HTTP リクエストのボディ部に許容される Byte 数を指定できます。指定できる範囲は 0 (無制限) ~ 2147483647 (2GB) までになります。デフォルト値は、0 (無制限) となります。指定された値を超えた場合、サーバは HTTP リクエストを処理せずにエラーを返します。通常の HTTP リクエストのボディ部のサイズは、リソースの種類やメソッドによって大きく異なります。例えば、ファイルアップロードできるサイズを 100 KB に制限する場合は、以下のように指定します。

# 100 KB = 1024 Byte * 100
LimitRequestBody 102400
LimitRequestBody ディレクティブの例

本ディレクティブは、クライアントからの異常なリクエストを制御できるようにし、何らかのサービス拒否攻撃(DoS 攻撃など)を避けるのに有効です。ただし、ファイルアップロードで使われる PUT メソッドの実装などでは、少なくとも受け入れ可能なサイズ以上にする必要があります。

LimitXMLRequestBody ディレクティブ

LimitXMLRequestBody ディレクティブは、XML 形式の HTTP リクエストのボディ部に許容される Byte 数を指定できます。基本的には、前述した LimitRequestBody ディレクティブと同様になります。0 (無制限) を指定することで、チェックを無効化できます。デフォルト値は、1000000 (約 1 MB) となります。

# LimitXMLRequestBody のチェックを無効化
LimitXMLRequestBody 0
LimitXMLRequestBody ディレクティブの例

Options ディレクティブ

Options ディレクティブは、ディレクトリに対してどの機能が使用可能かを制御します。複数の機能を指定する場合は、半角スペースで区切って指定します。さくらインターネットのレンタルサーバでは、2017 年 3 月 8 日から本ディレクティブが使用可能になりました。

Options ディレクティブに指定可能な値
説明
AllMultiViews を除いた全ての機能が有効となります。この値がデフォルト値となります。
ExecCGICGI スクリプトの実行を可能にします。
FollowSymLinksシンボリックリンクを有効にします。
IncludesSSI の実行を可能にします。
IncludesNOEXECSSI は有効になりますが、#exec cmd と #exec cgi は無効になります。
IndexesDirectoryIndex ディレクティブで指定したファイル (例えば、index.html) がなければ、ディレクトリ一覧を表示することを許可します。
MultiViewsリソースが複数の表現 (例えば、日本語や英語など) で利用できる場合、適切な言語や MIMEタイプ(Content-Type) を優先的に要求するコンテンツネゴシエーションを許可します。
Noneすべてのオプションを無効にします。
SymLinksIfOwnerMatchシンボリック先のファイル、またはディレクトリが、ファイル所有者と同じ権限である場合、シンボリックリンクを許可します。

また、+ や - を上記のキーワードに付けることでディレクトリ毎の設定を変更できます。例えば、上位ディレクトリで Options ExecCGI Includes を指定し、下位ディレクトリで Options -Includes を指定すると、上位ディレクトリから継承した設定から Includes が削除され、下位ディレクトリは Options ExecCGI の設定になります。ただし、+ や - を付けたキーワードと、付けていないキーワードを同時に指定する記述は誤りで、予期しない結果になる可能性があります。

# ExecCGI と Includes のみ許可する
Options ExecCGI Includes
Options ディレクティブの例

Require ディレクティブ

Require ディレクティブは、認証されたユーザがリソースに対してアクセスできるかを制御します。

Require ディレクティブに指定可能な値
説明
Require user
userid [userid] ...
指定されたユーザのみ、ディレクトリへのアクセスを許可します。パスワードファイルに登録されているユーザで、指定した userid のみ認証を行い、その他は拒否します。
Require group
group-name [group-name] ...
指定されたグループに属するユーザのみ、ディレクトリへのアクセスを許可します。パスワードファイルに登録されているユーザで、指定した group-name に属している場合に認証を行い、その他は拒否します。グループは AuthGroupFile で定義をしておく必要があります。
Require valid-userすべての認証されたユーザに、ディレクトリへのアクセスを許可します。
# Require の設定例(他のディレクティブとセット)
AuthType Basic
AuthName "Top Secret"
AuthUserFile "/home/murashun/passwords"
# 認証されたすべてユーザに、ディレクトリへのアクセスを許可します。
Require valid-user
AuthType の設定例

本ディレクティブは単体では利用できません。利用するには、AuthName ディレクティブ、AuthType ディレクティブ、AuthUserFile や AuthGroupFile のディレクティブと一緒に利用する必要があります。また、本ディレクティブが <Limit> ディレクティブ内に含まれる場合は、指定している HTTP メソッドに対して認証を行います。<Limit> ディレクティブ内に含まれない場合は、すべての HTTP メソッドに対して認証を行います。

RLimitCPU ディレクティブ

RLimitCPU ディレクティブとは、HTTP リクエストを受け付けた Apache の子プロセスである httpd から fork されたプロセスの CPU 占有時間を制限します。

本ディレクティブのパラメータは 1 つ、または 2 つ指定できます。1 番目のパラメータは全プロセスに対するリソースのソフトリミットを整数秒、または OS の最大値である max で指定します。2 番目のパラメータは最大のハードリミットを設定します。このパラメータは省略可能です。ただし、最大のハードリミットを上げるためには、特権を持つ root で実行、または起動する必要があります。

# プロセスの CPU 占有時間を 10 秒に設定
RLimitCPU 10
RLimitCPU の設定例

カーネルはプロセスにリソースリミットを設けています。リソースリミットは、プロセスが使用可能なカーネルリソースの上限値です。上限値は強制的なもので、上限値を超えた場合はプロセスを kill します。また、リソースリミットには、ソフトリミット (soft limit) とハードリミット (hard limit) の 2 種類の上限値があります。ソフトリミットは、0 ~ ハードリミットを超えない範囲で変更が可能です。ハードリミットは、ソフトリミットの上限値のことで、特権を持つプロセス以外は、上限値を下げる変更しか許されていません。

また、RLimit から始まる ディレクティブは、httpd から fork された CGI スクリプト と SSI exec コマンドで使われるリソースを制御します。そのため、mod_perl や mod_php を使用した スクリプトは、この設定が無効であることに注意しましょう。

RLimitMEM ディレクティブ

RLimitMEM ディレクティブとは、HTTP リクエストを受け付けた Apache の子プロセスである httpd から fork されたプロセスの メモリ消費量を制限します。

本ディレクティブのパラメータは 1 つ、または 2 つ指定できます。1 番目のパラメータは全プロセスに対するリソースのソフトリミットを Byte 数、または OS の最大値である max で指定します。2 番目のパラメータは最大のハードリミットを設定します。このパラメータは省略可能です。ただし、最大のハードリミットを上げるためには、特権を持つ root で実行、または起動する必要があります。

# プロセスの メモリ消費量を 10 MB に設定
RLimitMEM 10485760
RLimitMEM の設定例

リソースリミットに関する詳細は、前述した RLimitCPU を参照して下さい。

RLimitNPROC ディレクティブ

RLimitNPROC ディレクティブとは、HTTP リクエストを受け付けた Apache の子プロセスである httpd から fork されたプロセス数を制限します。

本ディレクティブのパラメータは 1 つ、または 2 つ指定できます。1 番目のパラメータは全プロセスに対するリソースのソフトリミットを整数、または OS の最大値である max で指定します。2 番目のパラメータは最大のハードリミットを設定します。このパラメータは省略可能です。ただし、最大のハードリミットを上げるためには、特権を持つ root で実行、または起動する必要があります。

# プロセスの数を 10 プロセスに設定
RLimitNPROC 10
RLimitNPROC の設定例

リソースリミットに関する詳細は、前述した RLimitCPU を参照して下さい。

Satisfy ディレクティブ

Satisfy ディレクティブは、Allow ディレクティブ(ホストを通過するための制限)と Require ディレクティブ(ユーザ名とパスワード要求における制限)の両方が使われているときのアクセスポリシーを設定します。デフォルトの設定値は All になります。

Satisfy ディレクティブに指定可能な値
説明
Allクライアントはホストの制限を満たし、かつ正しいユーザ名とパスワードを入力することを要求します。
Anyクライアントはホストの制限を満たす、または正しいユーザ名とパスワードの入力をすることを要求します。

例えば、内部ネットワーク上の利用者には、あるWebページについて無制限のアクセスを許可するが、外部ネットワークの利用者には、パスワードを要求するようにするためには、以下のような設定となります。

# Satisfy の設定例
Require valid-user
Order allow,deny
Allow from 192.168.1
Satisfy Any
Satisfy の設定例

Apache 2.0.51 からは <Limit> と <LimitExcept> ディレクティブを使用することで、本ディレクティブが適用される HTTP メソッドを制限することが可能になりました。

ScriptInterpreterSource ディレクティブ

ScriptInterpreterSource ディレクティブは、Apache が CGI スクリプトを実行するためのインタープリタをどのように探し出すかを指定できます。デフォルトの設定は Script となっており、これはスクリプトファイルの shebang 行 (最初の行で #! から始まるもの) に指されているパスを使用します。Win32 での例は以下のようになります。

#!C:/Perl/bin/perl.exe
...
Win32 におけるスクリプトファイルの shebang 行の例

もしも環境変数の PATH に perl のパスが設定している場合は、以下のようになります。

#!perl
...
Win32 におけるスクリプトファイルの shebang 行の例
ScriptInterpreterSource ディレクティブに指定可能な値
説明
Scriptスクリプトファイルの shebang 行に指されているパスを使用します。
Registryスクリプトファイルの拡張子 (例えば、.pl) をキーとして、Windows のレジストリツリー HKEY_CLASSES_ROOT を検索します。レジストリのサブキーは Shell\ExecCGI\Command、または Shell\Open\Command がスクリプトファイルを開くために使われます。レジストリキーが見つからない場合、Script の設定値になります。
Registry-StrictApache 2.0 以降で使用可能です。Registry と同様ですが、レジストリのサブキーは Shell\ExecCGI\Command のみ使われます。ExecCGI キーは手動で設定する必要があるキーで、一般的なキーではありません。そのため、偶発的なプログラムの誤動作を防ぐことができます。

ただし、本ディレクティブは、Win32 のみ互換性があるため、一般的に UNIX 系にインストールされている Apache では使用できません。

ServerSignature ディレクティブ

ServerSignature ディレクティブは、サーバが生成するドキュメントの最下行に付与するフッターの設定を行います。サーバが生成するドキュメントは、エラーメッセージ、mod_proxy における FTP のディレクトリリスト、mod_info の出力などです。デフォルトの設定値は Off になります。以下の例は、ServerSignature の設定が OffOnEMail の例です。

ServerSignature Off の場合
ServerSignature Off の場合
ServerSignature On の場合
ServerSignature On の場合
ServerSignature EMail の場合
ServerSignature EMail の場合

本ディレクティブの目的は、プロキシサーバーを複数台経由している場合に、ユーザがどのサーバがエラーメッセージを返したのか知る手段がほとんど無いためです。また、Apache 2.0.44 以降では、ServerSignature ディレクティブにより表示される情報も制御します。

# ServerSignature の設定例
ServerSignature On
ServerSignature の設定例
ServerSignature ディレクティブに指定可能な値
説明
OffServerName ディレクティブで指定したフッター行の出力しません。
OnServerName ディレクティブで指定したフッター行を出力します。
EMailServerName ディレクティブで指定したフッター行を出力し、ServerAdmin ディレクティブで指定されたメールアドレスに "mailto:" が追加されます。さくらインターネットのレンタルサーバーでは support@sakura.ad.jp となります。

SetHandler ディレクティブ

SetHandler ディレクティブは、ディレクトリにあるすべてのファイルを強制的に handler-name で指定されたハンドラで扱います。ハンドラとは、ファイルが呼ばれたときに実行される動作の Apache における内部表現です。例えば、ディレクトリ全体が CGI スクリプトファイルである場合、SetHandler ディレクティブで cgi-script を指定すると、拡張子をつけなくても CGI スクリプトと認識されます。

# SetHandler の設定例
SetHandler cgi-script
SetHandler の設定例
SetHandler ディレクティブに指定可能な値
説明
handler-nameデフォルトのハンドラを上書きします。指定できる設定値は下表を参考にして下さい。
None上書きされたハンドラの設定を無効化します。

Apache の組み込みハンドラは以下の通りです。これらのハンドラは、設定値と動作が定義されているだけであり、機能させるには適切に設定する必要があります。レンタルサーバーでは、/cgi-bin 配下で CGI スクリプトを動かすルールなどに従えば、特に設定する必要はありません。

Apache のハンドラタイプ
説明
default-handler静的なコンテンツを扱うときにデフォルトで使用されるハンドラです。
send-as-isHTTP ヘッダを含めてファイルをそのまま送ります。
cgi-scriptファイルを CGI スクリプトとして扱います。ただし、Options ディレクティブで ExecCGI を指定する必要があります。
imap-fileイメージマップのルールファイルとして解析します。
server-infoサーバの設定情報を取得します。
server-statusサーバの状態報告を取得します。
type-mapコンテンツネゴシエーションのためのタイプマップとして解析します。

本ディレクティブは、デフォルトのハンドラを上書きするため、例えば、/ で終わる URL をリクエストされたときにディレクトリや index ファルを返すような挙動が行われなくなります。上書きされたハンドラを無効にする場合は、設定値で None を指定することで無効化できます。

SetInputFilter ディレクティブ

SetInputFilter ディレクティブは、クライアントの HTTP リクエストを処理するフィルタを設定します。本ディレクティブは、AddInputFilter ディレクティブを含め、他の場所で定義されているフィルタの設定に追加されます。複数のフィルタを指定するときは、データを処理する順番に ; で区切る必要があります。

SetOutputFilter ディレクティブ

SetOutputFilter ディレクティブは、クライアントの HTTP レスポンスを処理するフィルタを設定します。本ディレクティブは、AddOutputFilter ディレクティブを含め、他の場所で定義されているフィルタの設定に追加されます。複数のフィルタを指定するときは、データを処理する順番に ; で区切る必要があります。

関連記事