Django specifies IP access (restrict IP access) Recently, the server can always be maliciously scanned and attempted attacked by foreign IPs, so I blo...
Django specifies IP access (restricts IP access)
Published: 2025-07-21 (a year ago)
PythonDjango

Django Specify IP access (restrict IP access)

######Recently, the server has always been maliciously scanned and attempted attacks by foreign IPs, so I blocked the foreign IP address
#######I do it through middleware

Geoip Database Download

After downloading, place it in the root directory of your project

###settings.py Configuration

python Copy
# settings.py
# GeoLite Path 
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
GEOIP_PATH = os.path.join(BASE_DIR, 'geoip')
python Copy
# settings.py Configuration
OPEN_FORBIDDEN = True #Whether to enable blocking
MIN_FORBIDDEN_TIME = 60 #Minimum masking duration
MAX_FORBIDDEN_TIME = 600 #maximum masking duration
FORBIDDEN_IP_SECONDS = 60 #Expiration time of a KEY that records the number of times a user is blocked under the same IP
FORBIDDEN_USER_SECONDS = 1 #The expiration time of a KEY that records the number of accesses within the time step specified by the same user
FORBIDDEN_IP_COUNT = 3 #Users with the same IP will be blocked more than this value will block the IP
FORBIDDEN_USER_COUNT = 8 #If the number of accesses within the specified time step of the same user exceeds this value, the user will be blocked
python Copy
#settings.py Middleware put first
MIDDLEWARE = [
    'page.CountryMiddleware.ForbiddenMiddleware', #Anticrawler
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
	..........
]

####Create a CountryMiddleware.py file in your project, name it yourself

python Copy
from random import choice
from django.conf import settings
from django.core.cache import caches
from django.contrib.gis.geoip2 import GeoIP2
from django.http import HttpResponseForbidden
from django.utils.deprecation import MiddlewareMixin

cache = caches['default']# from django.core.cache import cache has no incr feature
geoip = GeoIP2(settings.GEOIP_PATH) #Load IP geo-location database
forbidden = '<div style="font-size:30px;">403 forbidden</div><div>%s</div>'


class ForbiddenMiddleware(MiddlewareMixin):
    def process_request(self, request):
        if not settings.OPEN_FORBIDDEN: #Function switches in configuration file
            return
        ip = request.META.get ('HTTP_REMOTE_ADDR', request.META['REMOTE_ADDR']) #Get the visitor IP address
        try:
            country = geoip.country (ip)['country_code']#parse visitor country code
            if country != 'CN':#Block access to foreign IP
                return HttpResponseForbidden(forbidden % 'Temporarily')
        except:
            pass

    def process_response(self, request, response):
        if request.user.is_authenticated and request.user.is_superuser:
            return response #If you are a super administrator, return the response directly
        if not settings.OPEN_FORBIDDEN: #Function switches in configuration file
            return response
        ip_address = request.META.get ('HTTP_REMOTE_ADDR', request.META['REMOTE_ADDR']) #Get the visitor IP address
        try:
            user_tag = request.COOKIES.get(settings.CSRF_COOKIE_NAME) #Get cookies from the request
            if not user_tag:
                user_tag = response.cookies[settings.CSRF_COOKIE_NAME].value #Get cookies from the response when logging in
        except KeyError:
            user_tag = ip_address #There is no cookie, that is, the user has not logged in, and the IP address is used as the user token

        forbidden_ip_key = 'forbidden:ip:%s' % ip_address
        forbidden_user_key = 'forbidden:user:%s' % user_tag
        for cache_key in [forbidden_ip_key, forbidden_user_key]: #Check IP address masking and user token masking at the same time
            forbidden_time = cache.get(cache_key)
            if forbidden_time: #Continue requesting if blocked
                cache.set(cache_key, forbidden_time, forbidden_time) #Resets the expiration time to the initial value and extends the masking time
                return HttpResponseForbidden(Forbidden % 'is visited too frequently. Please try again later! ')

        ip_count_key = 'count:ip:% s'% ip_address #The number of times users with the same IP address have been blocked
        user_count_key = 'count:user:%s:% s'%(user_tag, request.path) #The number of visits by the same user in the specified time step
        forbidden_user_count = settings.FORBIDDEN_USER_COUNT
        if 'HTTP_FILE_UPLOAD_NAME' in request.META: #File transfers have a higher interactive frequency, and the frequency limit is increased by 5 times
            forbidden_user_count *= 5

        if cache.get(user_count_key, 0) Forbidden_user_count: #The same user accesses too many times in a specified time step
            forbidden_time = choice(range(settings.MIN_FORBIDDEN_TIME, settings.MAX_FORBIDDEN_TIME)) #Generate a random mask length
            cache.set(forbidden_user_key, forbidden_time, forbidden_time) #Set to block this user
            try:
                cache.incr(ip_count_key) #The number of times the IP used by this user is blocked is increased once
            except ValueError:
                cache.set(ip_count_key, 1, settings.FORBIDDEN_IP_SECONDS) #Set to 1 if you don't have this key yet
            return HttpResponseForbidden(Forbidden % 'is visited too frequently. Please try again later! ')
        elif cache.get(ip_count_key, 0) settings.FORBIDDEN_IP_COUNT: #Users with the same IP address are blocked three times and then access to that IP address is blocked
            forbidden_time = choice(range(settings.MIN_FORBIDDEN_TIME, settings.MAX_FORBIDDEN_TIME)) #Generate a random mask length
            cache.set(forbidden_ip_key, forbidden_time, forbidden_time) #Set to block this IP address
            return HttpResponseForbidden(Forbidden % 'is visited too frequently. Please try again later! ')
        else:
            try:
                cache.incr(user_count_key) #The number of visits this user has increased once
            except ValueError:
                cache.set(user_count_key, 1, settings.FORBIDDEN_USER_SECONDS) #Set to 1 if you don't have this key yet
            return response

####That's fine