Ответ
Блокировка доступа по стране (GeoIP blocking) реализуется с помощью баз данных, которые сопоставляют IP-адреса с их географическим положением. Это можно сделать на разных уровнях инфраструктуры.
На уровне приложения, например, с использованием фреймворка Flask и библиотеки geoip2, это выглядит так:
from flask import Flask, request, abort
import geoip2.database
app = Flask(__name__)
# Загружаем базу данных GeoLite2 от MaxMind
# Файл GeoLite2-Country.mmdb нужно скачать отдельно
reader = geoip2.database.Reader('path/to/GeoLite2-Country.mmdb')
# Список заблокированных стран в формате ISO 3166-1 alpha-2
BLOCKED_COUNTRIES = {'RU', 'CN', 'KP'}
@app.before_request
def block_by_country():
# Для тестов на localhost можно использовать '1.2.3.4' вместо request.remote_addr
ip_address = request.remote_addr
try:
response = reader.country(ip_address)
country_code = response.country.iso_code
if country_code in BLOCKED_COUNTRIES:
# Прерываем запрос с кодом 403 Forbidden
abort(403, description="Access from your country is restricted.")
except geoip2.errors.AddressNotFoundError:
# IP не найден в базе (например, локальный), разрешаем доступ
pass
except Exception as e:
# Логируем ошибку, но не блокируем пользователя
app.logger.error(f"GeoIP lookup failed for {ip_address}: {e}")
# ... остальная часть вашего приложения ...
Важные аспекты и лучшие практики:
- Уровень блокировки: Реализация на уровне веб-сервера (Nginx с модулем
ngx_http_geoip_module) или пограничного шлюза (CDN, WAF) гораздо эффективнее, так как снижает нагрузку на приложение. - Надежность: Метод не является 100% надежным из-за использования VPN, прокси и Tor, которые позволяют обходить такие блокировки.
- База данных: Требуется актуальная база данных GeoIP, например, бесплатная
GeoLite2от MaxMind или коммерческие аналоги. - Обработка ошибок: Важно предусмотреть обработку исключений (
try...except), чтобы не блокировать легитимных пользователей в случае ошибки определения геолокации.