.htaccessのSetEnvIfで定義した関数は、下位ディレクトリの.htaccessにも引き継がれる模様。そのあたりを応用した.htaccessの書き方と、「|」を用いて複数行にわたりSetEnvIfを1行にまとめる書き方の紹介。

SetEnvIf User-Agent "^aaa$" deny_ua
SetEnvIf User-Agent "^bbb$" deny_ua
SetEnvIf User-Agent "^ccc$" deny_ua
SetEnvIf User-Agent "^ddd$" deny_ua
という何行にも渡るSetEnvIfを

SetEnvIf User-Agent "^(aaa|bbb|ccc|ddd)$" deny_ua
とまとめてみた。
そしてその定義した変数は、下位ディレクトリの.htaccessでも有効な事を確認した。

以下、さくらのスタンダードにて有効な事を確認。
多分普通のサーバーならどこでも大丈夫だろう。

以下をルートディレクトリに設置
#禁止するUAやリファラの書き方例
SetEnvIf User-Agent "^(IE/4\.0|Python-urllib/3\.1|Mozilla/4\.0\(compatible;\)|Mozilla/4\.0 \(compatible; MSIE 8\.0; Win32\))$" deny_ua
SetEnvIf User-Agent "^(Wget|WeBoX|Sogou webspider|Snapbot|Snapbot|Moreoverbot|HappyFunBot|veoh-\\x|Mail|WinHttp.WinHttpRequest.5)" deny_ua
SetEnvIf User-Agent "(Arachmo|Website Explorer|search-hp_bot|SpeedySpider|WebFetch|HTTrack|MJ12bot|SiteSucker|Purebot|Weber|SiteBot|WebAuto|LexxeBot|Moreoverbot|suggybot|YodaoBot|discobot)" deny_ua
#SetEnvIf User-Agent "Baidu" deny_ua
SetEnvIf Referer "^(http://禁止したいURL_1\.com|http://禁止したいURL_2)" deny_ua
#上記は過去503エラー発生の原因になったUAやリファラ色々


#禁止するリモートホスト書き方例
SetEnvIf Remote_Addr 119.63.192.0/21 deny_ua
#マスクしたものを|で挟めるかは、多分できると思うが未確認。
SetEnvIf Remote_Addr"^(150\.70\.64|150\.70\.66|150\.70\.75|150\.70\.84|150\.70\.97|150\.70\.172|192\.168\.60\.1|216\.104\.15\.)"deny_ua
#途中まで書いて$で閉じないタイプ
SetEnvIf Remote_Addr"^(4\.78\.1\.36|38\.105\.71\.13|38\.105\.83\.22|64\.94\.66\.97|66\.226\.5\.248|67\.205\.46\.10|68\.51\.80\.2)$"deny_ua
#最後まで指定して$で閉じる
SetEnvIf Remote_Addr "^(203\.216\.255\.7[2-8]|65\.208\.151\.11.)" deny_ua
#正規表現[]で括ったり、「.」でIPの一部を柔軟に指定

#
#注意
#例)リモートホスト192.168.0.10の場合
#SetEnvIf Remote_Addr 192.168.0.1 deny_ua
#上記でも192.168.0.10が引っかかる。
#deny from 192.168.1
#だと192.168.0.10は引っかからない。
#$や\.をきちんと使いこなすこと。
#


order allow,deny
allow from all
deny from env=deny_ua

 

以下を携帯サイト用のディレクトリに設置
SetEnvIf User-Agent  "(DoCoMo|J-PHONE|Vodafone|SoftBank|MOT-|KDDI|UP\.Browser|PDXGW|DDIPOCKET|WILLCOM|Google)" is_keitai
SetEnvIf deny_ua "1" !is_keitai
#deny_ua は上位ディレクトリの.htaccessで定義した変数

order deny,allow
deny from all
allow from env=is_keitai

テスト: 
ルートで#SetEnvIf User-Agent "Firefox" deny_ua
下層で#SetEnvIf User-Agent "Firefox" is_keitai

結果:
下層ディレクトリでも禁止されるの確認。
自分の環境から試した限りでは、ルートで設定した変数が上手く下層ディレクトリに伝わっているっぽい。実戦でどういう作動をするかは、これから確認。

今まではディレクトリ毎にルートと同じ変数を定義していましたが、無駄だったかも知れないですね(色々ベンチ取らないと本当に無駄かどうかわかんないけど)

高速化・最適化は未確認

拒否したいIPを複数行SetEnvIfで設定するのと、上記の様に|で挟んで一行で指定するのは、どっちがCPUに負荷をかけないか?どっちが高速に処理されるのか?はよく解っていないです。

また暇なときにApacheBenchやってみます。

 

携帯サイトのPCからのアクセス禁止設定

約1年半ほど、携帯用サイトの閲覧許可設定を放ったらかしにしていた。
そろそろ見直さないとイカンだろうと、気合を入れて各キャリアのIP帯域を調査。

#docomo
#http://www.nttdocomo.co.jp/service/imode/make/content/ip/
#AU EZweb
#http://www.au.kddi.com/ezfactory/tec/spec/ezsava_ip.html
#softbank
#http://creation.mb.softbank.jp/web/web_ip.html
#WILLCOM
#http://www.willcom-inc.com/ja/service/contents_service/create/center_info/#01

AUとWILLCOM、IP帯域増えすぎ&1年半で変わりすぎ('Α`)
携帯サイトをIP帯域で制限を設けるのは、常にIPを追いかけなきゃならないのか。。。こりゃアマチュアのWeb制作者じゃ手に負えないわ。。。UA制限に切り替える。

あとがき

今は携帯サイトをCGIから静的HTMLファイルに変更しているので、「多少の漏れがあっても大変な事にならないだろう。」と判断。
この「多少漏れてくる」ユーザーはUA偽装しているだけの通常閲覧なら良いのですが、巡回ツールを利用する人が多数出現したのが非常に困りました。
また人目の多い外部サイトに携帯URLを貼り付けるのも(気持ちは解るが)かなり困った。

CGIで作動させていた頃は、サーバー負荷が非常に大きくて色々考えていたけど、今なら多少のアクセス増も大丈夫だろう。