Webアクセスを日本国内に ゆるめ に制限する

## きっかけ

[.htaccessに2000行書くとApacheの処理が何秒遅くなるか測ってみた | 編集長ブログ―安田英久 | Web担当者Forum](https://webtan.impress.co.jp/e/2016/08/02/23489) さんによると
.htaccessに2200行ほど書くと1リクエストあたり12ミリ秒の遅延になった
(中略)
(ディレクティブによる違いはあるかもしれません)

[IPアドレスで日本国外(海外/外国)からのアクセスを制限する.htaccess CGI's](http://www.cgis.biz/tools/access/) さんから 4137行のhtaccessをダウンロードした場合、
20ミリ秒程度の遅延が見込まれる。

また、行が多すぎてメンテナンスやどこで引っかかったのかチェックがし辛い。


## やらないよりマシ的なの作ってみた

[IPアドレスで日本国外(海外/外国)からのアクセスを制限する.htaccess CGI's](http://www.cgis.biz/tools/access/) さんから htaccessをダウンロードして以下実行

```sh:93行
cat htaccess | cut -f 1 -d "." | cut -f 3 -d " " | uniq
```

## .htaccess (やらないよりマシ的なの)

```apache:.htaccess
# Denied all access to the beginning
order deny,allow
deny from all

# allow bot (Slurp=yahoo)
SetEnvIf User-Agent ”Googlebot” allowbot
SetEnvIf User-Agent ”msnbot” allowbot
SetEnvIf User-Agent ”bingbot” allowbot
SetEnvIf User-Agent ”Slurp” allowbot
allow from env=allowbot

# localhost
allow from ::1
allow from 127.0.0.1

# allow access from japan (93 lines)
allow from 1.0.0.0/8
allow from 14.0.0.0/8
allow from 24.0.0.0/8
allow from 27.0.0.0/8
allow from 36.0.0.0/8
allow from 39.0.0.0/8
allow from 42.0.0.0/8
allow from 43.0.0.0/8
allow from 45.0.0.0/8
allow from 49.0.0.0/8
allow from 58.0.0.0/8
allow from 59.0.0.0/8
allow from 60.0.0.0/8
allow from 61.0.0.0/8
allow from 64.0.0.0/8
allow from 65.0.0.0/8
allow from 76.0.0.0/8
allow from 101.0.0.0/8
allow from 103.0.0.0/8
allow from 106.0.0.0/8
#
allow from 110.0.0.0/8
allow from 111.0.0.0/8
allow from 112.0.0.0/8
allow from 113.0.0.0/8
allow from 114.0.0.0/8
allow from 115.0.0.0/8
allow from 116.0.0.0/8
allow from 117.0.0.0/8
allow from 118.0.0.0/8
allow from 119.0.0.0/8
allow from 120.0.0.0/8
allow from 121.0.0.0/8
allow from 122.0.0.0/8
allow from 123.0.0.0/8
allow from 124.0.0.0/8
allow from 125.0.0.0/8
allow from 126.0.0.0/8
#
allow from 128.0.0.0/8
allow from 129.0.0.0/8
allow from 130.0.0.0/8
allow from 131.0.0.0/8
allow from 132.0.0.0/8
allow from 133.0.0.0/8
allow from 134.0.0.0/8
allow from 136.0.0.0/8
allow from 137.0.0.0/8
allow from 138.0.0.0/8
allow from 139.0.0.0/8
allow from 140.0.0.0/8
allow from 141.0.0.0/8
allow from 143.0.0.0/8
allow from 144.0.0.0/8
#
allow from 146.0.0.0/8
allow from 147.0.0.0/8
allow from 148.0.0.0/8
allow from 149.0.0.0/8
allow from 150.0.0.0/8
#
allow from 152.0.0.0/8
allow from 153.0.0.0/8
allow from 154.0.0.0/8
allow from 155.0.0.0/8
#
allow from 157.0.0.0/8
allow from 158.0.0.0/8
allow from 159.0.0.0/8
allow from 160.0.0.0/8
allow from 161.0.0.0/8
#
allow from 163.0.0.0/8
allow from 164.0.0.0/8
allow from 165.0.0.0/8
allow from 166.0.0.0/8
allow from 167.0.0.0/8
#
#
allow from 171.0.0.0/8
allow from 172.0.0.0/8
allow from 175.0.0.0/8
allow from 180.0.0.0/8
allow from 182.0.0.0/8
allow from 183.0.0.0/8
allow from 192.0.0.0/8
allow from 194.0.0.0/8
allow from 198.0.0.0/8
allow from 199.0.0.0/8
allow from 202.0.0.0/8
allow from 203.0.0.0/8
allow from 208.0.0.0/8
allow from 210.0.0.0/8
allow from 211.0.0.0/8
#
allow from 216.0.0.0/8
#
allow from 218.0.0.0/8
allow from 219.0.0.0/8
allow from 220.0.0.0/8
allow from 221.0.0.0/8
allow from 222.0.0.0/8
allow from 223.0.0.0/8
```

```apache:.htaccessその2
# Android端末からのアクセスを許可する場合
SetEnvIf User-Agent ”Android” allowmobile
allow from env=allowmobile
```

## 制限をかける前にチェック (egrep)

```sh:check.sh
IP_ALLOW="1|14|24|27|36|39|42|43|45|49|58|59|60|61|64|65|76|101|103|106|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|128|129|130|131|132|133|134|136|137|138|139|140|141|143|144|146|147|148|149|150|152|153|154|155|157|158|159|160|161|163|164|165|166|167|171|172|175|180|182|183|192|194|198|199|202|203|208|210|211|216|218|219|220|221|222|223"

# 上記以外からのアクセスを抽出
egrep -v "^($IP_ALLOW)" access_log
```

## 制限をかける前にチェック (php)

```php
<?php
$ip_allow="1|14|24|27|36|39|42|43|45|49|58|59|60|61|64|65|76|101|103|106|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|128|129|130|131|132|133|134|136|137|138|139|140|141|143|144|146|147|148|149|150|152|153|154|155|157|158|159|160|161|163|164|165|166|167|171|172|175|180|182|183|192|194|198|199|202|203|208|210|211|216|218|219|220|221|222|223";

if (preg_match("/^(".$ip_allow.")\./", $_SERVER["REMOTE_ADDR"])) {
        //echo "allow";
} else {
        error_log("deny: " . $_SERVER["REMOTE_ADDR"]);
}
```