Help us understand the problem. What is going on with this article?

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

More than 3 years have 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より取得

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away