前の記事で紹介した方法は手軽なのですが、 実は MaxMind 社の古いAPIを使っているという、ちょっとだけ気になる点が存在します。
そこで、今度は最新のAPIを利用したスクリプトを使用+データーベースの自動更新をやってみたいと思います。
依存ライブラリのインストール
sudo pip install geoip2
で、python スクリプト geoip2 とその依存パッケージをインストールします。
チェック用スクリプトの配置
スクリプトを /opt/geossh/check に配置します。 ファイルの中身は以下のとおりです。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import os, sys, traceback | |
import geoip2.database | |
ALLOW = 1 | |
DENY = 0 | |
when_error = ALLOW | |
def rule(code): | |
if code == "JP": return ALLOW | |
if code == None: return ALLOW | |
return DENY | |
exitcode = when_error | |
try: | |
log = os.popen("logger -t geoip/check -p daemon.notice", "w") | |
logerr = os.popen("logger -t geoip/check -p daemon.err", "w") | |
sys.stdout = log | |
sys.stderr = logerr | |
if len(sys.argv) != 2: | |
sys.stderr.write("Usage: %s ipaddress\n" % sys.argv0 ) |
|
sys.exit(0) | |
addr = sys.argv1 |
|
dirpath = os.path.abspath(__file__) | |
datafile = os.path.join(os.path.dirname(dirpath), "GeoIP.dat") | |
r = geoip2.database.Reader(datafile) | |
if not r: | |
sys.exit(0) | |
code = r.country(addr).country.iso_code | |
exitcode = rule(code) | |
print("%s %s %s" % (addr, code, exitcode == ALLOW and "allow" or "deny")) | |
except SystemExit: | |
pass | |
except: | |
traceback.print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback) | |
sys.exit(exitcode) |
配置が終わったら、コマンドで実行権限を付与します。
sudo chmod +x /opt/geossh/check
データベースアップデートスクリプトの配置
データベースをアップデートするスクリプトを /opt/geossh/update に配置します。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import os, urllib2, sys | |
url = "http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz" | |
log = os.popen("logger -t geoip/update -p daemon.notice", "w") | |
logerr = os.popen("logger -t geoip/update -p daemon.err", "w") | |
sys.stdout = log | |
sys.stderr = logerr | |
datadir = os.path.dirname(os.path.abspath(__file__)) | |
timestamp_file = os.path.join(datadir, "GeoIP.timestamp") | |
tmpfile = os.path.join(datadir, "GeoIP.tmp") | |
datfile = os.path.join(datadir, "GeoIP.dat") | |
try: | |
timestamp = open(timestamp_file).read() | |
except IOError: | |
timestamp = None | |
headers = {} | |
if timestamp: | |
headers"If−Modified−Since" = timestamp |
|
request = urllib2.Request(url, headers=headers) | |
try: | |
conn = urllib2.urlopen(request) | |
except urllib2.HTTPError, e: | |
status = getattr(e, "code", None) | |
if status == 304: | |
print("Not Modified") | |
sys.exit(0) | |
else: | |
raise | |
info = conn.info() | |
timestamp = info.get("Last-Modified", "") | |
tmp = os.popen("gunzip >%s" % tmpfile, "w") | |
while True: | |
buf = conn.read(4096) | |
if not buf: | |
break | |
tmp.write(buf) | |
tmp.close() | |
os.rename(tmpfile, datfile) | |
open(timestamp_file, "w").write(timestamp) | |
print("Updated to %r" % timestamp) | |
その後実行権限を、以下のコマンドで与えます。
sudo chmod +x /opt/geossh/update
なお、これらのスクリプトは ts1さん のコードを参考に手直したものです。
データベースのダウンロード
先ほどのスクリプトを利用して、データベースをダウンロードしてきます。
sudo /opt/geossh/update
GeoIP.dat というファイルと、 GeoIP.timestamp というファイルが /opt/geossh 以下に作成されます。
データーベースを定期的にダウンロードするようにする
sudo crontab -e
で、crontab を編集します。以下の内容を追加してください。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 23 1-8 * 3 /opt/geossh/update |
これは、月の最初の火曜日にファイルの更新が行われるため、その時に自動でスクリプトを走らせるための設定になります。
/opt/geossh/check の動作確認
前の記事と同じ方法で動作確認を行ってください。
自分が普段使っているクライアントPCののグローバルIPでリターンコードが 1 になることは必ず確認して下さい。
hosts.deny からスクリプトを呼び出す
アクセス制限をかけるために、 /etc/hosts.deny に以下の内容を追加します。
sshd: ALL: aclexec /opt/geossh/check %a
以上で終了です。お疲れ様でした。
0 件のコメント:
コメントを投稿