.htaccess解説ツール
ファイルを貼り付けると、各行に「何をしているか」の一文が付きます。リライトのパターンは部品ごとに分解し、既知の感染パターンに一致するルールには、よく確認するよう印を付けます。
フォルダーに置く設定ファイル
ウェブサーバーには、管理者しか編集できないメインの設定ファイルがあります。共用サーバーでは管理者はあなたではないので、Apacheは別の入口を用意しています。それが.htaccessという名前のただのテキストファイルで、サイトのフォルダーに置くと、その指示はそのフォルダーと配下のすべてに適用されます。LiteSpeedサーバーも同じファイルを読みます。nginxは読まず、完全に無視します。
サーバーはリクエストのたびにファイルを読み直すので、変更は保存した瞬間に反映されます。間違いも同じです。ディレクティブ名を1つ書き間違えるだけで、その行を直すまで全ページが500エラーを返します。編集の前には毎回コピーを取っておきましょう。
書いているのがあなただけということはまずありません。WordPressは# BEGIN WordPressと# END WordPressの間にブロックを書き込み、キャッシュ、セキュリティ、画像系のプラグインもそれぞれ印付きのブロックを追加します。解説ツールはWP Rocket、LiteSpeed Cache、Wordfence、Really Simple SSLなど約25種類の目印を認識し、各ブロックの持ち主を表示します。
リライトルールを声に出して読む
多くの人がつまずくのがmod_rewriteです。次の2行を見てみましょう。
RewriteCond %{HTTP_HOST} ^shop\.example\.com$ [NC]
RewriteRule ^products/(\d+)$ https://www.example.com/item?id=$1 [R=301,L]これは1つの文として読めます。「要求されたホストが(大文字小文字を問わず)shop.example.comで、パスがproducts/の後に数字が続く形なら、その数字をidとして新しいアドレスへ訪問者を恒久的に転送し、処理を終える。」
RewriteCondはサーバー変数に対する条件です。直後のRewriteRuleにだけ適用されます。複数並んでいる場合は、どれかが[OR]で終わっていない限り、すべてが真である必要があります。RewriteRuleの最初の部分は、パスに対して照合される正規表現です。括弧で囲んだ部分が取り出され、転送先で$1、$2として再利用できます。%1は直前の条件で取り出した部分を再利用します。
| フラグ | 効果 |
|---|---|
L | この回の処理で最後のルール。ENDなら完全に止まります。 |
R=301 | リダイレクトで応答します。301は恒久的、302は一時的。Rがなければ内部での書き換えになり、訪問者のアドレスバーは変わりません。 |
NC | 大文字と小文字を区別しません。 |
QSA | 元のクエリ文字列を残し、後ろに付け加えます。 |
F、G | 403で拒否するか、410 Goneを返します。 |
P | プロキシ:別のサーバーから内容を取得し、自分のものとして返します。 |
印が付くもの
サイトへの書き込み権限を得た攻撃者は、よく.htaccessを狙います。数行書くだけで訪問者を転送したり、隠したスクリプトにアクセスできる状態を保ったりできるからです。解説ツールは各行を実際の感染で見られたパターンと比べ、2種類のラベルのどちらかを付けます。
疑わしい(赤で表示):
- 検索エンジンから来た訪問者だけ、またはスマートフォンだけに適用される、別ドメインへのリダイレクト。パソコンでアドレスを直接入力する持ち主には見えません。
- 検索エンジンのクローラーにだけ別のPHPスクリプトを返す設定。
- 画像やテキストファイルをPHPとして、または普通のファイルをCGIスクリプトとして実行させる
AddHandler、AddType、SetHandler。 - すべてのスクリプトの前後にファイルを読み込ませる
php_value auto_prepend_fileやauto_append_file、そしてallow_url_include。 .php、.py、.exeをすべて拒否するFilesMatchブロックの後に、WordPressに含まれていない少数のPHPファイルだけを許可するブロックが続くもの。
要確認(オレンジで表示):WordPressブロック内にある標準ルール以外の行、クローラーや参照元だけを対象にした条件、[P]フラグ、別ドメインに置かれたエラーページ、有効にされたディレクトリ一覧表示、訪問者に表示されるPHPエラー、無効化されたアプリケーションファイアウォール、400文字を超える行やbase64・エンコード文字だらけの行、そして目に見えない文字。
構造上のエラーも2つ報告します。どちらも500エラーの原因になります。閉じられていない<IfModule>などのブロックと、DocumentRootや<VirtualHost>のようにメインのサーバー設定でしか使えないディレクティブです。
解説ツールはテキストを読むだけです。ルールを実行するわけではなく、サーバーにどのモジュールが読み込まれているかもわかりません。親フォルダーにある別の.htaccessやメインの設定も見えません。どれも結果を左右します。印は「誰がこれを追加したか調べてください」という意味で、正規のプラグインでも時々引っかかります。印のないファイルだからといって、サイトがきれいだという証明にはなりません。
自分で書いていない行に印が付いたら
- 何かに触る前に、証拠としてファイルのコピーをダウンロードします。
- ファイルの更新日時を確認し、同じ時刻に変更された他のファイルを探します。特にアップロード用フォルダー内のPHPファイルと、印の付いたルールに出てくるファイル名です。
- 悪意のある行を削除し、数分後にファイルを読み込み直します。行が戻っていたら、サーバー上のスクリプトが書き換えているので、行を消すだけでは足りません。
- サーバー、FTPまたはSSH、データベース、CMS管理者のパスワードを変更し、CMSをプラグインやテーマも含めてすべて更新します。
- 危険サイト照会でサイトがすでにブラウザーのブロックリストに載っていないか確認し、リダイレクト追跡で訪問者が正しい場所にたどり着くか確かめます。
よくある質問
.htaccessファイルはどこにありますか?
サイトの最上位のフォルダーです。public_html、httpdocs、wwwといった名前がよく使われます。サブフォルダーに独自のものがあることもあります。ドットで始まる名前は初期状態では隠れているので、サーバーのファイルマネージャーやFTPソフトで「隠しファイルを表示」をオンにしてください。
.htaccessを編集したらサイトが500エラーになるのはなぜですか?
Apacheは解釈できない最初の行で止まります。たいていはディレクティブ名の打ち間違い、開いたまま閉じていないブロック、サーバー会社が.htaccessで許可していないディレクティブ、インストールされていないモジュールのどれかです。コピーを元に戻し、変更を1つずつ加え直してください。
RewriteRuleの[L,R=301]はどういう意味ですか?
R=301はブラウザーに新しいアドレスへ移動し、恒久的なものとして覚えるよう伝えます。Lはこのリクエストにそれ以上リライトルールを適用しないようサーバーに指示します。組み合わせると、標準的な恒久リダイレクトになります。
.htaccessファイルが改ざんされたかどうかはどうすればわかりますか?
自分で追加していないルールを探します。見知らぬドメインへのリダイレクト、HTTP_REFERERやHTTP_USER_AGENTに対する条件、画像をPHPとして実行するハンドラー、auto_prepend_fileなどです。WordPressブロックは初期状態のものと比べてください。このページはそうしたパターンに自動で印を付けます。
.htaccessはnginxでも使えますか?
いいえ。nginxにはフォルダーごとの設定ファイルがありません。サーバーの管理者がルールをnginx自身の設定に書き換える必要があります。Apacheの前段にnginxを置いているサーバー会社もあり、その場合はApacheまで届いたリクエストに対して.htaccessが引き続き適用されます。
貼り付けたファイルはサーバーに送られますか?
いいえ。解析はブラウザー内で動くスクリプトで行います。それでも、ウェブページに何かを貼り付けるときは、パスワードや秘密鍵を取り除く習慣をつけておきましょう。