Apache HTTP Server 2.4からの新しい.htaccessの書き方

石川英典

プライム・ストラテジー「KUSANAGI」開発チームの石川です。

Apache HTTP Serverでは .htaccess というファイルを作成することでアクセス権を細かく設定することができます。
現在のApache HTTP Server 2.4が最初にリリースされたのは2012年2月と13年近くが経過していますが、その .htaccess ファイルのアクセス権に関するディレクティブがApache HTTP Server 2.4 から変わっていたことはご存知でしょうか。
Apache HTTP Server 2.2 が EOL になったのが 2017年6月と既に7年以上が前にも関わらず、未だに 2.2 の書き方が多く見られます。

ここでは、過去のApache HTTP Server (2.2まで)のディレクティブの書き方と、現在のApache HTTP Server (2.4以降)のディレクティブの書き方の違いについて解説します。

過去のApache HTTP Server (2.2まで)の書き方

これまでのApache HTTP Serverでは、Order, Allow, Deny というディレクティブを使ってアクセス権を制御していました。

例えば、全てからアクセスを拒否する設定は以下のようになります。

Order deny,allow
Deny from all

逆に、全てからのアクセスを許可する設定は以下のようになります。

Order allow,deny
Allow from all

特定のIPアドレスからのアクセスを許可する設定は、以下のようにしていました。

Order deny,allow
Deny from all
Allow from IPアドレス

また、Basic認証では以下のように上記までの Allow from Deny from とは全く異なる設定をしていました。

AuthType Basic
AuthName "ENTER YOUR NAME & PASSWORD TO LOGIN"
AuthUserFile /home/kusanagi/.htpasswd
Require valid-user
Satisfy any

なお、この最後の Satisfy any に重要な意味がありますので、後ほど解説します。

例えば、ローカルホスト (127.0.0.1) のアクセスは許可して、他のアクセスはBasic認証を必須とする場合は以下のようになります。

Order deny,allow
Deny from all
Allow from 127.0.0.1

AuthType Basic
AuthName "ENTER YOUR NAME & PASSWORD TO LOGIN"
AuthUserFile /home/kusanagi/.htpasswd
Require valid-user
Satisfy any

このディレクティブ (以降、「2.2互換のディレクティブ」とします) は現在のApache HTTP Server (2.4以降)でも引き続き使用することができます。
しかし、あくまでも互換として残されているものなので、将来的に使えなくなる可能性はあります。
また、Basic認証によるアクセス権の設定との組み合わせをより直感的にするため、新しいディレクティブ (以降、「2.4のディレクティブ」とします) が推奨されています。

2.2互換のディレクティブは何が問題だったか

2.2互換ディレクティブでの問題は、Apache HTTP Server 2.2より前から存在するIPアドレスベースのアクセス制御である Allow fromDeny from と、Basic認証のアクセス制御がそれぞれ別々に判定されていたことです。

そのため、IPアドレスによるアクセス制限とBasic認証の両方を有効にしようとすると問題が起きます。

一般的に、ウェブサイトでは以下のようにアクセス制限を運用します。

  1. BotやDoS攻撃のように明かに拒否したいアドレスをIPアドレスベースで制限
  2. 一般ユーザーは許可
  3. 管理者など制限されたページにアクセスできるユーザーをBasic認証で制限

Allow fromDeny from を設定すると、まずIPアドレスベースのアクセス制御が行われます。
許可されていないIPアドレスからのアクセスは、Basic認証を行うことなく拒否されます。
しかし、次にBasic認証のアクセス制御により、全てのユーザーにBasic認証が求められます。
そして、ページにアクセスするには場合はBasic認証を通る必要があります。

この問題は、localhost (127.0.0.1) など明かにBasic認証がなくてもアクセスを許可したい場合でも、Basic認証が必要となっていたことです。

これを解決するために設定に加えたのが Satisfy any です。

IPアドレスによるアクセス制限とBasic認証の、いずれかを満たす (satisfy any) ことができればよい、という意味になります。

この Satisfy any で問題は解決したように見えますが、実はそうではありません。

Deny from で拒否しているはずのIPアドレスからのアクセスであっても、Basic認証の要求が行われます。
そしてBasic認証を突破することができれば、制限されているはずのページにアクセスできてしまいます。

