# Регистрация только из локальной сети Переключатель в **серверном** backend `.env` (не frontend и не секрет runner): ```dotenv REGISTRATION_LAN_ONLY_ENABLED=true ``` Если переменной нет, она пустая или равна `false`, ограничение **выключено**. Включает его только `true` (регистр и пробелы по краям не важны). После изменения `.env` нужен перезапуск процессов Django или штатный деплой: настройки читаются при старте. Сам `.env` в Git не добавляется. При включении оба адреса `/api/auth/register/` и `/api/v1/auth/register/` принимают регистрацию только из `172.11.0.0/23`. Снаружи возвращается HTTP 403 с понятным сообщением до валидации, создания пользователя, отправки письма и LDAP. Вход, OIDC, восстановление пароля и подтверждение уже отправленного письма этим ограничением не затрагиваются. Frontend запрашивает `/api/auth/registration-availability/` (есть и alias `/api/v1/auth/registration-availability/`). Ответ `{"registration_allowed": true/false}` использует ту же проверку, что POST регистрации, не содержит IP или конфигурацию сети и имеет `Cache-Control: private, no-store`. Ссылка «Создать аккаунт» видна только после разрешающего ответа. При прямом открытии `/register` извне показывается объяснение вместо формы. Во время проверки и при ошибке форма скрыта; при ошибке можно повторить запрос. Проверка повторяется при возврате фокуса, восстановлении страницы и соединения. Авторитетной защитой остаётся POST API — скрытие кнопки её не заменяет. ## Адрес клиента и границы доверия Рабочий маршрут: клиент → Synology `172.11.1.254` → nginx CORP → ASGI на loopback. Оба прокси должны дописывать настоящий IP своего непосредственного клиента в `X-Forwarded-For`. На CORP это `$proxy_add_x_forwarded_for`. Проверка идёт справа налево, пропуская только явно доверенные прокси (`127.0.0.1`, `::1`, `172.11.1.254`), до первого недоверенного адреса. Подставленный клиентом префикс не влияет на решение. Другие заголовки адреса не используются. Если запрос пришёл от доверенного прокси, но адрес клиента отсутствует, повреждён или состоит только из адресов прокси, доступ запрещён. Router `172.11.0.1`, прокси и network/broadcast адреса не считаются пользователями. `172.11.0.0/16` и произвольные частные сети не разрешены. Нельзя открывать backend-порты наружу или добавлять всю LAN в доверенные прокси. Если пограничный NAT скрывает внешний адрес за другим LAN-IP, сначала исправить передачу исходного адреса/добавить этот шлюз в исключения: по одному IP приложение не отличит такой запрос от локального. Список прокси не является списком клиентов. 16 сентября 2026 проверены реальные заголовки через Synology: - обычный LAN-запрос: `172.11.1.128, 172.11.1.254`; - запрос с подставленным XFF: `172.11.0.123, 172.11.1.128, 172.11.1.254`. ## Проверка `pytest tests/api/auth/test_registration_network.py` проверяет оба режима, обе версии API, успешную регистрацию, отсутствие побочных эффектов при отказе, подмену заголовков, IPv6, повреждённые цепочки и доступность остальных auth API. В production проверять без создания учёток: POST пустого JSON `{}` из LAN должен вернуть 400 (валидация), извне при включённом флаге — 403. Отключение: `REGISTRATION_LAN_ONLY_ENABLED=false` и перезапуск Django/деплой. Это снова разрешит регистрацию извне; другие настройки авторизации не меняются. Основа реализации: [DRF permissions](https://www.django-rest-framework.org/api-guide/permissions/) и [nginx proxy_add_x_forwarded_for](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#var_proxy_add_x_forwarded_for).