何となくで使ってた「.htaccess」について勉強し直す

この記事は約13分で読めます。
記事内に広告が含まれています

イメージ

こんにちは、さち です。

先日、prepreset GENERATOR でエラーが出るとコメントを頂き、修正をしていました。

原因は CGI が正常動作していないことだったんですが、その原因の根源は「.htaccess」ファイルにありました。

ただ、これまで「.htaccess」については、あまり勉強せずその場しのぎで来てしまっていたので、簡単な修正にも関わらず手間取ってしまいました…。

今回は、反省の意味を込めて、「.htaccess」の記述方法の基礎をまとめていきます。

スポンサーリンク

基礎知識

「.htaccess」ファイルとは

サイトの表示,動作を設定するためのファイルで、「ドット エイチ ティー アクセス」と読みます。サーバーがこのファイルを読み取ることでサイトの制御を行います。

中身は単なるテキストなので「メモ帳」でも作成できます。

もともとはウェブサーバーソフト「Apache」用のファイルでしたが、現在はサーバーの動作を制御するファイルとしてデファクトスタンダード(事実上の標準仕様)になっています。

使用の可否

サーバーを動かすソフトウェアが「Apache」「LiteSpeed」の場合は、「.htaccess」を使用できます。

「nginex」の場合は「.htaccess」を使えませんが、「Apache」も併用して「.htaccess」が使えるようになっている事が多いです。

一部のレンタルサーバーでは、ソフトウェアが対応していても「.htaccess」ファイルの設置を許可していない場合があります。その場合、サーバーに「.htaccess」を設置しても機能しません。

適用範囲

「.htaccess」の内容は設置したディレクトリ以下で有効です。

例えば、「http://example.com/sample/」に設置した場合
である「http://example.com/sample/test/」にも有効ですが
である「http://example.com/」には効果がありません

複数設置した場合

「.htaccess」が複数ある場合すべて有効になります。

例えば、「http://example.com/」と
である「http://example.com/sample/」に設置した場合
である「http://example.com/sample/」では、2つの「.htaccess」両方の内容が適用されます。

両方に同じ種類の設定がある場合は子の方が優先されます。

記述したら必ず改行

設定内容を記述した行は、最後に改行を入れないと正常動作しない場合があります。

つまり、最終行は空っぽの行で終わらせましょう

改行コードは「LF」で

サーバーの OS は基本的に Linux 系が多いので、「改行コード」もそれ合わせて「LF」形式を使います。

Windows の「メモ帳」などで作ると、「CRLF」形式になってしまうことがあります。この場合、「.htaccess」の記述内容が正しくても、上手く動かないことがあります。

最近は、サーバーにアップロードする時に、「改行コード」を自動で変換してくれることが多いですが、気を付けてください。

改行コード 表 CR LF

パーミッション

「.htaccess」ファイルのパーミッションは、通常の静的ファイルと同じく「644」にします。共用サーバー(他のユーザーと共同利用する)の場合は「604」の方がよいです。

Windows の仕様

Windows はファイル名を拡張子だけにできないので、直接「.htaccess」というファイルを作ることはできません。

一旦、ファイル名を「.htaccess.txt」などにしておき、サーバーにアップロードした後、FTPソフト等で「.htaccess」へ変更します。

【追記】
最新版の Windows「10」「11」ではファイル名を拡張子だけにできます

正規表現

「.htaccess」ファイルでは、ファイル名・URL などを指定する時に、「正規表現」を使えることがあります。

非常に便利なので、よく分からない場合は、ぜひ記述方法を覚えてみて下さい。

「正規表現」の勉強のために「メタ文字」をまとめてみた

使い方(記述例)

「.htaccess」の使い方(記述例)について見ていきます。

コメントアウト

行頭に # を書くと、その行の内容はコメントと見なされます。

# コメントアウト

行の途中に # を使うこともできますが、サーバー環境によっては不具合が出る可能性があるので非推奨です。

ファイル一覧の表示/非表示

操作画面

「index.html」などが無いディレクトリに直接アクセスした場合、そのディレクトリにあるファイル一覧を表示するかどうか。

# 表示する
Options Indexes

# 表示しない
Options -Indexes

特に理由がない限り、セキュリティ面から「表示しない」にするのが無難です。

サーバーによっては、初期設定で「表示しない」になっていることもあり、その場合「.htaccess」で設定をしなくても表示されません。

