📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

ページの作成:「== 概要 == <br><br> == Filesディレクティブ == Apache2のセキュリティを向上させる重要なツールの1つである。<br> <br> Filesディレクティブは、特定のファイルやファイルタイプに対してアクセス制御を行うために使用する。<br> 特定のファイルやファイルタイプへのアクセスを制御することにより、機密情報の保護や不正アクセスの防止に役立つ。<br> <br> *…」
 
 
(同じ利用者による、間の18版が非表示)
140行目: 140行目:
     RewriteRule ^article-([0-9]+)\.html$ article.php?id=$1 [L]
     RewriteRule ^article-([0-9]+)\.html$ article.php?id=$1 [L]
  </Directory>
  </Directory>
</syntaxhighlight>
<br><br>
== mod_rewriteモジュール ==
==== mod_rewriteモジュールとは ====
mod_rewriteモジュールは、Apache2の非常に強力で柔軟な機能の1つである。<br>
このモジュールを使用することにより、URLの書き換えやリダイレクトを動的に行うことができる。<br>
<br>
mod_rewriteモジュールは正規表現を使用して柔軟なルール設定が可能であるが、複雑な設定になりがちであり、間違った設定によるパフォーマンスへの影響も考慮する必要がある。<br>
<br>
* URL書き換え
*: 複雑なURLを簡潔で覚えやすいものに変更できる。
* リダイレクト
*: ユーザを別のURLに転送することができる。
* 条件分岐
*: 様々な条件 (ブラウザタイプ、IPアドレス等) に基づいて異なる動作を設定できる。
* セキュリティ強化
*: 特定のリソースへのアクセスを制限、または、悪意のあるリクエストをブロックすることができる。
* SEO最適化
*: 検索エンジンフレンドリーなURLを作成できる。
* レガシーURLの維持
*: サイト構造を変更しても古いURLを機能させ続けることができる。
<br>
==== RewriteEngine ====
mod_rewriteモジュールの機能を有効または無効にするための命令である。<br>
<br>
以下の例では、mod_rewriteモジュールおよび<code>RewriteRule</code>を有効にしている。<br>
<syntaxhighlight lang="apache">
RewriteEngine On
</syntaxhighlight>
<br>
==== RewriteCond ====
<code>RewriteRule</code>が適用される条件を指定する。<br>
複数のRewriteCondを指定することができる。<br>
<syntaxhighlight lang="apache">
RewriteCond <設定の種類> <パターン> [<フラグ>]
</syntaxhighlight>
<br>
<syntaxhighlight lang="apache">
# 例: HTTPホストが"www.example.com"の場合に条件が真になる
RewriteCond %{HTTP_HOST} ^www\.example\.com$
</syntaxhighlight>
<br>
複数の<code>RewriteCond</code>ディレクティブが連続して記述されている場合、それらは暗黙的にAND条件として扱われる。<br>
<syntaxhighlight lang="apache">
# 例: リモートホストに".example.com"で終わる文字列が含まれており、かつ、".osk[0-9]."という文字列が含まれていない場合はアクセスを許可
RewriteCond %{REMOTE_HOST} \.example\.com$ [NC]
RewriteCond %{REMOTE_HOST} !\.osk[0-9]\.  [NC]
RewriteRule ^ - [L]
</syntaxhighlight>
<br>
もし、OR条件にしたい場合は、<code>[OR]</code>フラグを使用して明示的に指定する必要がある。<br>
<syntaxhighlight lang="apache">
# 例: リモートホストに".example.com"で終わる文字列が含まれている場合、または、".osk[0-9]."という文字列が含まれていない場合はアクセスを許可
RewriteCond %{REMOTE_HOST} \.example\.com$ [NC,OR]
RewriteCond %{REMOTE_HOST} !\.osk[0-9]\.  [NC]
RewriteRule ^ - [L]
</syntaxhighlight>
<br>
また、OR条件の場合のみ、複数の<code>RewriteCond</code>ディレクティブを1つにまとめることが可能である。<br>
<br>
以下の例では、<code>|</code> (パイプ) を使用して、OR条件を使用している。<br>
これにより、リクエストURIに"osaka"または"osk"が含まれている場合にマッチする。<br>
<br>
<u>※注意</u><br>
<u>複数の条件を1行にまとめる場合は、OR条件 (<code>|</code>) のみが可能である。</u><br>
<u>AND条件は、複数の<code>RewriteCond</code>ディレクティブを別々の行に記述することにより表現する。</u><br>
<br>
<syntaxhighlight lang="apache">
RewriteCond %{REQUEST_URI} osaka|osk
# 3つの条件のいずれかに該当する場合にリダイレクトを行う
RewriteCond %{REQUEST_URI} Qt|QML    [NC,OR]
RewriteCond %{THE_REQUEST} \s(Qt|QML) [NC,OR]
RewriteCond %{QUERY_STRING} Qt|QML [NC]
RewriteRule ^(.*)$ </path/to/redirect> [L,R=301]
</syntaxhighlight>
<br>
1つにまとめる場合、以下に示すようなメリットがある。<br>
ただし、パフォーマンスに大きな影響を与えるものではないため、可読性を重視する場合は別々に記述しても構わない。<br>
* コードがより簡潔になる。
* パフォーマンスが若干向上する可能性がある。 (1回の条件チェックで済むため)
<br>
==== RewriteRuleディレクティブ ====
<code>RewriteCond</code>の設定を適用する。<br>
<syntaxhighlight lang="apache">
RewriteRule <パターン> <Substitution> [<フラグ>]
</syntaxhighlight>
<br>
* <code>RewriteRule ^ - [L]</code>
*: この規則は、現在のURLを変更せずにそのまま処理を続行することを表す。
*: [L]フラグは<u>Last</u>を意味しており、この規則によりRewriteエンジンの処理を停止する。
*: つまり、この規則以降の他の<code>RewriteRule</code>は適用されない。
*: <br>
* <code>RewriteRule ^ - [F,L]</code>
*: この規則も現在のURLを変更しないが、[F]フラグによりアクセスを拒否する。
*: [F]フラグは<u>Forbidden</u>を意味しており、<u>403 Forbiddenステータスコード</u>を返す。
*: [L]フラグも含まれているため、この規則により処理が停止する。
<br>
<syntaxhighlight lang="apache">
# 例 1: mineo回線のアクセスを許可する場合
RewriteCond %{REMOTE_HOST} ^[\w.-]*\.mineo\.jp$ [NC]
RewriteRule ^ - [L]
# 例 2: リモートホストに".osaka."という文字列が含まれている場合は、アクセスを拒否する場合
RewriteCond %{REMOTE_HOST} ^[\w.-]*\.osaka\.[\w.-]*$ [NC]
RewriteRule ^ - [F,L]
# 例 3: "old-page.html"へのリクエストを"/new-page.html"にリダイレクトする
RewriteRule ^old-page\.html$ /new-page.html [R=301,L]
</syntaxhighlight>
<br>
以下に示す2つの設定は、全てのリクエストに対して403 Forbiddenエラーを返す。<br>
したがって、Webサイト全体へのアクセスを禁止する設定である。<br>
* RewriteRule .* - [F,L]
* RewriteRule ^(.*)$ - [F,L]
<br>
後者のルールの方がより厳密である。<br>
正規表現である<code>^</code>および<code>$</code>を使用することにより、URLの先頭から末尾までを完全にマッチさせる。<br>
一方、前者のルールは理論的にはURLの一部分にもマッチする可能性がある。<br>
<br>
以下に示す設定は、全てのリクエストに対して403 Forbiddenエラーを返す。<br>
<u>R=403</u>とは、<u>403 Forbiddenステータスコード</u>でリダイレクトを行う設定である。<br>
* RewriteRule ^ /hoge.html [L,R=403]
<br>
==== RewriteBaseディレクティブ ====
RewriteBaseディレクティブは、mod_rewriteモジュールで使用されており、その後に続く<code>RewriteRule</code>で使用される相対URLのベースパスを設定する。<br>
RewriteBaseディレクティブが設定されていない場合は、<code>RewriteBase</code>はドキュメントルートからの相対パスとなる。<br>
<br>
RewriteBaseを適切に設定することにより、より柔軟でメンテナンスしやすいURL書き換えルールを作成することができる。<br>
<br>
サブディレクトリでの<code>RewriteRule</code>使用時において、特に重要である。<br>
.htaccessファイルを異なる階層で再利用する場合に便利である。<br>
<br>
* 機能
** 相対パスの解決
**: <code>RewriteRule</code>で相対パスを使用する際の起点を定義する。
** URLの一貫性
**: 異なるディレクトリ階層でも同じ<code>RewriteRule</code>を使用可能にする。
<br>
<syntaxhighlight lang="apache">
# 例 1: "/blog/post/123"へのリクエストは、"/blog/view.php?id=123"に内部的にリダイレクトする
RewriteBase /blog/
RewriteRule ^post/(.*)$ view.php?id=$1
# 例 2: Webサイトのルートディレクトリ (例: http://example.com/) にアクセスした場合、サーバは内部的に"index.php"にリクエストを転送する
#      WebブラウザにはURLの変更は表示されない (内部リダイレクト)
# "RewriteBase /"は、以降のRewriteRuleで使用される相対パスの基準点をサーバのドキュメントルート (/) に設定する
# つまり、全ての相対パスはサーバのルートディレクトリを起点として解釈される
# "RewriteRule ^$ index.php [L]"は、書き換えルールを定義している
# "^$": この正規表現は、空の文字列 (ディレクトリのルート) にマッチする
# "index.php": マッチした場合にリダイレクトされる先のファイル
# "[L]": "Last"の略であり、このルールが適用された場合、以降のルールは処理されない
RewriteBase /
RewriteRule ^$ index.php [L]
</syntaxhighlight>
<br>
==== 例 1 : 全てのWebサイトからのリンク経由のアクセスを許可 ====
<u>ただし、HTTPリファラーはWebブラウザによっては送信されない場合があり、また、ユーザによって改竄される可能性があることに注意する。</u><br>
<syntaxhighlight lang="apache">
# "RewriteCond %{HTTP_REFERER} ."は、HTTP_REFERERヘッダが存在して、かつ、空でない場合にマッチする (ドットは任意の1文字にマッチ)
# マッチした場合、"RewriteRule ^ - [L]"が適用されて、リクエストは変更されずに処理が終了する
# したがって、リファラーが存在する全てのリクエスト (他のWebサイトからのリンク経由のアクセス全て) が許可される
RewriteCond %{HTTP_REFERER} .
RewriteRule ^ - [L]
</syntaxhighlight>
<br>
==== 例 2 : 特定のWebサイト以外からのリンク経由のアクセスを許可 ====
<syntaxhighlight lang="apache">
# "RewriteCond %{HTTP_REFERER} !^$"は、HTTP_REFERERが空でない場合にマッチする
# "RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?example\.com [NC]"は、リファラーが指定されたドメイン (example.com) ではない場合にマッチする
# 両方の条件がマッチした場合、"RewriteRule ^ - [L]"が適用されて、リクエストは変更されずに処理が終了する
# したがって、リファラーが存在して、かつ、指定されたドメイン以外からのアクセスが全て許可される
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?example\.com [NC]
RewriteRule ^ - [L]
</syntaxhighlight>
<br>
==== 直接アクセスを拒否 ====
以下の例では、WebブラウザのURL入力やブックマークからの直接アクセスを拒否している。<br>
<syntaxhighlight lang="apache">
# リファラーが存在しない(直接アクセスの)場合にアクセスを拒否
RewriteCond %{HTTP_REFERER} ^$
RewriteRule ^ - [F,L]
</syntaxhighlight>
<br>
==== 例 3 : 特定のリモートホストのアクセスを拒否 ====
以下の例では、リモートホストに".osaka."という文字列が含まれている場合、特定のユーザエージェント以外はアクセスを拒否している。<br>
<syntaxhighlight lang="apache">
SetEnvIfNoCase User-Agent "Linux x86_64"            linux_user_agent=1
SetEnvIfNoCase User-Agent "Linux i686"              linux_user_agent=1
SetEnvIfNoCase User-Agent "Linux i686 on x86_64"    linux_user_agent=1
SetEnvIfNoCase User-Agent "Linux arm"              linux_user_agent=1
SetEnvIfNoCase User-Agent "Linux aarch64"          linux_user_agent=1
SetEnvIfNoCase User-Agent "CrOS"                    linux_user_agent=1
RewriteCond %{REMOTE_HOST} ^[\w.-]*\.osaka\.[\w.-]*$ [NC]
RewriteCond %{ENV:linux_user_agent} =1              [OR]
RewriteRule ^ - [L]
RewriteCond %{REMOTE_HOST} ^[\w.-]*\.osaka\.[\w.-]*$ [NC]
RewriteRule ^ - [F,L]
</syntaxhighlight>
<br>
==== 例 4 : 特定のリモートアドレスのアクセスを許可 ====
以下の例では、指定されたIPアドレスの範囲からのアクセスを許可している。<br>
<syntaxhighlight lang="apache">
RewriteCond %{REMOTE_ADDR} ^91\.219\.239\. [OR]
RewriteCond %{REMOTE_ADDR} ^85\.203\.39\.  [OR]
RewriteCond %{REMOTE_ADDR} ^45\.250\.255\.
RewriteRule ^ - [L]
</syntaxhighlight>
<br>
==== wgetコマンドからのアクセスを拒否 ====
wgetコマンドでダウンロードする場合、ユーザエージェントに<u>Wget</u>という文字列が含まれている。<br>
<code>RewriteRule</code>と組み合わせて使用することにより、wgetコマンドからのアクセスを拒否することができる。<br>
<syntaxhighlight lang="apache">
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTP_USER_AGENT} ^Wget [NC]
    RewriteRule .* - [F,L]
