[Nginx] Сторонний PHP-форум на сайте с ЧПУ

xintrea

Новичок
[Nginx] Сторонний PHP-форум на сайте с ЧПУ

Здравствуйте!


Имею сайт с ЧПУ, который отображается по следующим правилам:

- Если это картинка или архив, файл выдается напрямую
- В остальных случаях УРЛ вида http://site.ru/site/page/index преобразуется в http://site.ru/index.php?site/page/index.

Эти правила описаны в конфигурации следующим образом:

Код:
location / {
 root   /var/www/webhamster;
 index  index.html index.htm;

 if (!-f $request_filename) {
  rewrite ^(.*) /index.php?$1 last;
 }
}

location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|txt|js|zip|rar|tar.gz)$
{
}

location ~ \.php$ {
 fastcgi_pass   127.0.0.1:8888;
 fastcgi_index  index.php;
 include fastcgi_params;
 fastcgi_param  SCRIPT_FILENAME /var/www/webhamster$fastcgi_script_name;
}
Теперь нужно, чтобы на сайте отображался форум punbb. Я положил его в директорию /punbb относительно корня сайта (т.е. абсолютный путь - /var/www/webhamster/punbb). И теперь не могу понять, как его отображать таким образом, чтоб на него не действовали правила преобразования ЧПУ.

Я пробовал дописать вот так (регвыр пока просто "punbb" чтоб срабатывало наверняка):

Код:
location ~* punbb
{
}
но толи реврайт в "location /" всеравно срабатывает, ибо "location /" имеет более высокий приоритет (так ли это?), либо еще что-нибудь, может быть последовательность описания локаций имеет влияние, хотя я перемещал по-всякому, в общем, эффекта нет.

При открытии URL "site.ru/punbb" я вижу либо попытку вызвать скрипт по ЧПУ, либо "403 Forbidden". Думал, дело в правах, но права выставлены по той же схеме, что и у основного сайта. Видимо, это из-за того, что нужно прописать опцию index, пока не знаю.

При открытии URL "site.ru/punbb/index.php", файл index.php отдается напрямую (то есть без выполнения). То есть, на "location ~ \.php$" с FastCGI бакэндом обработка не переходит (а из "location /" волшебным образом переходит).

Тогда я прописал так:

Код:
location ~* punbb
{
 if (!-f $request_filename) {
  rewrite ^(.*) $1 last;
 }
}
В этом случае при открытии URL "site.ru/punbb/index.php" выдается ошибка "500 Internal Server Error". А в логе ошибка:

[error] 7323#0: *1 rewrite or internal redirection cycle while processing "/punbb/"
В общем, вопрос - как в моем случае написать конфигурацию, чтобы работал сторонний форум, и в нем не срабатывали изменения урла, описанные для всех остальных страниц сайта?
 

fixxxer

К.О.
Партнер клуба
ужас!
http://nginx.org/en/docs/http/converting_rewrite_rules.html

Код:
root   /var/www/webhamster;

location / {
 index  index.html index.htm;
 try_files $uri @php_main;
}

location @php_main {
 fastcgi_pass   127.0.0.1:8888;
 include fastcgi_params2; // там убираем QUERY STRING
 fastcgi_param QUERY_STRING $uri;
 fastcgi_param  SCRIPT_FILENAME $document_root/index.php;
}

