Ubuntu22.04でApache用にmod rewriteを使用してURLを書き換える方法
著者は、 Diversity in Tech Fund を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。
序章
Apacheのmod_rewriteモジュールを使用すると、URLをよりクリーンに書き換えて、人間が読める形式のパスをコードに適したクエリ文字列に変換できます。 また、条件に基づいてURLを書き換えることもできます。
.htaccessファイルを使用すると、サーバー構成ファイルにアクセスせずに、書き換えルールを作成して適用できます。 .htaccessファイルをWebサイトのルートに配置することにより、サイトごとまたはディレクトリごとに書き換えを管理できます。
このチュートリアルでは、mod_rewriteを有効にし、.htaccessファイルを使用して基本的なURLリダイレクトを作成してから、いくつかの高度なユースケースを検討します。
前提条件
このチュートリアルに従うには、次のものが必要です。
- 1台のUbuntu22.04サーバーは、 Ubuntu 22.04初期サーバーセットアップガイドに従ってセットアップされます。これには、sudo非rootユーザーとファイアウォールが含まれます。
- Ubuntu 22.04 にLinux、Apache、MySQL、PHP(LAMP)スタックをインストールする方法のステップ1に従ってインストールされたApache。
ステップ1—mod_rewriteを有効にする
Apacheが書き換えルールを理解するには、最初にmod_rewriteをアクティブ化する必要があります。 すでにインストールされていますが、デフォルトのApacheインストールでは無効になっています。 a2enmodコマンドを使用して、モジュールを有効にします。
sudo a2enmod rewrite
これにより、モジュールがアクティブ化されるか、モジュールがすでに有効になっていることを警告します。 これらの変更を有効にするには、Apacheを再起動します。
sudo systemctl restart apache2
mod_rewriteが完全に有効になりました。 次のステップでは、リダイレクトの書き換えルールを定義するために使用する.htaccessファイルを設定します。
ステップ2—.htaccessを設定する
.htaccessファイルを使用すると、サーバー構成ファイルにアクセスせずに書き換えルールを変更できます。 このため、.htaccessはWebアプリケーションのセキュリティにとって重要です。 ファイル名の前のピリオドは、ファイルが非表示になるようにします。
注: .htaccessファイルに入れることができるルールは、サーバー構成ファイルに直接入れることもできます。 実際、公式のApacheドキュメントでは、.htaccessの代わりにサーバー構成ファイルを使用することを推奨しています。これは、Apacheがサーバー構成ファイルをより高速に処理するためです。
ただし、この単純な例では、パフォーマンスの向上はごくわずかです。 さらに、.htaccessでルールを設定すると、特に同じサーバー上に複数のWebサイトがある場合に便利です。 変更を有効にするためにサーバーを再起動する必要はなく、これらのルールを編集するためにroot権限も必要ないため、メンテナンスが簡素化され、権限のないアカウントで変更が可能になります。 WordPressやJoomlaなどの人気のあるオープンソースソフトウェアの中には、ソフトウェアが.htaccessファイルに依存して、必要に応じて追加のルールを変更および作成することがよくあります。
.htaccessファイルの使用を開始する前に、さらにいくつかの設定をセットアップして保護する必要があります。
デフォルトでは、Apacheは.htaccessファイルを使用して書き換えルールを適用することを禁止しているため、最初にファイルへの変更を許可する必要があります。 nanoまたはお好みのテキストエディタを使用して、デフォルトのApache設定ファイルを開きます。
sudo nano /etc/apache2/sites-available/000-default.conf
そのファイル内には、最初の行から始まる<VirtualHost *:80>ブロックがあります。 そのブロック内に、次の新しいブロックを追加して、構成ファイルが次のようになるようにします。 すべてのブロックが適切にインデントされていることを確認してください。
/etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
<Directory /var/www/html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
. . .
</VirtualHost>
ファイルを保存して閉じます。 これらの変更を有効にするには、Apacheを再起動します。
sudo systemctl restart apache2
次に、Webルートに.htaccessファイルを作成します。
sudo nano /var/www/html/.htaccess
新しいファイルの先頭にこの行を追加して、書き換えエンジンをアクティブにします。
/var/www/html/.htaccess
RewriteEngine on
ファイルを保存して終了します。
これで、Webアプリケーションのルーティングルールを管理するために使用できる操作可能な.htaccessファイルができました。 次のステップでは、書き換えルールのデモンストレーションに使用するサンプルWebサイトファイルを作成します。
ステップ3—URL書き換えの構成
ここでは、きれいなURLを実際のページへのパスに変換する基本的なURL書き換えを設定します。 具体的には、ユーザーにhttp://your_server_ip/aboutへのアクセスを許可しますが、about.htmlというページを表示します。
Webルートにabout.htmlという名前のファイルを作成することから始めます。
sudo nano /var/www/html/about.html
次のHTMLコードをファイルにコピーし、保存して閉じます。
/var/www/html/about.html
<html>
<head>
<title>About Us</title>
</head>
<body>
<h1>About Us</h1>
</body>
</html>
このページにはhttp://your_server_ip/about.htmlでアクセスできますが、http://your_server_ip/aboutにアクセスしようとすると、 404 NotFoundエラーが表示されることに注意してください。 代わりに/aboutを使用してページにアクセスするには、書き換えルールを作成します。
すべてのRewriteRulesは、次の形式に従います。
一般的なRewriteRule構造
RewriteRule pattern substitution [flags]
RewriteRuleはディレクティブを指定します。patternは、正規表現であり、URLから目的の文字列に一致します。これは、視聴者がブラウザに入力する文字列です。substitutionは、実際のURLへのパス、つまりファイルApacheサーバーのパスです。flagsは、ルールの動作を変更できるオプションのパラメーターです。
次に、URL書き換えルールを作成します。 .htaccessファイルを開きます。
sudo nano /var/www/html/.htaccess
最初の行の後に、強調表示されたRewriteRuleを追加し、ファイルを保存します。
/var/www/html/.htaccess
RewriteEngine on RewriteRule ^about$ about.html [NC]
この場合、^about$はパターン、about.htmlは置換、[NC]はフラグです。 この例では、特別な意味を持ついくつかの文字を使用しています。
^は、your_server_ip/の後のURLの開始を示します。$はURLの終わりを示します。aboutは文字列「about」と一致します。about.htmlは、ユーザーがアクセスする実際のファイルです。[NC]は、ルールの大文字と小文字を区別しないフラグです。
これで、ブラウザでhttp://your_server_ip/aboutにアクセスできます。 実際、上記のルールでは、次のURLはabout.htmlを指します。
http://your_server_ip/about、ルール定義のため。http://your_server_ip/About、ルールでは大文字と小文字が区別されないため。http://your_server_ip/about.html、元の適切なファイル名が常に機能するため。
ただし、以下は機能しません。
http://your_server_ip/about/は、$文字がaboutの後に表示されるため、aboutの後には何もない可能性があることをルールが明示的に示しているためです。http://your_server_ip/contact、ルールのabout文字列と一致しないため。
これで、必要に応じて変更および拡張できる基本ルールを備えた操作可能な.htaccessファイルができました。 次のセクションでは、一般的に使用されるディレクティブの2つの追加の例について説明します。
例1—RewriteRuleを使用したクエリ文字列の簡略化
Webアプリケーションは、多くの場合、アドレスの後に疑問符(?)を使用してURLに追加されるクエリ文字列を使用します。 個別のパラメーターは、アンパサンド(&)を使用して区切られます。 クエリ文字列は、個々のアプリケーションページ間で追加のデータを渡すために使用できます。
たとえば、PHPで記述された検索結果ページでは、http://example.com/results.php?item=shirt&season=summerのようなURLを使用できます。 この例では、2つの追加パラメーターが架空のresult.phpアプリケーションスクリプトに渡されます。値がshirtのitemと、値がsummer。 アプリケーションは、クエリ文字列情報を使用して、訪問者に適したページを作成できます。
Apacheの書き換えルールは、上記のような長くて不快なリンクを、視覚的に入力および解釈しやすいわかりやすいURLに単純化するためによく使用されます。 この例では、上記のリンクを単純化してhttp://example.com/shirt/summerにします。 shirtおよびsummerパラメーター値はまだアドレスにありますが、クエリ文字列とスクリプト名はありません。
これを実装するための1つのルールは次のとおりです。
単純な置換
RewriteRule ^shirt/summer$ results.php?item=shirt&season=summer [QSA]
shirt/summerは要求されたアドレスで明示的に一致し、Apacheは代わりにresults.php?item=shirt&season=summerを提供するように指示されます。
[QSA]フラグは、一般的に書き換えルールで使用されます。 提供されるURLに追加のクエリ文字列を追加するようにApacheに指示するため、訪問者がhttp://example.com/shirt/summer?page=2と入力すると、サーバーはresults.php?item=shirt&season=summer&page=2で応答します。 これがないと、追加のクエリ文字列は破棄されます。
この方法では目的の効果が得られますが、アイテム名とシーズンの両方がルールにハードコードされています。 これは、pantsのような他のアイテム、またはwinterのような季節に対してルールが機能しないことを意味します。
ルールをより一般的にするために、正規表現を使用して元のアドレスの一部を照合し、それらの部分を置換パターンで使用できます。 変更されたルールは次のようになります。
単純な置換
RewriteRule ^([A-Za-z0-9]+)/(summer|winter|fall|spring) results.php?item=$1&season=$2 [QSA]
括弧内の最初の正規表現グループは、shirtやpantsのような英数字と数字を含む文字列と一致し、一致したフラグメントを$1変数として保存します。 括弧内の2番目の正規表現グループは、summer、winter、fall、またはspringと完全に一致し、同様に一致したフラグメントを$2として保存します。 ]。
一致したフラグメントは、以前にハードコードされたshirtおよびsummer値の代わりに、itemおよびseason変数の結果のURLで使用されます。
上記は、たとえば、http://example.com/pants/summerをhttp://example.com/results.php?item=pants&season=summerに変換します。 この例は将来も保証されており、単一のルールを使用して複数のアイテムとシーズンを正しく書き換えることができます。
例2—RewriteCondsを使用してロジックで条件を追加する
書き換えルールは、必ずしも制限なく1つずつ評価されるとは限りません。 RewriteCondディレクティブを使用すると、書き換えルールに条件を追加して、ルールがいつ処理されるかを制御できます。 すべてのRewriteCondsは、次の形式に従います。
一般的なRewriteCond構造
RewriteCond TestString Condition [Flags]
RewriteCondは、RewriteCondディレクティブを指定します。TestStringは、テストする文字列です。Conditionは、一致するパターンまたは条件です。Flagsは、条件と評価ルールを変更する可能性のあるオプションのパラメーターです。
RewriteCondがtrueと評価された場合、直後のRewriteRuleが考慮されます。 そうでない場合、ルールは破棄されます。 複数のRewriteCondを次々に使用できます。デフォルトの動作では、次のルールが考慮されるためには、すべてがtrueと評価される必要があります。
例として、標準の 404 Not Found エラーページを表示する代わりに、サイト上の存在しないファイルまたはディレクトリへのすべてのリクエストをホームページにリダイレクトするとします。 これは、次の条件ルールで実現できます。
存在しないファイルおよびディレクトリへのすべてのリクエストをホームページにリダイレクトします
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . / [R=301]
上記で:
%{REQUEST_FILENAME}はチェックする文字列です。 この場合、それは要求されたファイル名であり、すべての要求に使用できるシステム変数です。-fは、要求された名前がディスク上に存在し、ファイルであるかどうかを確認する組み込み条件です。!は否定演算子です。 組み合わせると、!-fは、指定された名前が存在しないか、ファイルでない場合にのみtrueと評価されます。- 同様に、
!-dは、指定された名前が存在しないか、ディレクトリではない場合にのみtrueと評価されます。
最終行のRewriteRuleは、存在しないファイルまたはディレクトリへのリクエストに対してのみ有効になります。 RewriteRule自体は非常にシンプルです。 パターン内のドット.はすべてに一致し、置換によってすべてのリクエストが/Webサイトルートに送信されます。
さらに、[R=301]フラグは、 301 Moved Permanently リダイレクトHTTP応答コードをブラウザーに返すようにApacheに指示します。その結果、ブラウザーはリダイレクトが発生したことを認識し、要求されたURLではなくWebサイトのルートを明示的にフェッチします。 、変更はブラウザのアドレスバーに反映されます。
このフラグがないと、ApacheはWebサイトのルートコンテンツを返しますが、ブラウザは要求されたページのURLが存在すると見なし、アドレスバーに最初に要求されたアドレスを表示します。
結論
mod_rewriteを使用すると、人間が読めるURLを作成できます。 このチュートリアルでは、RewriteRuleディレクティブを使用して、クエリ文字列を含むURLをリダイレクトしました。 また、RewriteCondディレクティブを使用して条件付きでリダイレクトするURLを作成しました。
mod_rewriteの詳細については、Apacheのmod_rewriteの概要およびApacheのmod_rewriteの公式ドキュメントを参照してください。