У меня проблемы с преобразованием файлов .htaccess в nginx. У меня 3 файла .htaccess. Первый файл .htaccess находится в корне документа и выглядит следующим образом:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^img-(.*)\.html img.php?id=$1 [L]
RewriteRule ^slide-(.*)\.html slider.php?id=$1 [L]
RewriteRule ^page-(.*)\.html page.php?name=$1 [L]
RewriteRule ^contact\.html$ contact.php [QSA,L,NC]
Второй файл .htaccess находится в папке с именем upload:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?foo\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule .*\.(jpe?g|gif|bmp|png)$ nohotlink.gif [L]
<Files ~ "\.(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)$">
order allow,deny
deny from all
</Files>
И третий и последний файл .htaccess находится в подкаталоге папки загрузки с именем "small":
RewriteEngine Off
Теперь я создал папку в / etc / nginx под названием includes и сделал 3 отдельных файла .access с этими правилами перезаписи:
Для первого файла .htaccess, расположенного в корневом каталоге документа, я создал файл в / etc / nginx / includes с именем root.access. В этом файле у меня есть:
# nginx configuration
location /img {
rewrite ^/img-(.*)\.html /img.php?id=$1 break;
}
location /slide {
rewrite ^/slide-(.*)\.html /slider.php?id=$1 break;
}
location /page {
rewrite ^/page-(.*)\.html /page.php?name=$1 break;
}
location /contact {
rewrite ^/contact\.html$ /contact.php break;
}
Для второго файла, находящегося в папке «upload», я создал файл в / etc / nginx / includes под названием upload.access. Этот файл содержит следующее:
# nginx configuration
location /upload {
if ($http_referer !~ "^http://(.+\.)?foo\.com/"){
rewrite .*\.(jpe?g|gif|bmp|png)$ /nohotlink.gif break;
}
}
location ~ \.(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)$ {
deny all;
}
А для третьего и последнего файла я создал файл в / etc / nginx / с именами small.access. Содержимое этого файла следующее:
# nginx configuration
location /upload/small {
}
В файле конфигурации серверного блока у меня есть:
location / {
try_files $uri $uri/ /index.php;
include /etc/nginx/includes/root.access;
}
location /upload {
include /etc/nginx/includes/upload.access;
}
location /upload/small {
include /etc/nginx/includes/small.access;
}
Теперь с этой конфигурацией при попытке сайта я получаю 403 ошибки. Отчеты журнала ошибок Nginx:
[error] 18156#0: *7 access forbidden by rule, client: 111.**.**.**, server: foo.com, request: "POST /upload.php HTTP/1.1", host: "foo.com", referrer: "http://foo.com/"
Теперь под apache все работает без проблем. Но я не могу понять, почему я получаю ошибку 403. Я также обеспокоен тем, что правила перезаписи, как я их сформулировал, помимо ошибки 403, вообще не будут работать должным образом. Кто-нибудь может мне с этим помочь? Я не вижу, что здесь не так.
Это стандартное поведение nginx для этой части вашей конфигурации:
location /upload {
if ($http_referer !~ "^http://(.+\.)?foo\.com/"){
rewrite .*\.(jpe?g|gif|bmp|png)$ /nohotlink.gif break;
}
location ~ \.(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)$ {
deny all;
}
}
Зачем?
Позвольте мне пояснить, как работают локации: когда nginx читает файлы конфигурации, он сортирует блоки локаций по трем типам:
location = /upload { }
location /upload { }
location ~ /upload { }
Как только запрос приходит в nginx, процесс выбора местоположения выглядит следующим образом:
Итак, в вашем случае блок местоположения, соответствующий .php
расширение имеет приоритет над блоком местоположения, соответствующим /upload
часть URI.
редактировать : Пояснение к решению, добавлено альтернативное решение.
Используя ^~
вы можете указать nginx изменить его поведение на шаге 2, чтобы он немедленно использовал совпадающее префиксное местоположение, минуя поиск местоположений по регулярным выражениям. Итак, у вас есть 2 решения:
Решение 1 :
upload.access:
if ($http_referer !~ '^http://(.+\.)?foo\.com/') {
rewrite '.*\.(jpe?g|gif|bmp|png)$' '/upload/nohotlink.gif' break;
}
if ($uri ~ '\.(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)$') {
return 403;
}
тот же серверный блок
Решение 2 :
upload.access:
if ($http_referer !~ '^http://(.+\.)?foo\.com/') {
rewrite '.*\.(jpe?g|gif|bmp|png)$' '/upload/nohotlink.gif' break;
}
location ~ \.(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)$ {
deny all;
}
серверный блок:
location ^~ /upload {
include /etc/nginx/includes/upload.access;
}
Теперь ваша текущая конфигурация ни к чему не приведет, если вы не настроите место для пересылки обработки файла php: проверьте nginx модуль fastcgi. Затем вам нужно будет изменить правила перезаписи в файле root.access, чтобы они не разрешались в контексте текущего местоположения (т.е. создать одно уникальное резервное местоположение и изменить break
к last
чтобы указать nginx снова запустить процесс выбора местоположения после перезаписи).