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と同じ挙動。 |