「http」のアクセスを「https」にする

「http://example.com」にアクセスがあった場合に、強制的に「https://example.com」にします。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^.*$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

やっていることとしては、「HTTPS がオフなら https にリダイレクトする」です。

リダイレクトには、サーバー機能(モジュール)の「mod_rewrite」を使います。そのため、<IfModule mod_rewrite.c> で「mod_rewrite」が使用可能かを確認して、使用可能なら <IfModule> タグの中身を実行します。(有料レンタルサーバーなら大体使える)

RewriteCond でアクセスが「条件」に当てはまるかを確認し、当てはまれば RewriteRule を「実行」します。

今回の場合、条件である RewriteCond は、%{HTTPS} off で「HTTPS がオフの時」という意味。

実行内容である RewriteRule は、^.*$ が「"アクセスURL"を」という意味、https://%{HTTP_HOST}%{REQUEST_URI} が「"httpsにしたURL"に」という意味、[R=301,L] が「リダイレクトする」という意味です。

「www」の有無を統一する

「www」なしに統一する

「https://www.example.com」にアクセスがあった場合に、強制的に「https://example.com」にします。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$
RewriteRule ^.*$ https://%1%{REQUEST_URI} [R=301,L]
</IfModule>

条件である RewriteCond は、%{HTTP_HOST} ^www\.(.*)$ で「ホスト名が www. で始まる時」という意味。

実行内容である RewriteRule は、^.*$ が「"アクセスURL"を」という意味、https://%1%{REQUEST_URI} が「"www.を消したURL"に」という意味、[R=301,L] が「リダイレクトする」という意味です。

「www」ありに統一する

逆に、「https://example.com」にアクセスがあった場合に、強制的に「https://www.example.com」にします。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^.*$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

条件である RewriteCond は、%{HTTP_HOST} !^www\. で「ホスト名が www. で始まらない時」という意味。

実行内容である RewriteRule は、^.*$ が「"アクセスURL"を」という意味、https://www.%{HTTP_HOST}%{REQUEST_URI} が「"www.を付けたURL"に」という意味、[R=301,L] が「リダイレクトする」という意味です。

URL に「index.html」を表示しない

URL の表示に「index.html」「index.php」などを表示しないように統一します。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^(.*/)index\.(?!js|css)[^./]*$
RewriteRule ^.*$ https://%{HTTP_HOST}%1 [R=301,L]
</IfModule>

条件である RewriteCond は、アクセスURL に「index」というファイル名で拡張子が「js」「css」以外の時という意味。(「js」「css」を除外するのは、JavaScript, CSS の読み込みを妨げないようにするため)

実行内容である RewriteRule は、「index.xxx」というファイル名を削除した URL にリダイレクトするという意味です。

ファイルへのアクセスを制限する

完全にアクセス不可にする

特定のファイルを、外部から完全に見えないようにします。

# sample.html をアクセス不可にする
<Files "sample.html">
  Require all denied
</Files>

セキュリティの脆弱性となり得るファイルや、サーバー上でしか使わないファイルを非公開にするときなどに使います。

特定の IPアドレス 以外アクセス不可にする

特定の IPアドレス 以外、ファイルにアクセスできないようにします。

# 192.0.2.0~192.0.2.255 の人は sample.html にアクセスできる
<Files "sample.html">
  <RequireAll>
    Require all denied
    Require ip 192.0.2.0/24
  </RequireAll>
</Files>

<Files ""> の代わりに <FilesMatch ""> にすると、ファイル指定の記述に「正規表現」を使えます。

アクセス制限の詳しい方法は、こちらの記事で書いているので、併せて読んでみて下さい。

サーバー上の「ファイル」「ディレクトリ」へのアクセスを制限する

アクセスすべてに「404エラー」を返す

アクセス拒否だけなら、パーミッションを変えて「403(アクセス禁止)」でも良いんですが、そこにディレクトリやファイルがあることはバレてしまいます。「404」にすることで存在ごと隠せます。

アクセスがあった場合に、強制的に「404エラー」を返します。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^.*$ - [R=404,L]
</IfModule>

やっていることとしては、「すべてのアクセスを、404にリダイレクトする」です。

実行内容である RewriteRule は、^.*$ が「"アクセスURL"を」という意味、- が「何もせずに」という意味、[R=404,L] が「404 Not Found にする」という意味です。

