.htaccess の書き方（アクセス制御編）

1. [.htaccess の書き方（リダイレクト編）](http://qiita.com/shotets/items/1f8f308e008dcb96bf43)
2. **.htaccess の書き方（アクセス制御編）**
3. [.htaccess(Apache) の Order Allow,Deny(またはDeny,Allow)について](http://qiita.com/shotets/items/58a69aa15e2adc9f930a)
4. [.htaccess の書き方（スピードアップ編）](http://qiita.com/shotets/items/a5465fb41623cc3dae94)
5. [.htaccess の書き方（設定変更編）](http://qiita.com/shotets/items/cf0783530a1f2809c4d5)


## アクセス制御

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

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

`.htpasswd` はできれば非公開領域に配置した方がよい。
パスワードファイル生成は [.htaccessEditor](http://www.htaccesseditor.com/) が便利。

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

```apache:.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`で対処する。

```apache:.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
```

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

```apache:.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なディレクトリ」 という条件になります。

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

```apache:.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`には手を焼いています。

```apache:.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/

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

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


### 見られたくないファイルへのアクセスを拒否
テンプレートとか設定ファイルとか、ログなどは見られちゃ困るので。

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

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

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

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

```apache:.htaccess
deny from all
```

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

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

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

```apache:.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>
```

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


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

```apache:.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より取得](http://www.cgis.biz/tools/access/)