2017年8月16日水曜日

Apacheで特定の国からのアクセスを拒否する


for CentOS7.x

GCEの利用料金を抑えるため、1パケット目から料金の発生する中国とオーストラリアからのHTTPリクエストに拒否応答(403)を返すApacheの設定です。

完全に遮断したいのであれば、GCEのFWでブロックしたほうがいいのですが、中国もオーストラリアもとなると対象IPが多すぎるのと一つ一つ登録するのが面倒なので・・・

まずは、mod_geoipをインストールします。
sudo yum install mod_geoip
次にGeoIPのデータベースをmaxmind社からダウンロードして配置しておきます。
Licenseは CC BY-SA 3.0で、下記の文章を製品などに含むことでライセンスを満たすことになるようです。
この製品には MaxMind が作成した GeoLite2 データが含まれており、
<a href="http://www.maxmind.com">http://www.maxmind.com</a> から
入手いただけます。
mkdir geoip
cd geoip/
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
gunzip GeoIP.dat.gz
sudo mv /usr/share/GeoIP/GeoIP.dat /usr/share/GeoIP/GeoIP.dat.bak
sudo mv GeoIP.dat /usr/share/GeoIP/GeoIP.dat
httpdのconfを変更します。mod_geoipのconfigは/etc/httpd/conf.d/geoip.confに配置されますので、若干の修正を加えます。
sudo vi /etc/httpd/conf.d/geoip.conf

<IfModule mod_geoip.c>
  GeoIPEnable On
  GeoIPDBFile /usr/share/GeoIP/GeoIP.dat

  GeoIPDBFile /usr/share/GeoIP/GeoIP.dat MemoryCache
  GeoIPDBFile /usr/share/GeoIP/GeoIP.dat CheckCache
</IfModule>
あとは、httpd.confでCountry Codeをブラックリストとして登録して拒否します。
sudo vi /etc/httpd/conf/httpd.conf

<Location "/">
  Order allow,deny
  SetEnvIf GEOIP_COUNTRY_CODE CN BLACKLIST_COUNTRY
  SetEnvIf GEOIP_COUNTRY_CODE AU BLACKLIST_COUNTRY

  Allow from all
  Deny from env=BLACKLIST_COUNTRY
</Location> 
ログにCountry Codeを追加したい場合は"%{GEOIP_COUNTRY_CODE}e"を追加すると、下図のようにJPとかUSとかがログに記載されるようになります。
LogFormat "%h %l %u %t  \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{GEOIP_COUNTRY_CODE}e" combined
LogFormat "%h %l %u %t  \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{GEOIP_COUNTRY_CODE}e"
あと、403を返す時に少しでもサイズを減らすため、最小の文字列を返すように設定しておきます。まぁ、1文字でもいいと思いますが、E403とだけ返すように設定してみました・・・。
ErrorDocument 403 "E403"
最後にhttpdを再起動して設定を反映させてください。
sudo systemctl restart httpd
以上ですー。

2017年8月7日月曜日

顔を認識してモザイクをかける@OpenCV3 + Python3

USBカメラなどから画像を取り込んで、顔と認識した部分にモザイクを掛けます。 都度顔認識していますので、物体追跡させて方が効率がいいのかも。

# -*- coding: utf-8 -*-
# for Python 3.4, 3.5
import cv2

def mozaic(cascade, image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    faces = cascade.detectMultiScale(
        gray, scaleFactor=1.11, minNeighbors=4, minSize=(5, 5))

    # 検出した部分を縮小して、拡大(最近傍補間)する
    for [x, y, w, h] in faces:
        face = image[y:(y + h), x:(x + w)]
        face_tmp = cv2.resize(face, (int(w/20),int(h/20)))
        face = cv2.resize(
            face_tmp, (w,h), interpolation=cv2.INTER_NEAREST)
        image[y:(y + h), x:(x + w)] = face
    return image

# デバイスは固定
cap = cv2.VideoCapture(0)
if cap.isOpened() is False:
        raise("IO Error.")

# haarcascade_frontalface_alt.xmlは下記から持ってくる
# https://github.com/opencv/opencv/tree/master/data/haarcascades
cascade_path = "haarcascade_frontalface_alt.xml"
cascade = cv2.CascadeClassifier(cascade_path)

while True:
    ret, frame = cap.read()
    frame = mozaic(cascade, frame)
    cv2.imshow('image', frame)
    k = cv2.waitKey(1)
    if k == 27:
        break;
        
cap.release()
cv2.destroyAllWindows()

Python3 IPアドレスから国の情報を取得

geolite2とかはPython3では使えなくなっているので注意が必要。

コード:

# -*- coding: utf-8 -*-
# for Python 3.4, 3.5
import geoip2.database as geodb
import geoip2.errors as geoerr

rec_city = geodb.Reader('GeoLite2-City.mmdb')
try:
    rec = rec_city.city("23.44.226.40")
    if rec:
        print(rec.country.iso_code)
        print(rec.country.names["ja"])
        print(rec.country.name)
        print(rec.city.names["ja"])
        print(rec.city.name)

except geoerr.AddressNotFoundError as anfe:
    print (anfe)



実行結果:
 US
 アメリカ合衆国
 United States
 ケンブリッジ
 Cambridge

GeoLite2-City.mmdbは下記のURLからダウンロード
https://dev.maxmind.com/ja/geolite2/
Licenseは CC BY-SA 3.0
下記の文章を製品などに含むことでライセンスを満たすことになるようです。
この製品には MaxMind が作成した GeoLite2 データが含まれており、
<a href="http://www.maxmind.com">http://www.maxmind.com</a> から
入手いただけます。