Apache
.htaccess

.htaccess の書き方(アクセス制御編)

More than 1 year has passed since last update.
  1. .htaccess の書き方(リダイレクト編)
  2. .htaccess の書き方(アクセス制御編)
  3. .htaccess(Apache) の Order Allow,Deny(またはDeny,Allow)について
  4. .htaccess の書き方(スピードアップ編)
  5. .htaccess の書き方(設定変更編)

アクセス制御

ベーシック認証

まずはベーシックなベーシック認証

.htaccess
AuthUserFile /var/www/.htpasswd
AuthGroupFile /dev/null
AuthName "Input ID and Password."
AuthType Basic
require valid-user

.htpasswd はできれば非公開領域に配置した方がよい。
パスワードファイル生成は .htaccessEditor が便利。

特定ディレクトリだけベーシック認証をかけたい場合は

.htaccess
<Directory /var/www/html/member>
AuthUserFile /var/www/.htpasswd
AuthGroupFile /dev/null
AuthName "Input ID and Password."
AuthType Basic
require valid-user
</Directory>

.htaccessではDirectoryディレクティブが使えないようなので
特定ディレクトリだけベーシック認証をかけたい場合は
そのディレクトリに.htaccessを置くのが簡単。

ただ、wordpressなど物理的に存在しないディレクトリでも
特定のURIでベーシック認証をかけたい場合がある。
その場合はLocationディレクティブなのだが
これも.htaccessでは使えないのでSetEnvIfで対処する。

.htaccess
Satisfy Any

AuthType Basic
AuthName "Input your ID and Password."
AuthUserFile /var/www/.htpasswd
require valid-user

SetEnvIf Request_URI "/member/" secure_dir
Order Allow,Deny
Allow from all
Deny from env=secure_dir

その逆で、全体はベーシック認証をかけて、
特定のディレクトリはベーシック認証かけたくない場合は

.htaccess
Satisfy Any

AuthType Basic
AuthName "Input your ID and Password."
AuthUserFile /var/www/.htpasswd
require valid-user

SetEnvIf Request_URI "/ok_dir/" ok_dir
Order Deny,Allow
Deny from all
allow from env=ok_dir

デフォルトはSatisfy All(全ての条件をクリアしないとアクセスできない)のところを
Satisfy Any(いずれかの条件が通れば良い)とすることで
「ベーシック認証」 or 「OKなディレクトリ」 という条件になります。

同様に特定のサブドメインや特定のアクセス元はベーシック認証をかけない
ということが可能です。

.htaccess
AuthType Basic
AuthName "Input your ID and Password."
AuthUserFile /var/www/.htpasswd
require valid-user

SetEnvIf Host "^subdomain\." host_ok
Order Deny,Allow
allow from env=host_ok
Allow from XXX.XXX.XXX.XXX
Deny from all

# Satisfy Anyはどこに書いてもいい
Satisfy Any

検索エンジンのクローラーを拒否

悪質なクローラーが中にはいるのです。特に360spiderには手を焼いています。

.htaccess
<IfModule mod_setenvif.c>

