Если нужно временно спрятать сайт от посторонних без сложных систем доступа, самый быстрый способ — включить HTTP Basic Auth (защита паролем на уровне веб-сервера) и при необходимости добавить белый список IP-адресов (allowlist), чтобы своей команде не вводить пароль каждый раз. Дальше — практический разбор для Nginx и Apache, с рабочими сниппетами, нюансами и отладкой.
Зачем закрывать сайт паролем именно на уровне веб-сервера
HTTP Basic Auth работает до приложения, поэтому:
- не допускает индексации поисковиками (получают 401 и не идут дальше),
- не требует прав на код, CMS или фреймворк,
- быстро включается и выключается одной правкой конфигурации,
- моментально покрывает весь сайт или выбранные разделы.
Типовые сценарии: предпросмотр нового проекта, закрытый стейджинг, миграция или редизайн, защита панели администрирования, приватные файловые каталоги, внутренние демо. Для миграций полезен чек-лист по доменам, редиректам и HSTS — см. разбор миграции доменов, редиректов и HSTS.
Важно: Basic Auth не шифрует трафик — логин и пароль передаются в заголовке Authorization в Base64. Обязательно используйте HTTPS и установите SSL-сертификаты, чтобы не отдавать креды в открытом виде.
Кратко о механике HTTP Basic Auth
Сервер возвращает 401 Unauthorized и заголовок WWW-Authenticate: Basic realm="...". Браузер показывает диалог, а затем добавляет Authorization: Basic ... к каждому запросу. Realm — это подпись зоны, задаётся в конфиге и влияет на кэширование логина браузером.

