43 lines
1.6 KiB
Python
Executable File
43 lines
1.6 KiB
Python
Executable File
from django.core.exceptions import PermissionDenied
|
|
from django.core.cache import cache
|
|
from django.conf import settings
|
|
|
|
class IPBlockingMiddleware:
|
|
def __init__(self, get_response):
|
|
self.get_response = get_response
|
|
# 事前にブロックする IP アドレスのリスト
|
|
self.blacklisted_ips = getattr(settings, 'BLACKLISTED_IPS', [])
|
|
|
|
def __call__(self, request):
|
|
ip = self.get_client_ip(request)
|
|
|
|
# キャッシュからブロックリストを取得
|
|
blocked_ips = cache.get('blocked_ips', set())
|
|
|
|
# 事前にブロックされた IP またはキャッシュ内のブロックされた IP をチェック
|
|
if ip in self.blacklisted_ips or ip in blocked_ips:
|
|
raise PermissionDenied
|
|
|
|
# 不正アクセスの検出ロジックをここに実装
|
|
if self.is_suspicious(ip):
|
|
blocked_ips.add(ip)
|
|
cache.set('blocked_ips', blocked_ips, timeout=3600) # 1時間ブロック
|
|
raise PermissionDenied
|
|
|
|
response = self.get_response(request)
|
|
return response
|
|
|
|
def is_suspicious(self, ip):
|
|
request_count = cache.get(f'request_count_{ip}', 0)
|
|
cache.set(f'request_count_{ip}', request_count + 1, timeout=60)
|
|
return request_count > 100 # 1分間に100回以上のリクエストがあれば不審と判断
|
|
|
|
def get_client_ip(self, request):
|
|
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
|
|
if x_forwarded_for:
|
|
ip = x_forwarded_for.split(',')[0]
|
|
else:
|
|
ip = request.META.get('REMOTE_ADDR')
|
|
return ip
|
|
|