BrowserMatch "\s360Spider$" bad_bot
BrowserMatch "https?://(www\.)?cognitiveseo[\./]" bad_bot
BrowserMatch ";\s?MJ12bot[ /;\+\)]" bad_bot
BrowserMatch "^rogerbot[ /;\+]" bad_bot
BrowserMatch "^Scrapy[ /;\+]" bad_bot
BrowserMatch "^Screaming[ /;\+]" bad_bot
BrowserMatch ";\s?SemrushBot[ /;\+\)]" bad_bot
BrowserMatch ";\s?SMTBot[ /;\+\)]" bad_bot
BrowserMatch ";\s?spbot[ /;\+\)]" bad_bot
BrowserMatch "^vebidoobot$" bad_bot
BrowserMatch "^YisouSpider$" bad_bot
BrowserMatch "^ZoomBot[ /;\+]" bad_bot
BrowserMatch ";\s?AhrefsBot[ /;\+\)]" bad_bot
BrowserMatch ";\s?MegaIndex\.ru[ /;\+\)]" bad_bot
BrowserMatch ";\s?aiHitBot[ /;\+\)]" bad_bot
BrowserMatch ";\s?BLEXBot[ /;\+\)]" bad_bot
BrowserMatch "^BOT[ /;\+]" bad_bot
BrowserMatch "^CCBot[ /;\+]" bad_bot
BrowserMatch "^CheckMarkNetwork[ /;\+]" bad_bot
BrowserMatch ";\s?Cliqzbot[ /;\+\)]" bad_bot
BrowserMatch ";\s?coccocbot\-web[ /;\+\)]" bad_bot
BrowserMatch ";\s?DeuSu[ /;\+\)]" bad_bot
BrowserMatch "^DomainStatsBot[ /;\+]" bad_bot
BrowserMatch ";\s?DotBot[ /;\+\)]" bad_bot
BrowserMatch "^Mozilla/[^ ]+ eCairn\-Grabber[ /;\+]" bad_bot
BrowserMatch ";\s?Exabot[ /;\+\)]" bad_bot
BrowserMatch ";\s?FatBot[ /;\+\)]" bad_bot
BrowserMatch ";\s?GrapeshotCrawler[ /;\+\)]" bad_bot
BrowserMatch ";\s?HaosouSpider[ /;\+\)]" bad_bot
BrowserMatch ";\s?linkdexbot[ /;\+\)]" bad_bot
BrowserMatch "^ltx71[ /;\+]" bad_bot
BrowserMatch ";\s?Mail\.RU_Bot[ /;\+\)]" bad_bot
BrowserMatch ";\s?memoryBot[ /;\+\)]" bad_bot
BrowserMatch "^psbot[ /;\+]" bad_bot
BrowserMatch "^roboto$" bad_bot
BrowserMatch ";\s?SecurityResearch\.bot[ /;\+\)]" bad_bot
BrowserMatch ";\s?SEOkicks\-Robot[ /;\+\)]" bad_bot
BrowserMatch ";\s?SurdotlyBot[ /;\+\)]" bad_bot
BrowserMatch ";\s?WBSearchBot[ /;\+\)]" bad_bot
BrowserMatch "^Wotbox[ /;\+]" bad_bot
BrowserMatch ";\s?yoozBot\-2\.2[ /;\+\)]" bad_bot

  # Apache < 2.3
  <IfModule !mod_authz_core.c>
    Order Allow,Deny
    Allow from all
    Deny from env=bad_bot
  </IfModule>

  # Apache >= 2.3
  <IfModule mod_authz_core.c>
    <RequireAll>
      Require all Granted
      Require not env bad_bot
    </RequireAll>
  </IfModule>
</IfModule>

参照元
https://www.reddit.com/r/sysadmin/comments/59y7xj/why_so_many_badbots_setup_use_anchored_setenvif/

逆に、メンテナンス中で近々公開予定なので、クローラーにまた来て欲しいと伝えたい場合は

.htaccess
<IfModule mod_headers.c>
# クローラー用に指定日時にまたきてねと言っておく
Header set Retry-After "Mon, 10 September 2016 12:00:00 GMT"
</IfModule>

見られたくないファイルへのアクセスを拒否

テンプレートとか設定ファイルとか、ログなどは見られちゃ困るので。

.htaccess
# 見られたくないファイルの拡張子
<Files ~ ".(log|csv|ini|dat|tpl|yml)$">
deny from all
</Files>

ファイルとディレクトリをまとめて設定する例

.htaccess
# ファイルとディレクトリを保護
SetEnvIf Request_URI "(\.(txt|dat|csv|ini)|/(data|lib|templates)/)$" ng_dir
Order Allow,Deny
Allow from all
Deny from env=ng_dir

ディレクトリだったら正規表現書くより、そのディレクトリに以下を入れるだけでもいい。

.htaccess
deny from all

.htaccess.htpasswdはApacheの設定ファイルに以下がデフォルトで書かれているので
わざわざ拒否設定書かなくていい。
.ht から始まるファイル名はすべて拒否されている。

.htaccess
<FilesMatch "^¥.ht">
    Order allow,deny
    Deny from all
</FilesMatch>

ページをキャッシュさせたくない場合

.htaccess
# HTMLはキャッシュさせない
# mod_headersが必要
<Files ~ "\.(html|php)$">
    <IfModule mod_headers.c>
        Header set Pragma no-cache
        Header set Cache-Control no-cache
        Header set Expires "Thu, 01 Dec 1994 16:00:00 GMT"
    </IfModule>
</Files>

キャッシュの有効期限を過去にする

アクセスを国内のみに制限する

.htaccess
order deny,allow
deny from all

allow from 1.0.16.0/20
allow from 1.0.64.0/18
allow from 1.1.64.0/18
:
長いので省略

国内IPアドレスをAPNICより取得