Перейти к основному содержимому

Работа с auth_basic в nginx. На что обратить внимание

· 5 мин. чтения
Иван Давыдов

Расскажу про использование директивы auth_basic для включения/отключения базовой аутентификации в nginx. Как она работает, и что может заставить её работать не так, как вы ожидаете.

NGINX

Как это работает и для чего вообще нужно?

Часто бывают случаи, когда нужно обернуть веб-сервер в дополнительный слой защиты, которым может стать базовая http аутентификация.

По сути вся базовая http аутентификация заключается в добавлении клиентом к запросу хедера Authorization со строкой Basic $credentials, где $credentials это закодированные в base64 логин и пароль в формате login:password. Пример полного хедера: Authorization: Basic YWRtaW46dGVzdA==.

В случае, если клиент пользуется веб браузером для получения доступа к ресурсам, то ему браузер предложит ввести пароль в специальное окно.

Basic Auth

После ввода браузер запомнит учетные данные для этого сайта и в запросы всех остальных ресурсов будет автоматически помещать логин и пароль, которые вы ввели при заходе. Но если на один из запросов вернётся статус код 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 – переписанный урл уйдёт в папку статики и базовая аутентификация не запросится.

Пример с proxy_pass
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;
}
Пример с try_files
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;
}