自分のサイト(example.com)を介さず、ファイルに直接アクセス(直リンク)された場合は、アクセスを拒否します。

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^(https?://)?([^./?]+\.)?example\.com
RewriteRule ^.*$ - [R=403,L]
</IfModule>

やっていることとしては、「リファラ(参照元)のメインドメインが example.com 以外の場合は 403 Forbidden にする」です。

条件である RewriteCond は、%{HTTP_REFERER} が移動前のページ URL を表していて、!^(https?://)?([^./?]+\.)?example\.com が「URL のドメインが example.com でない時」という意味。

実行内容である RewriteRule は、「403 Forbidden にする」という意味です。仕組みとしては、前述の「404エラーにする」と同じです。

前述の「ファイルへのアクセスを制限する」と併用すれば、特定のファイルだけ直リンクを拒否できます。

「エラー」は専用ページを表示

操作画面

存在しないページにアクセスした時に出るエラー「404 Not Found」などに、自作した代替ページ(error.html)を表示します。

# 404エラーの時は「error.html」を表示
ErrorDocument 404 /error.html

代替ページの場所は、必ず相対パスで指定して下さい。絶対パスにすると、URL が書き換わってしまいます。

# 専用ページを「http://example.com/dir/error.html」に設置した場合
ErrorDocument 404 /dir/error.html

# URLが書き換わってしまうので絶対パスはダメ
ErrorDocument 404 http://example.com/error.html

404 の部分を 403 500 など別の数字にすれば、他のエラーについても専用ページを表示できます。

CGIを使う

拡張子「.cgi」のファイルをCGIとして動かします。

# 拡張子「.cgi」のファイルをCGIとして認識させる
AddHandler application/x-httpd-cgi .cgi

# サーバによっては「AddType」を使う場合も
AddType application/x-httpd-cgi .cgi

記述内容としては、拡張子「.xxx」のファイルを「○○○」として認識させるという指示です。

SSI を使う拡張子を指定する場合も同様の方法で記述します。

# 拡張子「.shtml」「.html」で SSI を使う
AddHandler text/x-server-parsed-html .shtml .html

レンタルサーバーによって記述方法が異なることがあるので、サーバー会社が開示している情報に従って記述しましょう。

初期表示ページを変更

ファイルを指定せず「ディレクトリ」にアクセスした場合に、初期表示するページは「index.html」ですが、「index.php」に変更します。

# 初期表示ページを「index.php」に変更
DirectoryIndex index.php

#「index.php」が無いときは「index.html」を表示
DirectoryIndex index.php index.html

常に動的ページを表示したい場合などに使うと便利です。

最近は、この設定をしなくても、index.html がない時は自動的に index.php を表示してくれることが多いです。

アクセス制限(Basic認証)

操作画面

ID と パスワード を入力しないとページを表示できないようにします。ただし、セキュリティが激甘なので重要なことに使ってはいけません。あくまで簡易的な認証として割り切って使って下さい。

# Basic認証の使用宣言
AuthType Basic

# アクセス時のダイアログに表示される領域名(何でも良い)
AuthName "sachi-web.com"

#「.htpasswd」が存在する絶対パス(相対パスはダメ)
# URLではなくサーバ内のパスなので注意
AuthUserFile /home/xxxxx/.htpasswd

# 認証したユーザは誰でもアクセスOKという意味の記述
require valid-user

# 外部から「.htaccess」「.htpasswd」が見えないようにする
<Files ".ht*">
deny from all
</Files>

「.htpasswd」には、Basic認証に使う「ID」と「暗号化したパスワード」を記述します。パスワードの暗号化する方法については検索すればすぐに出てきます。(レンタルサーバーが暗号化ツールを公式提供している場合もあり)

改行すると複数の ID と パスワード を記述できます。

id1:passward1
id2:passward2
id3:passward3

詳細は下記の記事を読んでみて下さい。

→ 「Basic認証」用の「.htaccess」ファイルを作成する

コメント

  1. CodeByDeer より:

    Windowsでも名前なし拡張子だけのファイルは作れますよ!!

    • 昔はできなかったのですが、Windows 10, 11 ではできるようになりましたね。
      追記させて頂きました。コメントありがとうございました。

タイトルとURLをコピーしました