htmlcss .htaccess ファイルのメモ

2013年6月17日

.htaccess ファイルについてのメモ。

目次

基本的事項

ウェブサーバとして「Apache」が使用されていて、サーバ管理者が「.htaccess」ファイルの設置を許可していれば使用可能。

.htaccess ファイルは、サーバの挙動を決定する設定ファイルのひとつ

  • ウェブサーバの設定は httpd.conf ファイルに記述するが、サーバ管理者しか編集できない。
  • .htaccess ファイルは各ユーザが、各ディレクトリ単位で設定できる。
  • .htaccess ファイルを設置したディレクトリとその配下にある全てのディレクトリに適用される。
  • 最後の行を1行空白の行にして記述する。
  • コメントは、行頭に「#」をつける。
  • 行の途中よりコメントアウトする場合はダブルクォートで囲む。”# comment”
  • .htaccess ファイルに文法誤りがあると、そのディレクトリ以下のファイルにアクセスしようとすると、500 Internal Server Error が発生する。

参考:

セキュリティ上の記述

ディレクトリの一覧を表示しない

ファイル一覧機能を無効にする。

#ディレクトリの参照を防止
Options -Indexes

レンタルサーバによっては上記の記述をするとエラーになる(Options が使えない)場合がある。その場合は以下のように記述すると、ファイルの一覧機能は有効なままだがディレクトリの一覧は表示させないようにできる。

#ディレクトリの一覧を表示しない
IndexIgnore *

またはディレクトリにインデックスファイルがない場合はディレクトリの一覧ではなく任意のエラーメッセージを表示するように設定。

以下のようなエラーメッセージのファイル(errmsg.html:ファイル名と内容は任意)を作成して、ルートディレクトリに配置。

もし画像やリンクなどを記述する場合は、絶対パスで記述(どの階層で呼び出されるかわからないため)。

errmsg.html

<html>
<head>
<title>Forbidden - ページを表示できません -</title>
</head>
<body>
<h2>Forbidden - ページを表示できません -</h2>

<p>ファイル名を指定して接続してください。</p>

<p>You don't have permission to access the requested resource. Please specify the page.</p>

</body>
</html>

.htaccess ファイルに以下を記述してインデックスファイルがない場合はエラーメッセージを表示するように設定。

配置する場所は、エラーメッセージを表示するようにしたいディレクトリ等。

DirectoryIndex index.html /errmsg.html

特定のファイルへのアクセスを拒否

以下は自分の IP(123.456.789.012) 以外からの phpinfo.php へのアクセスを拒否する例。

<Files phpinfo.php>
  Order Deny,Allow
  Deny from all
  Allow from 123.456.789.012
</Files>

全てのアクセスを拒否

CGI プログラムのみが利用するディレクトリ等では、HTTP 経由でのアクセスは必要ないので、全てのアクセスを拒否するように設定(この場合、許可と拒否の順番を設定する「order deny,allow」は省略可能)

# 全てのアクセスを拒否
order deny,allow
deny from all

クエリの内容によりブロック

クエリの内容によりブロックする。(どれだけの効果があるかは不明)