これはIPアドレスによるアクセス制限が満たされなかったら、Basic認証で満たせればいいからです。
こうなると、BotなどにBasic認証へのbrute force攻撃を許すことになってしまいます。

ちなみに、同じ問題は Nginx でも発生することを過去に紹介しています。

現在のApache HTTP Server (2.4以降)の書き方

2.4のディレクティブでは、これまでの Allow fromDeny from を互換機能として分離して、 Require ディレクティブを使うように変わりました。

例えば、全てからアクセスを拒否する設定は以下のようになります。

Require all denied

逆に、全てからのアクセスを許可する設定は以下のようになります。

Require all granted

2.2互換ディレクティブにあった Order が廃止されて、直感的に denied granted で全て拒否・許可が書けるようになっています。

特定のIPアドレスからのアクセスを許可する設定は、以下のようになります。

Require ip IPアドレス

特定のホスト名からのアクセスを許可する設定は、以下のようになります。

Require host ホスト名やドメイン名

逆に拒否する場合は not を付けます。

Require not ip IPアドレス
Require not host ホスト名やドメイン名

また、Basic認証では2.2互換のディレクティブとほぼ同じになりますが、 Satisfy any が不要となります。

AuthType Basic
AuthName "ENTER YOUR NAME & PASSWORD TO LOGIN"
AuthUserFile /home/kusanagi/.htpasswd
Require valid-user

2.2互換のディレクティブの例と同じように、ローカルホスト (127.0.0.1) のアクセスは許可して、他のアクセスはBasic認証を必須とする場合は以下のようになります。

Require ip 127.0.0.1

AuthType Basic
AuthName "ENTER YOUR NAME & PASSWORD TO LOGIN"
AuthUserFile /home/kusanagi/.htpasswd
Require valid-user

2.2互換のディレクティブの問題の解決

2.2互換のディレクティブにあった Satisfy any の問題を2.4のディレクティブでは解決しています。

2.4では <RequireAll> <RequireAny> が追加されています。デフォルトでは <RequireAny> が適用されますので、先程の例は厳密には以下と等価です。

<RequireAny>
Require ip 127.0.0.1

AuthType Basic
AuthName "ENTER YOUR NAME & PASSWORD TO LOGIN"
AuthUserFile /home/kusanagi/.htpasswd
Require valid-user
</RequireAny>

例えばあるIPアドレスからアクセスを拒否した上で、Basic認証を設定する場合は以下のようになります。

<RequireAll>
Require not ip アクセス拒否するIPアドレス

AuthType Basic
AuthName "ENTER YOUR NAME & PASSWORD TO LOGIN"
AuthUserFile /home/kusanagi/.htpasswd
Require valid-user
</RequireAll>

まとめ

Apache HTTP Serverは歴史が長く、特に2.2互換のディレクティブについては1.xの頃からある記述方法です。
歴史が長いということはHow-Toやドキュメントも豊富ということであり、未だに使っている人も多いのは事実です。

互換性を維持した記述が使えることはよいことですが、逆に新しい機能を使うことができない、ということでもあります。
これを機会に2.4のディレクティブを使い始めてみるのはいかがでしょうか?

なお、ドキュメントについては残念ながら英語版しか存在しません。
日本語訳も存在はするのですが、英語版の最新に追従していないどころか古い記述が残っているため、むしろ誤った内容が記載されたまま、となっているので参照しない方がよいです。
我こそは、という方はぜひ日本語訳のアップデートに手を挙げてみるのもいかがでしょうか。

<< WordPressサイトの重要な安全機能「自動更新」は有効ですか

関連記事

Webサイト運用の課題解決事例100選 プレゼント

Webサイト運用の課題を弊社プロダクトで解決したお客様にインタビュー取材を行い、100の事例を108ページに及ぶ事例集としてまとめました。

・100事例のWebサイト運用の課題と解決手法、解決後の直接、間接的効果がわかる

・情報通信、 IT、金融、メディア、官公庁、学校などの業種ごとに事例を確認できる

・特集では1社の事例を3ページに渡り背景からシステム構成まで詳解