location /punbb/ {
    location ~ \.php {
        fastcgi_pass   127.0.0.1:8888;
        fastcgi_index  index.php;
        include fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
    location ~ ^ {}
}
кактатак.
 

xintrea

Новичок
Конечно ужас. Еще ужаснее, что http://nginx.org/ru/docs/http/conve...rite_rules.html -> 404: not found. Я, конечно, понимаю, что rewrite Сысоев не рекомендует пользоваться, но вменяемого объяснения как надо делать по-другому нигде не нашел. Только куски конфигов, без объяснений что к чему.


Вот объясните мне, как строка

Код:
try_files $uri @php_main;
позволяет напрямую отдавать файлы _только_ типов jpg|jpeg|gif|png|ico|css|txt|js|zip|rar|tar.gz? А какой-нибудь .sh или файл без расширения не будет попадать под это правило. Как? Еще не ясно, почему при прямом обращении к php файлу (без ЧПУ), он не будет отдаваться явном виде, а включится его обработка через FastCGI?


Далее неясно, зачем убирать QUERY STRING (кстати, как это делать??), если следующей опцией QUERY STRING переопределяется?

Код:
include fastcgi_params2; // там убираем QUERY STRING
fastcgi_param QUERY_STRING $uri;

Что обозначает символ "@" перед локацией?


Кроме того, я излазил русскую документацию (http://sysoev.ru/nginx/docs/), и не нашел, откуда берется переменная $uri. Что она содержит? Да и с $query_string, $request_uri и всякими другими не все ясно. Нигде не описано, что конкретно они содержат, на примере хотя бы одного URL. Даже раздела в документации такого нет - "Встроенные переменные" или что-то похожее.
 

fixxxer

К.О.
Партнер клуба
>> А какой-нибудь .sh или файл без расширения не будет попадать под это правило. Как?

Будет конечно. Не надо такие файлы класть в докрут, их надо класть вне него.

Но если конечно бардак, а разгребать его религия не позволяет - то надо хотя бы решить что с такими урлами делать. Отдавать 403? 404? Или как?

На мой взгляд, гораздо проще не держать в root ничего, кроме статики (UPD если index.php там же то надо либо для него добавить location либо (лучше) положить где то отдельно).

>> Даже раздела в документации такого нет - "Встроенные переменные" или что-то похожее.

А это что?

http://sysoev.ru/nginx/docs/http/ngx_http_core_module.html#variables

-~{}~ 06.09.10 15:26:

http://sysoev.ru/nginx/docs/faq.html
http://sysoev.ru/nginx/docs/http/ngx_http_core_module.html#location
 

xintrea

Новичок
>> А какой-нибудь .sh или файл без расширения не будет попадать под это правило. Как?

> Будет конечно. Не надо такие файлы класть в докрут, их надо класть вне него.

Ну ладно, но ведь будет еще и доступ напрямую к PHP скриптам, если написать их не через ЧПУ. То есть, содержимое всех скриптов можно посмотреть. Как это заблокировать?

Ну и кроме того, прописав ваш конфиг, имею ошибку при старте nginx:

unknown directive "try_files" in /etc/nginx/sites-enabled/webhamster_ru:32
Ничего внятного поиск не показывает.
 

Gas

может по одной?
Ну ладно, но ведь будет еще и доступ напрямую к PHP скриптам, если написать их не через ЧПУ. То есть, содержимое всех скриптов можно посмотреть. Как это заблокировать?
fixxxer же писал уже:
Не надо такие файлы класть в докрут, их надо класть вне него.
или пропиши
location ~ \.php {
deny all; # or error_page 404 /404_url.html
}


unknown directive "try_files"
очень возможно что старая версия nginx'а, директива доступна с версии 0.7.27

p.s. хотя мне тоже кажется чпу в nginx через try_files каким-то официальным костылём, приходится для error_log указывать уровень ошибок error.
 

xintrea

Новичок
> хотя мне тоже кажется чпу в nginx через try_files каким-то официальным костылём, приходится для error_log указывать уровень ошибок error.

Угу.

Опция try_files открывает все что можно на сервере для доступа извне. И нужно дополнительно прописывать, к чему доступа быть не должно через опцию вида location ~ \.php {deny all}. Это же дурдом!

А нужно чтобы было наоборот - открывать доступ только для того, что конкретно разрешено.

Хорошо что я додумался дописать location ~ \.db {deny all} для файлов SQLite баз, а то бы они так наружу и торчали бы.
 

xintrea

Новичок
Автор оригинала: fixxxer
Дурдом - это класть эти файлы в docroot.
В docroot кроме index.php ничего и нет. Просто настройка в стиле

Код:
location / {
 index  index.html index.htm;
 try_files $uri @php_main;
}
открывает доступ на все файлы. Хочешь - получи по прямому линку содержимое любого php в любом подкаталоге. Хочешь - SQLite базу, если знаешь где она лежит. Я проверил - так и есть. Поэтому и приходится закрывать опциями:

Код:
location ~ \.php {deny all}
location ~ \.db {deny all}
То есть, вместо того, чтобы открыть только то что нужно, как это делается при rewrite и

Код:
location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|txt|js|zip|rar|tar.gz)$ {}
... метод без rewrite наоборот - открывает все файлы на сервере, и нужно блокировать то, что не должно быть видно вовне, специальными правилами. Вот в чем дурдом.
 

fixxxer

К.О.
Партнер клуба
ну я ж там написал, что надо .php наружу или явно лоекйшеном... класть *.php (а тем более .db) в одно дерево каталогов со статикой - плохая привычка :)

я делаю так:

project
/static
/lib
/data
/...
index.php

set $_app_root /var/www/project;
root $_app_root/static;

/ {
try_files $uri @php;
}

@php {
...
SCRIPT_FILENAME $_app_root/index.php;
...
}

А если все в куче - то, конечно, надо в явном виде прописывать.

Хотя и для всяких говнодвижков мне обычно хватает единственного regexp-локейшена на ~ "\.php" (а каталоги с данными явно закрываются указаниями прямо на них в локейшенах, вида location /data/ { return 403;}.
 

xintrea

Новичок
> ну я ж там написал, что надо .php наружу или явно лоекйшеном... класть *.php (а тем более .db) в одно дерево каталогов со статикой - плохая привычка

Я нижуя не понял! Может быть пора старожилу научиться ставить знаки препинания и начинать предложения с большой буквы?
 
Сверху