# 以下のような場合アクセスをブロックする
Options +FollowSymLinks
RewriteEngine On
# proc/self/environ(ディレクトリトラバーサル?)がクエリ(URL)に含まれる場合
RewriteCond %{QUERY_STRING} proc/self/environ [OR]
# mosConfig に関連するもの(Joomla を使用している場合かな?)
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
# base64_encode に関連するもの
RewriteCond %{QUERY_STRING} base64_encode.*(.*) [OR]
# <script> タグ
RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
# PHP グローバルに関連するもの
RewriteCond %{QUERY_STRING} GLOBALS(=|[|\%[0-9A-Z]{0,2}) [OR]
# _REQUEST を変更しようとするもの
RewriteCond %{QUERY_STRING} _REQUEST(=|[|\%[0-9A-Z]{0,2})
# 403 Forbidden error で index.php へ [F]:マッチしたURLへのアクセスを禁止 [L] :条件にマッチした場合終了
RewriteRule ^(.*)$ index.php [F,L]
# または 403 server responseを返す
# RewriteRule ^(.*)$ - [F,L]

参考サイト:17 Useful Htaccess Tricks and Tips

これらのことは「mod_security」が有効になっていれば大丈夫という説もあるが不明。「mod_security」は「enabled」にしておく。

以下のサイトにもセキュリティ関連の記述あり(未検証:そのまま記述しただけでは環境により不具合がでる可能性あり)。
Perishable Press/5G Blacklist 2013

「www あり」「www なし」の統一

「www なし」でアクセスがあったら、「www あり」に 301 リダイレクトさせる。

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(example¥.com)(:80)? [NC]
RewriteRule ^(.*) http://www.example.com/$1 [R=301,L]

参考:「www の有無

トップページのURLを「/index.html」から「/」に変更(統一)

http://xxxx.com/index.html を http://www.xxxx.com/ にリダイレクト。
(「/index.html」でアクセスがあったら、「/」に 301 リダイレクトさせる )

RewriteRule ^index.html$ http://www.xxxx.com/ [R=301,L]

参考:「ApacheウェブサーバーのRewrite設定で使える正規表現サンプル集

www.xxxx.com 内のすべてのディレクトリで、常に index.html 無しでアクセスされるように(URL を統一:正規化)するには、以下のようにする。

Options +FollowSymLinks
RewriteEngine on
RewriteCond %{THE_REQUEST} ^.*/index.html
RewriteRule ^(.*)index.html$ http://www.xxxx.com/$1 [R=301,L]

リダイレクト

リニューアルやサイト構造を変更して URL が変更になった場合などでは以下のように記述。

Redirect permanent /e-about.htm http://www.mysite.com/en/about/about.html
  • サイト全体を別ドメインにリダイレクトする
    Redirect permanent / http://新しいドメイン/
  • 1つのファイルを別ドメインにリダイレクトする
    Redirect permanent /ディレクトリ名/ファイル名 http://新ドメイン/
  • リダイレクト先は相対パスではなく、絶対URLで記述する。
  • Apache モジュール mod_alias のRedirect ディレクティブ」参照

.htaccess が使えない場合

使用しているサーバー環境により.htaccess の設定ができない場合の例。

「rel=”canonical”」と「meta refresh」を使う方法。

rel=”canonical”(URL 正規化タグ)

<link rel="canonical" href="http://exampl.com/" />
  • このタグは、検索エンジンに対し、そのページを「http://exampl.com」という URL のコピーとして扱うように(このページの元になってるページの URL は「http://exampl.com」)ということを伝えるものとのこと(正規 URL を使用する
  • HTML の head 要素内に配置する

meta refresh

<meta http-equiv="refresh" content="秒数;URL=URL">
  • meta 要素の http-equiv 属性に”refresh” を設定することにより、リダイレクト(転送)を指定することができる
  • content 属性で指定した秒数後に、指定した URL へジャンプする
  • content 属性で指定する秒数を0秒にすると、スパム扱いされることもある(真偽不明)

「http://exampl.com/」にリダイレクトするには、これらの2つを head 内に記述する。

<meta http-equiv="refresh" content="0;URL=http://exampl.com/" />
<link rel="canonical" href="http://exampl.com/" />

上記の例では meta 要素の content 属性で指定する秒数を0秒に指定してあるのでそのページにアクセスするとすぐに指定された URL にリダイレクトされる。

または、0秒ではなく5秒後くらいの待機時間を設定して、元のページには移転先のページへ訪れるような説明と移転先へのリンクも用意しておく。

ファイルを gzip 圧縮して .htaccess で圧縮ファイルを読み込む指定をする

JavaScript と CSS は可能であれば圧縮されたファイルを使うように指定する例。

RewriteEngine On   "# 書き換えエンジンを有効に"
RewriteCond %{HTTP:Accept-Encoding} gzip  "# gzipが許容されていれば"
RewriteCond %{REQUEST_FILENAME} !\.gz$  "# 拡張子が「.gz」でなければ次へ"
RewriteCond %{REQUEST_FILENAME}\.gz -s  "# 元のファイルの末尾に「.gz」を付与したファイルが存在すれば次へ"
RewriteCond %{REQUEST_FILENAME} \.js$ [OR]  "# JavaScript ファイルまたは"
RewriteCond %{REQUEST_FILENAME} \.css$  "# CSS ファイルの場合"
RewriteRule .+ %{REQUEST_URI}.gz  "# URIの末尾に「.gz」を付与"

<FilesMatch "\.js\.gz$">  "# FileMatchでファイル毎に MIME-TYPE と gz エンコードを指定"
    ForceType application/x-javascript
    AddEncoding x-gzip .gz  
</FilesMatch>

<FilesMatch "\.css\.gz$">
    ForceType text/css
    AddEncoding x-gzip .gz
</FilesMatch>

mod_deflate の利用

サーバーが「mod_deflate」をサポートしていて、text, html, xml, css, javascript を圧縮して転送する場合の例。

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/text text/html text/plain text/xml text/css application/x-javascript application/javascript
</IfModule>

キャッシュの設定

サーバーが「mod_expires」をサポートしていれば、有効にして画像ファイルや CSS などの静的ファイルをブラウザにキャッシュさせるように以下を記述する。キャッシュの有効期間はサイトの運用に合わせて変更する。

<ifModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 30 minutes"
ExpiresByType text/html "access plus 10 seconds"
ExpiresByType image/jpg "access plus 7 days"
ExpiresByType image/jpeg "access plus 7 days"
ExpiresByType image/gif "access plus 7 days"
ExpiresByType image/png "access plus 7 days"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 month"
</ifModule>

ユーザーの言語環境によって自動的に日本語または英語のサイトを表示する

ルートディレクトリに index.html(英語) の内容をコピーした「index.html.en」と indexJp.html(日本語) の内容をコピーした「index.html.ja」を配置してある場合、以下を記述。

Options +MultiViews
AddLanguage ja .ja
AddLanguage ja-jp .ja
AddLanguage ja-jp-mac .ja
AddLanguage en-us .en
AddLanguage en .en
LanguagePriority en ja
ForceLanguagePriority Prefer
ForceLanguagePriority Fallback
DirectoryIndex index
DefaultLanguage en

404 Not Foundエラーメッセージを、独自のエラーページに置き換える

エラーの種類
404 Not Found:存在しないページをブラウザで表示
401 Authorization Required:ユーザ認証に失敗
500 Internal Server Error:CGI の実行に失敗等

  • 404 ページを作成。ファイル名は任意。この例では 「404.html」
  • 「404.html」をアップロード
  • htaccess を編集
ErrorDocument 404 /404.html

401 や 500 を追加する場合

ErrorDocument 401 /401.html
ErrorDocument 500 /500.html

関連ページ:404 ページの作成

どのURLにアクセスしても「現在メインテナンス中です」というページを表示する

ErrorDocument 503 /maintenance.html

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_URI} !=/maintenance.html
  RewriteCond %{REMOTE_ADDR} !=xxx.xxx.xxx.xxx
  RewriteRule ^.*$ - [R=503,L]
</IfModule>

<IfModule mod_headers.c>
  Header set Retry-After "Sun, 15 Jun 2013 6:00:00 GMT"
</IfModule>

Webサイトのメンテナンス中画面を出す方法

WordPress の場合のセキュリティの追加

wp-config.php, wp-mail.php, install.php へのアクセスを拒否。

<FilesMatch "^(wp-config\.php|wp-mail\.php|install\.php|\.ht)">
order allow,deny
deny from all
</FilesMatch>

ログインにベーシック認証を使用する場合

以下を .htaccess に記述し、.htpasswd (パスワード)ファイルを作成する。

# wp-login.php にベーシック認証を設定
<files wp-login.php>
# 認証をかける領域名の指定。 ダイアログに表示される(任意の)文字列を指定。
AuthName "Login Password Required"    
AuthType Basic
# パスワードファイルの指定(下記の注意参照)
AuthUserFile /home/xxxxx/.htpasswd 
require valid-user
</files>
# 「.htaccess」や「.htpasswd」へのアクセスを拒否
<Files ~ "^.(htpasswd|htaccess)$">
deny from all  
</Files>

関連ページ