Работа с auth_basic в nginx. На что обратить внимание
Расскажу про использование директивы auth_basic
для включения/отключения базовой аутентификации в nginx.
Как она работает, и что может заставить её работать не так, как вы ожидаете.
Как это работает и для чего вообще нужно?
Часто бывают случаи, когда нужно обернуть веб-сервер в дополнительный слой защиты, которым может стать базовая http аутентификация.
По сути вся базовая http аутентификация заключается в добавлении клиентом к запросу хедера Authorization
со строкой Basic $credentials
, где $credentials
это закодированные в base64 логин и пароль
в формате login:password
. Пример полного хедера: Authorization: Basic YWRtaW46dGVzdA==
.
В случае, если клиент пользуется веб браузером для получения доступа к ресурсам, то ему браузер предложит ввести пароль в специальное окно.
После ввода браузер запомнит учетные данные для этого сайта и в запросы всех остальных ресурсов будет автоматически
помещать логин и пароль, которые вы ввели при заходе. Но если на один из запросов вернётся статус код 401 Unauthorized
– придётся вводить логин и пароль заново.
Как этим пользоваться в nginx?
Для того, чтобы включить базовую аутентификацию в nginx для всего виртуального сервера достаточно в контекст server
добавить следующие директивы:
auth_basic "auth"; # обозначает защищаемую область.
# Также должен выводиться пользователю в окне ввода
# логина и пароля, но лично ни разу такого не видел)
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
В auth_basic_user_file
нужно указать путь до файла, в котором будут указаны учетные данные для доступа. Файл должен
быть создан при помощи утилиты htpasswd от Apache. Подробнее читать тут.
Так же директиву auth_basic_user_file
можно указывать в location
, http
и limit_except
блоках.
Для отключения базовой аутентификации для конкретных ресурсов
достаточно добавить следующий блок в location
.
auth_basic off;
С отключением иногда могут возникнуть проблемы, о них я расскажу ниже.
На что следует обратить внимание
И так, существуют варианты конфигураций, при которых включение или отключение basic auth работать не будет.
1. Использование с директивой return
Эта директива сработает вне зависимости от того, включена или выключена базовая аутентификация.
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
# всегда будет возвращать 200, несмотря та то,
# что локейшон наследует базовую аутентификацию
location = /test {
return 200 "success";
}
2. Использование с директивой rewrite
Надо понимать, что rewrite
перепишет ваш урл и направит
на другой локейшон, и если в этом локейшоне не отключен auth_basic
, то у клиента всё равно
запросит логин и пароль.
Но в сочитании с директивой proxy_pass
переписанный локейшон сразу перейдёт в проксю,
и, соответственно, запроса на аутентификацию не будет (если у ресурса,
который указан в proxy_pass
нет своей аутентификации. Смотреть в пункте 3).
Тоже самое с try_files
– переписанный урл уйдёт в папку статики и базовая
аутентификация не запросится.
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
# Перебросит на location /todos, но так как у todos
# не отключена базовая аутентификация, то /link будет её запрашивать
location /link {
auth_basic off;
rewrite ^/link/(.+?)$ /todos/$1 break;
}
location /todos {
proxy_pass https://jsonplaceholder.typicode.com;
}
# Перепишет урл и отправит его в проксю. Базовая
# аутентификация не будет запрошен а.
location /rewrited_todos {
auth_basic off;
rewrite ^/link/(.+?)$ /todos/$1 break;
proxy_pass https://jsonplaceholder.typicode.com;
}
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
root /usr/share/nginx/html;
# Перепишет урл и отправит его в папку
# статики за файлом. Базовая
# аутентификация не будет запрошена.
location /static {
auth_basic off;
rewrite ^/static/(.+?)$ /$1 break;
try_files /$uri =404;
}
3. Использование с директивой proxy_pass
Тут особо говорить нечего. Просто помните, что бэкенд, на который ведёт проксипас, может быть скрыт под своей базовой аутентификацией.
4. Использование с директивой error_page
Директива отвечает за обработку ошибок и переброс на нужную fallback-страничку.
# На все перечисленные ошибки nginx будет возвращать
# error.html страничку из директории со статикой.
error_page 400 403 404 500 501 502 503 504 /error.html;
Используя её в связке с auth_basic
стоит обратить внимание на то,
что если локейшон с отключенной аутентификацией отдаст ошибку, которая
обработается этой директивой и у этой страницы будет включена базовая аутентификация, то
и ваш локейшон её запросит. Помните, что error_page
может указываться не только для конкретного локейшона,
но и для всего сервера.
auth_basic "auth";
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
error_page 400 403 404 500 501 502 503 504 /error.html;
# При запросе несуществующего ресурса (например /todos/2223424), вернётся 404,
# которая обработается директивой error_page и вернёт error.html
# для которого включена basic auth.
# Соответственно и этот локейшон в таком случае запросит аутентификацию.
location /todos {
auth_basic off;
proxy_ssl_server_name on;
proxy_intercept_errors on;
proxy_pass https://jsonplaceholder.typicode.com;
}
5. Использование с директивой try_files
Используя try_files
смотрите, куда вы отправляете nginx за статикой. Вы можете
создать локейшон с auth_basic off
и try_files
, который будет доставать статику из защищённого
базовой аутентификацией контекста, и в таком случае отключение basic auth в вашем локейшоне работать не будет.
auth_basic "auth";
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
root /usr/share/nginx/html;
# Базовая аутентификация все равно будет запрашиваться,
# так как try_files будет запрашивать
# файлы у рутовой директории, которая защищена basic auth.
location ^~ /htmls {
auth_basic off;
rewrite ^/htmls/(.+?)$ /$1 break;
try_files /$uri =404;
}