本番環境のWEBアプリケーションで、デバッグ情報を表示させる際、サーバー情報なども全部さらけだすので、最低限IP認証だけ行いたいと思った。
IPアドレスの文字列比較なら簡単だけど、できればネットワークアドレス(192.168.0.0/24等)で許可できると便利。
検索した所、python3からは標準でipaddressというモジュールがあるのを知った。Googleが作ったipaddrが元になってるらしい。
21.28. ipaddress — IPv4/IPv6 操作ライブラリ — Python 3.5.2 ドキュメント
下記のような感じで書いてみた。
許可するIPのリスト名はDjangoのsettings.pyから取った。
strでカンマ区切りで指定して後で分割する。
import ipaddress INTERNAL_IPS_V4 = "192.168.0.0/16,127.1.1.1" def is_internal_ip(client_ip_str) -> bool: internal_ip_list = INTERNAL_IPS_V4.split(",") client_ip = ipaddress.ip_address(client_ip_str) for internal_ip in internal_ip_list: ip_network = ipaddress.ip_network(internal_ip) if client_ip in ip_network: return True return False
ipaddress.ip_networkは、/なしで普通のIPアドレスを指定すると/32があるとして良しなにしてくれるので、IPアドレスとネットワークアドレスが一緒でも問題なく動いた。
>>> is_internal_ip("192.168.50.1") True >>> is_internal_ip("192.167.50.1") False >>> is_internal_ip("127.1.1.1") True >>> is_internal_ip("127.1.1.2") False >>> is_internal_ip("127.1.2.1") False >>> is_internal_ip("255.255.255.0") False >>> is_internal_ip("192.168.277.777") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/oceanus/app/common/utils.py", line 77, in is_internal_ip client_ip = ipaddress.ip_address(client_ip_str) File "/usr/local/lib/python3.6/ipaddress.py", line 54, in ip_address address) ValueError: '192.168.277.777' does not appear to be an IPv4 or IPv6 address
そもそも与えられたclient_ip_strがIPアドレスとして正しいかは見ていないので、変なの入れるとエラーが出るけど、自分で設定するんだから大丈夫だよね。
- 作者: Bill Lubanovic,斎藤康毅,長尾高弘
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/12/01
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る