</IfModule>
</syntaxhighlight>
<br>
==== リダイレクト ====
<syntaxhighlight lang="apache">
# 例 1: リモートホストに"vpn"という文字列が含まれている場合、アクセスを拒否してhoge.htmlへリダイレクト
RewriteCond %{REMOTE_HOST} vpn [NC]
RewriteRule ^ /hoge.html [L,R=403]
# 例 2: リモートホストに"softbank"という文字列が含まれている場合、アクセスを拒否してpiyo.htmlへリダイレクト
RewriteCond %{REMOTE_HOST} softbank [NC]
RewriteRule ^ /piyo.html [L,R=403]
</syntaxhighlight>
<br>
また、HTMLファイルやPHPファイル等の後に<code>?</code>を追記することにより、元のリクエストのクエリ文字列を無視して、新しいURLにクエリ文字列が付加されない。<br>
<syntaxhighlight lang="apache">
# 例 1: リモートホストに"au-net"という文字列が含まれている場合、huga.htmlへリダイレクト
RewriteCond %{REMOTE_HOST} au-net [NC]
RewriteRule ^ /huga.html? [R=302,L]
</syntaxhighlight>
<br>
必要に応じて、301 (恒久的リダイレクト) や 302 (一時的リダイレクト) に変更することもできる。<br>
<br>
==== 全角文字の取り扱い ====
.htaccessファイルでは、以下に示す理由から、全角文字の使用は非推奨である。<br>
* エンコーディングの問題
*: .htaccessファイルは通常ASCII文字セットで保存される。
*: 全角文字を使用する場合、ファイルのエンコーディングがUTF-8等になり、サーバによっては正しく解釈されない可能性がある。
* 可読性と保守性
*: 全角文字を使用する場合、他の開発者やサーバ管理者が.htaccessファイルを読み解くのが難しくなる可能性がある。
* 互換性の問題
*: 異なるサーバ環境や設定間での互換性の問題が発生する可能性がある。
* URLエンコーディング
*: URLには通常ASCII文字のみが使用されるため、全角文字はURLエンコードされる必要がある。
<br>
そのため、以下に示すようにURLエンコードされた文字列を使用する必要がある。<br>
<syntaxhighlight lang="apache">
# "ほげ"をURLエンコードした"%E3%81%BB%E3%81%92"を使用
RewriteCond %{REQUEST_URI}  "%E3%81%BB%E3%81%92"                  [OR]
RewriteCond %{THE_REQUEST}  \s"%E3%81%BB%E3%81%92"                [OR]
RewriteCond %{QUERY_STRING} "%E3%81%BB%E3%81%92"
</syntaxhighlight>
<br>
これにより、エンコーディングの問題を回避して、より安全で互換性のある設定が可能になる。
<br>
もし全角文字の使用が絶対に必要な場合は、Apacheの設定でUTF-8エンコーディングが正しく処理されることを確認する。<br>
<br>
<u>ただし、上記の理由から、可能な限りURLエンコードされた文字列を使用することを強く推奨する。</u><br>
<br><br>
== Options -Indexes ==
<code>Options -Indexes</code>は、ディレクトリリスティング (インデックス表示) を無効にする設定である。<br>
特定のディレクトリにアクセスされた時、index.html等のデフォルトページが存在しない場合はディレクトリの内容一覧を表示せずに、"403 Forbidden"エラーが表示される。<br>
<br>
この設定は、Webサイトのセキュリティを向上させるための基本的な方策の1つとして広く推奨されている。<br>
ディレクトリの内容を意図せず公開してしまうリスクを軽減することができる。<br>
<br>
Options -Indexesが設定されていない場合は、<br>
デフォルトのインデックスファイル (例:index.html, index.php等) が存在しないディレクトリにアクセスすると、ディレクトリの内容一覧が表示される。<br>
<br>
* セキュリティ面での利点
** Webサーバ上のファイル構造や存在するファイルの一覧が公開されるのを防ぐ。
** 潜在的な脆弱性や機密情報の露出リスクを低減する。
<br>
<syntaxhighlight lang="apache">
Options -Indexes
  </syntaxhighlight>
  </syntaxhighlight>
<br><br>
<br><br>