Готовим файл паролей: htpasswd
Оба сервера (и Nginx, и Apache) понимают формат пароля из файла .htpasswd. Лучше хранить его вне docroot, например в /etc/nginx/.htpasswd или /etc/apache2/.htpasswd. Права: достаточно чтения веб-сервером, другим пользователям — закрыть.
Установка утилиты и генерация
# Debian/Ubuntu
sudo apt-get update
sudo apt-get install apache2-utils
# RHEL/CentOS/Alma/Rocky
sudo dnf install httpd-tools
# Создать файл и первого пользователя (формат Apache MD5 APR1, совместим с Nginx)
sudo htpasswd -c -m /etc/nginx/.htpasswd admin
# Добавить ещё одного пользователя
sudo htpasswd -m /etc/nginx/.htpasswd dev
Ключи:
-c— создать новый файл (используйте только один раз, чтобы не перетереть существующих пользователей),-m— хэш Apache MD5 APR1. Его понимает и Nginx, и Apache, поэтому это безопасный кросс-серверный выбор.
Для Apache можно использовать bcrypt (
htpasswd -B), но Nginx на многих системах его не валидирует. Для совместимости выбираем-mили, при необходимости, генерируем APR1 через OpenSSL.
# Генерация APR1 через OpenSSL
openssl passwd -apr1
# Вставьте полученную строку как хэш в файл формата user:hash
Проверьте права и владельца:
sudo chown root:www-data /etc/nginx/.htpasswd
sudo chmod 640 /etc/nginx/.htpasswd
Подставьте правильного системного пользователя группы веб-сервера: www-data, nginx или apache.
Nginx: быстро закрываем весь сайт паролем
Минимальный фрагмент в серверном блоке:
server {
listen 80;
server_name example.com;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
root /var/www/example.com;
index index.html index.php;
}
Перезагрузите конфиг и проверьте:
sudo nginx -t
sudo systemctl reload nginx
Только для выбранного раздела
location /admin/ {
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
Остальная часть сайта останется открытой.
Белый список IP с обходом пароля
Чтобы сотрудники с доверенных IP не видели окно пароля, используйте satisfy any: доступ разрешён, если выполнено хотя бы одно условие (IP в allowlist ИЛИ верная пара логин/пароль).
location / {
satisfy any;
allow 203.0.113.10;
allow 2001:db8::/32;
deny all;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
}
Порядок директив важен: сначала
satisfyиallow/deny, затемauth_basic. Иначе можно получить неожиданный 401/403.
Nginx за обратным прокси/CDN
Если Nginx стоит за балансировщиком или CDN, реальный IP клиента может не совпадать с $remote_addr. Тогда allowlist работать не будет, пока не доверите источник и не поднимете реальный IP:
set_real_ip_from 192.0.2.0/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
Укажите подсеть или адрес вашего прокси. Никогда не доверяйте всем подряд источникам X-Forwarded-For — это критично для безопасности.
Исключения для статических файлов
Иногда ассеты должны быть доступны без пароля (например, публичный логотип). Можно снять Basic Auth на подмножестве:
location ~* \.(css|js|png|jpg|gif|woff2?)$ {
auth_basic off;
}
Разумеется, делайте это осознанно: любые исключения — потенциальная поверхность утечки.
Apache 2.4: защита в виртуальном хосте или через .htaccess
В Apache можно включить Basic Auth в конфиге виртуального хоста или локально в .htaccess. Предпочтительнее — конфиг vhost: быстрее и прозрачнее. .htaccess выбирают, когда нет доступа к глобальному конфигу (это типично для виртуального хостинга). На собственном VDS удобнее править конфигурацию полностью.
Вариант 1: конфиг виртуального хоста
<Directory "/var/www/example.com">
AuthType Basic
AuthName "Restricted"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Directory>
Перезапуск:
sudo apachectl configtest
sudo systemctl reload apache2
Вариант 2: .htaccess
Содержимое /var/www/example.com/.htaccess:
AuthType Basic
AuthName "Restricted"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
Убедитесь, что в конфигурации разрешены директивы авторизации:
<Directory "/var/www/example.com">
AllowOverride AuthConfig
</Directory>
Белый список IP и обход пароля
Современный способ (Apache 2.4): контейнер <RequireAny>. Доступ даётся, если выполнено хотя бы одно условие.
<Directory "/var/www/example.com">
AuthType Basic
AuthName "Restricted"
AuthUserFile /etc/apache2/.htpasswd
<RequireAny>
Require ip 203.0.113.10
Require ip 2001:db8::/32
Require valid-user
</RequireAny>
</Directory>
Для .htaccess синтаксис тот же — просто поместите блок <RequireAny> внутрь файла.
Старый синтаксис (
Allow from,Deny from,Satisfy any) — часть модуля совместимости и не рекомендуется в новых конфигурациях.
Только для каталога /admin
<Directory "/var/www/example.com/admin">
AuthType Basic
AuthName "Admin Area"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Directory>
Прячем сам .htpasswd от прямого доступа
Храните файл за пределами docroot. Если по какой-то причине он лежит внутри, закройте паттерн на уровне сервера.
# Apache
<Files ".ht*">
Require all denied
</Files>
# Nginx
location ~ /\.ht {
deny all;
}
Отладка и проверка
Проверьте ответ кодом и заголовками:
curl -I https://example.com/
# Должно прийти: HTTP/1.1 401 Unauthorized и WWW-Authenticate
curl -I -u admin:secret https://example.com/
# Должно прийти: HTTP/1.1 200 OK
Проверьте обход по IP, сделав запрос из сети с доверенного адреса или через туннель. Если видите 403 вместо 401 — правило allow/deny отрабатывает до авторизации. Убедитесь, что включили satisfy any (Nginx) или <RequireAny> (Apache).

Типичные ошибки и быстрые решения
- Apache: .htaccess не работает. Часто причина —
AllowOverride None. РазрешитеAllowOverride AuthConfigили вынесите правила в vhost. - Неверный путь к AuthUserFile. Проверьте абсолютный путь, права доступа и владельца. Apache/Nginx должен уметь читать файл.
- Nginx не принимает пароль, созданный
htpasswd -B. Используйте-m(APR1) или генерируйте хэш черезopenssl passwd -apr1. - Allowlist за прокси не срабатывает. Поднимите реальный IP через
set_real_ip_fromиreal_ip_headerв Nginx, либо соответствующие модули в Apache, доверяя только вашим прокси. - Браузер «залипает» с кэшем логина. Измените
AuthName/realm, чтобы форсировать новое окно авторизации, или закройте все вкладки/перезапустите браузер. - Случайная раздача .htpasswd. Держите файл вне
docrootи запретите любые файлы, начинающиеся на.ht, через правила сервера.
Комбинации и расширения
- Только HEAD/GET. Обычно Basic Auth применяется ко всем методам. Для API можно точечно ограничивать методы и локации отдельными блоками.
- Множественные зоны. Для разных разделов задайте разные
AuthNameи разные файлы пользователей. - Исключение проверок для мониторингов. Добавьте их IP в allowlist, чтобы не получать ложные алерты.
- CMS-админка. Накрывайте
/wp-admin,/cms/,/backend/отдельными правилами, но не забывайте, что некоторые AJAX-эндпоинты могут жить вне каталога — проверяйте логи и открывайте точечно при необходимости.
Коды ответов и влияние на SEO
При включенном Basic Auth не будет индексации: боты получают 401 и не читают контент. При снятии защиты индексация возобновится. В продакшене вместо пароля используйте полноценные механизмы авторизации приложения. Параллельно настройте базовые security headers — см. гайд по заголовкам безопасности.
Готовые шаблоны «скопируй-вставь»
Nginx: весь сайт под паролем + allowlist
server {
listen 443 ssl;
server_name example.com;
satisfy any;
allow 203.0.113.10;
deny all;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
root /var/www/example.com;
index index.html index.php;
}
Apache: .htaccess с обходом по IP
AuthType Basic
AuthName "Restricted"
AuthUserFile /etc/apache2/.htpasswd
<RequireAny>
Require ip 203.0.113.10
Require valid-user
</RequireAny>
Итоги
HTTP Basic Auth — быстрый, универсальный и предсказуемый способ закрыть сайт или разделы на уровне веб-сервера. Для совместимости генерируйте .htpasswd с APR1/MD5, храните его вне docroot, а доверенным командам добавляйте allowlist по IP. Не забывайте про HTTPS, реальные IP за прокси и логи — и защита сработает без сюрпризов.


