mod_rewriteで特定のアクセスを拒否する
AWSからシステムを使ったクロールが多いので拒否することとなった。
個人的には過負荷になっているわけではないし、攻撃的なパラメータでもないのでほっといてもいいと思うが、是非拒否してほしいとの事。
下記を設定し、403エラーを返すようにした。
条件:
- *.amazonaws.comからのアクセス
- リファラがない
- Accept-Languageがen-us.*
(個人的にはAccept-Languageとか入れたくなかったが、入れて欲しいとのこと。多言語サイトでないからまぁいいのかな。)
RewriteCond %{REMOTE_HOST} "^.*\.amazonaws\.com" [NC]
RewriteCond %{HTTP_REFERER} ^$
RewriteCond %{HTTP:Accept-Language} "^en-us" [NC]
RewriteRule ^.*$ - [F,L]
RewriteCondディレクティブ
書き換えの条件を指定する。この条件に一致した場合だけ書き換えが行われる。
RewriteCond テスト文字列 条件パターン オプション
RewriteCond %{REQUEST_FILENAME} !-f
後方参照について
RewriteCondの条件パターンで「()(カッコ)」を使って一致した値は、変数を使って再利用できます。これを後方参照と言います。
RewriteCondで指定したパターンを参照する場合は「%(パーセント)」を使います。「()(カッコ)」が複数ある場合は左から%1、%2といった具合に利用することができます。
同じように、後に解説するRewriteRuleディレクティブでも後方参照を利用できます。こちらは通常の正規表現の後方参照と同じように「$(ドル)」で利用できます。
RewriteCond %{REQUEST_FILENAME} ^(.*)/(.*)/index.html$
RewriteRule ^/ex/(.*)/(.*)$ /$1/%1/$2
以上のルールが実行されると、「/hoge/ex/index.html」となります。
注意
直下のrewriteruleにしか適用されない。適用したい場合は都度かくか[C]フラグでチェインする必要あります。
RewriteCond a
RewriteCond b
RewriteRule c
RewriteRule d
上記のような場合、a && b のときcのルールが適用される。
dはaとbのcondが効かずに常に適用される。
RewriteCondに利用できる環境変数変数表
| グループ | 変数名 | 備考 |
|---|---|---|
| HTTP ヘッダ | HTTP_USER_AGENT | ユーザーエージェント |
| HTTP_REFERER | 参照元URL | |
| HTTP_COOKIE | クッキー情報 | |
| HTTP_FORWARDED | プロキシ情報 | |
| HTTP_HOST | サーバーのホスト名 | |
| HTTP_PROXY_CONNECTION | プロキシを経由しているか否か | |
| HTTP_ACCEPT | ブラウザの言語タイプ | |
| コネクション & リクエスト | REMOTE_ADDR | リモートアドレス |
| REMOTE_HOST | リモートホスト名 | |
| REMOTE_USER | リモートユーザー名 (基本認証利用時) | |
| REMOTE_IDENT | リモートユーザーのID | |
| REQUEST_METHOD | リクエストメソッド | |
| SCRIPT_FILENAME | スクリプトファイル名 | |
| PATH_INFO | パス情報 | |
| QUERY_STRING | クエリ文字列 | |
| AUTH_TYPE | 認証タイプ | |
| サーバ内部変数 | DOCUMENT_ROOT | ドキュメントルートのパス |
| SERVER_ADMIN | サーバー管理者情報 | |
| SERVER_NAME | サーバー名 | |
| SERVER_ADDR | サーバーのアドレス | |
| SERVER_PORT | サーバーのポート番号 | |
| SERVER_PROTOCOL | プロトコルバージョン | |
| SERVER_SOFTWARE | サーバーソフトウェア | |
| システム関連 | TIME_YEAR | 年 |
| TIME_MON | 月 | |
| TIME_DAY | 日 | |
| TIME_HOUR | 時 | |
| TIME_MIN | 分 | |
| TIME_SEC | 秒 | |
| TIME_WDAY | 曜日 (0:日 ~ 6:土) | |
| TIME | 年月日時分秒 (例:20130123123456) | |
| その他 | API_VERSION | APIバージョン |
| THE_REQUEST | リクエスト文字列 | |
| REQUEST_URI | リクエストURI | |
| REQUEST_FILENAME | リクエストされたファイル名 | |
| IS_SUBREQ | サブリクエストか否か | |
| HTTPS | HTTPSでのアクセスか否か |
Accept-Languageは下記のような書き方を何故かするみたいです。
HTTP:Accept-Language
RewriteCondに利用できる条件パターンの一覧
| パターン | 意味 |
|---|---|
| ! | 否定 |
| < | テスト文字列より上の場合true |
| > | テスト文字列より下の場合true |
| = | テスト文字列と等しい場合true |
| <= | テスト文字列以上の場合true |
| >= | テスト文字列以下の場合true |
| -d | (is directory)ディレクトリが存在すればtrue |
| -f | (is regular file)ファイルが存在すればtrue |
| -eq | (is numerically equal to)いわゆる「=」 |
| -ge | (is numerically greater than or equal to)いわゆる「<=」 |
| -gt | (is numerically greater than)いわゆる「<」 |
| -le | (is numerically less than or equal to)いわゆる「>=」 |
| -lt | (is numerically less than)いわゆる「>」 |
| -F | (is existing file, via subrequest)アクセス可能な有効なパスを指している場合にtrue (内部サブリクエストを用いてcheckされる) |
| -l | (is symbolic link)シンボルリンク(-H、-Lも同じ意味。ちなみに小文字エルです) |
| -s | (is regular file, with size)ファイルが存在し、サイズが0でなければtrue |
| -U | (is existing URL, via subrequest)アクセス可能な有効なURLとなっている場合にtrue |
| -x | (has executable permissions)実行権限がある場合にtrue |
RewriteCondに利用できるオプションの一覧
下記のように[]でオプションを指定できます。複数指定時はカンマ区切り
RewriteCond %{HTTP:Accept-Language} "^en-us" [NC]
| オプション | 意味 |
|---|---|
| OR | 連続した複数の条件の内、どちらかに一致した場合に実行する。指定しない場合はANDとなり、連続した全ての条件が一致した場合にだけ実行する。 |
| NC | 大文字小文字を区別しない。 |
RewriteRuleディレクティブ
書き換えのルールを決めるディレティブ。パターンで一致した値を置換文字列で書き換えます。
条件パターンはPerl互換の正規表現で指定する。
RewriteRule 条件パターン 置換文字列 [フラグ]
RewriteRuleのフラグ
一般的にはこの省略形で記載します。
| フラグ | 省略形 | 意味 |
|---|---|---|
| B | 英数字のエスケープ。いわゆるURLエンコード(&を%26など)。 | |
| chain | C | チェーン。次の処理を連続して行う場合に指定する。 |
| cookie | CO=NAME:VAL | Cookieをセットすることができる。書式:CO=NAME:VAL:domain[:lifetime[:path[:secure[:httponly]]]] |
| discardpath | DPI | PATH_INFOの削除。PATH_INFOとは実際のスクリプトファイル名とクエリ文字列の間にある、クライアントが提供するパス名情報。 |
| env | E=[!]VAR[:VAL] | 環境変数をセットできます。セットするときは[E=VAR:VAL]、削除するときは[E=!VAR]とする。例)hogeという閑居言う変数にhugaを入れる。[E=hoge:huga] |
| forbidden | F | クライアントに403 Forbiddenステータスコードを返す。 |
| gone | G | クライアントに410 Goneステータスコードを返す。 |
| Handler | H=Content-handler | 実行するアプリケーションを指定するハンドラを強制的に付ける。application/x-httpd-phpなど。設定ファイルでAddType application/x-httpd-php .phpとしておけば同じハンドラの場合はPHPプログラムとして実行されてる。 |
| last | L | Lフラグが付くとそこでルールセットが停止する。直後に続くルールを実行しない。 |
| next | N | 書き換えを行ったら、ルールセットの最初からやり直す。 |
| nocase | NC | no case。大文字小文字を区別しない。 |
| noescape | NE | noescape。エスケープをしなくなる。通常は&や%はURLエスケープされるが、このフラグを使うとエスケープせずにそのままの文字になる。 |
| nosubreq | NS | 現在のリクエストがサブリクエストの場合はルールをスキップ。 |
| proxy | P | ルールに一致したリクエストをプロキシを介して処理する。以降の処理はプロキシに渡るのでLフラグと同じようにルールの進行は停止する。 |
| passthrough | PT | uri フィールドに filename フィールドの値をセットする。直後にmod_aliasでディレクトリ構造の書き換えを行う際などに利用する。 |
| qsappend | QSA | クエリ文字列部分に書き換えではなく、文字を追加したい場合に指定する。通常「?」後のクエリ文字列は削除されるため利用する。 |
| qsdiscard | QSD | クエリ文字列がある場合削除される。これはデフォルトの動作。 |
| redirect | R[=code] | クライアントに外部へのリダイレクトとレスポンスコードを返す。何も指定しないと302で返す。[R=301]等とすればレスポンスコードを変更できる。 |
| skip | S=num | 指定した数のルールをスキップする。[s=2]とすれば、一致した場合、以降のルールを2つ飛ばす。if-then-elseを実現できる。 |
| type | T=MIME-type | 一致した項目にMIME-typeを付加する。AddTypeと同じ挙動。 |