тупая ошибка конфигурации nginx

grigori

( ͡° ͜ʖ ͡°)
Команда форума
nginx+php, тяжелый конфиг nginx с проксированием, пачкой редиректов и субдоменов,
долго дебажил одну глупую проблему: запрос обрабатывается, а ответа нет.

Код:
location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.*)$;

    if (!-f $PROJECT_PATH/$RELEASE/php_htdocs$fastcgi_script_name){
        return 404;
    }

    fastcgi_param SCRIPT_FILENAME $PROJECT_PATH/$RELEASE/php_htdocs$fastcgi_script_name;
    fastcgi_pass  $fcgi;

    #PATH_INFO and PATH_TRANSLATED can be omitted, but RFC 3875 specifies them for CGI
    fastcgi_param  PATH_INFO        $fastcgi_path_info;
    fastcgi_param  PATH_TRANSLATED  $PROJECT_PATH/$RELEASE/php_htdocs$fastcgi_script_name;

    #Pass the request host name, not the first listed in the server_name.
    fastcgi_param  SERVER_NAME        $host;
}
делаю запрос на test.php - пустой ответ и пустые логи.
включил все логи на максимальные уровни, catch_workers_output = yes, display_errors = on, и нифига, 200й ответ нулевой длины
в access.log GET /test.php HTTP/1.1" 200 31 "-", в errors.log пусто, в php-fpm.www.access.log "- " 200 /opt/www/test.php
то есть fpm запрос получает, файл находит, а результата исполнения нет :)
долго смотрел на все это как баран на новые ворота пока не заметил, что не подключил fastcgi_params.

Еле догадался по access_log fpm, который никогда не включается, что в php не передается тип запроса, должен быть "GET ", а не "- ". Хрен отдебажишь!
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
С локейшеном \.php$ fastcgi_split_path_info не имеет смысла.

Вообще, хорошая практика - не инклюдить стандартный fastcgi_params, дописывая параметры в location, а делать sitename-fastcgi.conf для каждого случая, когда набор параметров отличается от стандартного хотя бы одной переменной. Намного меньше путаницы.

Так лучше вообще не делать, проксирование на аргумент, заданный переменной - это совсем отдельный режим, со своим багодромом, и несколько медленнее. Вообще переменные в nginx не надо использовать как макросы, лучше в таких случаях генерировать конфиг (я это делаю обычным php-скриптом).
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
Дебажить fastcgi, кстати, легко через socat:

socat UNIX-LISTEN:/var/tmp/php-fpm.sock STDIN

Вполне читаемо. На всякий случай можно на od/hexdump запайпить.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
спасибо за подсказки

c fastcgi_pass $fcgi цель - чтобы у всех был одинаковый конфиг, в котором редактируются верхние 5 строк с путями.
конфиг большой, сложный - 6 файлов, несколько доменов, пачка субдоменов, десятки редиректов,

раньше вообще все было разнесено между конфигом и приложением - найти что-то было нереально, сведение структур сайтов на одинаковые пути заняло у меня 2 итерации, до canonical еще не добрались даже,
каждый раз как я что-то меняю - у всех проблема обновить была, а щас я вынес один общий инклюд, конфиги стали маленькие, все включил в git, и каждый теперь сможет сам поставить себе актуальный конфиг

в общем, все это генерировать из php тоже как-то неуютно, для production уберу лучше

>\.php$ fastcgi_split_path_info
да, забыл убрать, еще вчера там было \.php(\\.*)?$
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
С конфигами nginx в чистом виде есть проблема разделения ответственностей: в одном файле - и работа сисадмина, и работа программистов. Как следствие - проблема с раздельным деплоем кода и конфигурации.
Генерация и вынос шаблонов конфигов в отдельный репозиторий хоть как-то позволяют это сгладить.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
получается свой конфиг для шаблонизатора конфига nginx под каждого разработчика
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
fixxxer, а ты не знаешь ли, почему
Код:
location /img/ {
  root $html_root;
   try_files $uri /;
}
если не находит файл - не отдает обработку в location /, а возвращает 301 Location / ?

в то же время try_files $uri /index.php; уходит на обработку в php
 

fixxxer

К.О.
Партнер клуба
Помимо fastcgi_split_path_info еще надо, чтобы до fpm доходили запросы на несуществующие php-файлы.
В общем, довольно экзотическая конфигурация.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
я бы не назвал экзотической конфигурацию c `location ~ \.php$ { fastcgi_split_path_info`, она предложена, например, в доке nginx для wordpress,
а cgi.fix_pathinfo=1 по дефолту
надо не забывать, что wordpress - это 33% всех активных сайтов мира

а почему ты считаешь, что это касается запросов к несуществующим файлам?
 

fixxxer

К.О.
Партнер клуба
а почему ты считаешь, что это касается запросов к несуществующим файлам?

Of course, there are factors that can prevent exploitation even if fastcgi_split_path_info is present. For example, if nginx and php-fpm share the same filesystem, one can first check the script actually exists, so the malicious request will never make it to php-fpm (it is usually done using something like `try_files $uri =404`). Or there may be cgi.fix_pathinfo=0 --- it will also prevent exploitation. Both settings are present in a lot of config snippets back from the days when php-fpm didn't check extensions of the scripts, but now it does, so some more recent configs lack the checks.
Почему так, я не вникал, поверю на слово.

Там try_files есть
 

fixxxer

К.О.
Партнер клуба
Я, кстати, отправлял патчи, чтобы избавиться от fix_pathinfo, еще лет наверное 10 или 12 назад, но все боятся сломать совместимость с каким-нибудь экзотическим веб-сервером.
 

fixxxer

К.О.
Партнер клуба
А, я не тот пример смотрел. В том, который multisite, правильно.

Впрочем, и в первом есть комментарий, где говорится, что надо выставить fix_pathinfo=0.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
да, я когда-то прямым текстом написал в доке по yii, что fix_pathinfo надо отключить, но по дефолту-то он 1 🤷‍♂️

дыра шикарная, лет 15 ей уже
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
Кстати, этот кусок кода скопипащен из sapi/cgi, и там явно та же дыра, судя по коду :)

Не факт, что можно проэксплоитить, проверять лень, но потенциально да.

Хотя, кого волнует cgi sapi?
 

AnrDaemon

Продвинутый новичок
Будешь ржать, но не далее как месяц назад видел шаред с CGI SAPI.
 
Сверху