1. 1
  2. 2
  3. 3
  4. 4
  5. 5

# конспект · шаг 5 из 5

Конспект: PHP и FastCGI

выжимка - её можно унести в заметки

PHP через FastCGI - другой контентный обработчик, но те же правила выбора location.

Минимальный рабочий конфиг

root  /var/www/shop;
index index.php index.html;

location / {
    try_files $uri $uri/ /index.php?$args;
}

location ~ \.php$ {
    try_files $uri =404;                     # без этого - исполнение чужих файлов
    include      fastcgi_params;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
Форма fastcgi_pass Когда
unix:/run/php/php8.3-fpm.sock php-fpm на этой же машине - быстрее
127.0.0.1:9000 php-fpm в другом контейнере

Ключевые строки

  • SCRIPT_FILENAME говорит php-fpm, какой файл выполнять. Забыл - клиент получает File not found. и 404 при живом файле, а в логе php-fpm имя скрипта пустое. Старое «Primary script unknown» в этом случае свежий php-fpm уже не пишет.
  • try_files $uri =404; в php-локации проверяет, что файл существует, до передачи интерпретатору. Это рубеж на стороне nginx, не зависящий от настроек PHP.

Два рубежа, а не один

Что закрывает nginx php-fpm
несуществующий скрипт в конце пути try_files $uri =404 security.limit_extensions
чужое расширение (photo.jpg) отдельный блок на каталог security.limit_extensions (умолчание .php .php3 .php4 .php5 .php7)
загруженный shell.php location ~ ^/uploads/.*\.php$ { deny all; } ничего

Замер: при ослабленном limit_extensions наивный конфиг выполнил картинку (200 и код из неё), а конфиг с try_files вернул 404, не дойдя до php-fpm. cgi.fix_pathinfo в PHP 8.3 по-прежнему On, то есть механизм на месте.

Ловушки джокера

  • fastcgi_param наследуется целиком или никак. Свой параметр в location отменяет весь набор сверху; симптом - ответ 200 с пустым телом. include fastcgi_params; пишут в том же блоке, где стоят свои параметры.
  • try_files не защищает от загруженного shell.php - файл существует, и проверка его пропустит. Каталог загрузок закрывают отдельным блоком выше общей регулярки: из двух регулярок побеждает первая совпавшая.
  • Забытый блок ~ \.php$ отдаёт исходники клиенту вместе с паролями к базе.
  • try_files в php-локации не отдаёт файл клиенту - он только проверяет наличие, а файл уходит контентному обработчику.
  • Пределы правят с двух сторон: client_max_body_size против upload_max_filesize, fastcgi_read_timeout против max_execution_time.

Комментарии

Пока нет комментариев. Будь первым!

Оставить комментарий

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