У меня есть приложение, развернутое в тестовом режиме на сервере. Доступ к нему был ограничен определенной группой пользователей через HTTP-аутентификацию. Это нормально работает. Проблема в том, что если я обслуживаю статические файлы с помощью другой директивы «location», nginx дает мне «Not Authorized» для этих файлов. Я пробовал auth_basic выключить, но без кубиков.
Вот конфиг vhost:
# Virtual Host
upstream appname {
server 127.0.0.1:4000;
server 127.0.0.1:4001;
server 127.0.0.1:4002;
}
server {
listen 80;
server_name appname.domain.com;
# write app specific log
# make sure you create this file in your log directory before running behind nginx
access_log /home/apps/appname/shared/log/nginx.log main;
# let nginx serve static files directly
# images
location ^~/images {
auth_basic off;
root /home/apps/appname/current/public/images;
}
location ^~/covers {
auth_basic off;
root /home/apps/covers;
}
# # javascript
location ^~/javascripts {
auth_basic off;
root /home/apps/appname/current/public/javascripts;
}
# # css
location ^~/stylesheets {
auth_basic off;
root /home/apps/appname/current/public/style;
}
# Push all other requests to Merb
location / {
# needed to forward user's IP address to merb
proxy_set_header X-Real-IP $remote_addr;
auth_basic "domains";
auth_basic_user_file htpasswd;
if (!-f $request_filename) {
proxy_pass http://appname;
break;
}
}
}
Какие-либо предложения ?
РЕДАКТИРОВАТЬ:
Я попытался поместить изображения в другой поддомен и настроить для него отдельный блок «server» - без http_auth. Но он все равно дает мне 403 запрещено на изображении! Вот что я добавил:
server {
listen 80;
server_name images.domain.com;
access_log /home/apps/appname/shared/log/nginx_images.log main;
error_log /home/apps/appname/shared/log/nginx_images_error.log;
error_page 500 502 503 504 /500.html;
location = /500.html {
root /home/apps/www/http_error_codes;
}
location /images {
root /home/apps/appname/current/public/images;
}
location /covers {
root /home/apps/covers;
}
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
}
Я также попытался открыть новый браузер и получить доступ к файлу изображения прямо с images.domain.com, но он по-прежнему говорит, что 403 запрещено!
Я не уверен, что тебе нужно
auth_basic off
в областях, в которых вы не хотите выполнять аутентификацию. В документации говорится, что это служит для «переопределения действия для наследуемого от директивы более низкого уровня», но ваша родительская директива в этом случае (серверный блок) не содержит никаких директив auth.
Это может быть ошибка, когда вы пытаетесь отключить унаследованную аутентификацию без ее включения, вы включаете ее (возможно, это буквально просто немного переворачивается?), Но я бы предложил удалить этот оператор из ваших статических местоположений.
Насколько я могу судить, ваше использование ^ ~ в местах на самом деле ничего не делает, потому что у вас нет соответствия регулярным выражениям в серверном блоке. Если вы посмотрите на описание порядка разрешения здесь:
http://wiki.nginx.org/NginxHttpCoreModule#location
Вы увидите, что использование ^ ~ предотвращает проверку местоположений, указанных в регулярном выражении. Далее на этой странице документации вы увидите, что для буквальных совпадений nginx выбирает «лучшее» совпадение, где «лучший» обычно является буквальным совпадением с самым длинным совпадением подстроки. В чем я не уверен, так это в том,
location /foo
лучше, чем
location ^~ /foo
хотя оба являются буквальными совпадениями, к последнему просто прилагается подсказка. Но поскольку вам не нужен бит ^ ~ в вашей текущей настройке, попробуйте отбросить его и посмотреть, проясняет ли он ситуацию. Конечно, если вы предоставили нам отредактированную конфигурацию для пояснения и у вас есть совпадения ~ или ~ * в вашем блоке, это вам не поможет.
Если ничего из этого не работает, попробуйте переместить
auth_basic
и
auth_basic_user_file
операторы в серверный блок. Тогда положи свой
auth_basic off
операторы в статические местоположения, где они будут отключать то, что вы включили.
== ОБНОВЛЕНИЕ ==
Этот простой пример работает для меня под 0.7.61:
server { listen 80; server_name test.domain.com; access_log /var/log/nginx/sites/test.domain.com/access.log; error_log /var/log/nginx/sites/test.domain.com/error.log; location /images { root /srv/www/sites/test.domain.com; } location / { root /srv/www/sites/test.domain.com; index index.html; auth_basic test; auth_basic_user_file /etc/nginx/auth/test.htpasswd; if ( -f $request_filename ) { expires 30d; break; } } }
В каталоге сайта у меня есть только index.html и графический файл в / images. Если я перейду к /images/filename.jpg в новом сеансе браузера, он появится без ошибок. Если затем перейти в корень сайта, я получаю запрос аутентификации. Если я затем вернусь к изображению, в моем журнале будет показано аутентифицированное имя пользователя (где первый запрос только что показал "-")
Трассировка пакета показывает, что информация об аутентификации была предложена браузером с помощью GET /images/filename.jpg (не было запроса 401). Я предполагаю, что nginx регистрирует предлагаемое имя пользователя, независимо от того, требовалось ли оно специально для получения файла (и, конечно же, поскольку проблема была против /, браузер должен предоставить введенные пользователем учетные данные для /images/filename.jpg).
Очевидно, что мой пример не включает проксирование, но базовая функциональность есть.
Одна ошибка, которую я сделал вначале при тестировании (что и вы сделали), - это включить подкаталог блока местоположения в корневую директиву. Обратите внимание на то, что корень для / images и / одинаков - nginx добавит подкаталог при попытке получить файл.
Если я сделаю корневой параметр для блока / images include / images, я получу ошибку 404, пытающуюся перейти к jpg из нового сеанса браузера (без запроса аутентификации). Интересно, не вызывает ли ваша настройка прокси-сервера запрос, который перехватывается блоком /, а не (как в моем примере) проваливается через нижнюю часть конфигурации?
Попробуйте передать ваши файлы пользователю, запускающему nginx (я полагаю, www-data)