Вопрос или проблема
Работаю с nginx версии 1.27.2 и php-8.3.14 на openSUSE Tumbleweed. Проблема заключается в следующем. Обычно у меня есть несколько каталогов под веб-сервером, с которым я работаю для целей разработки. Я долгие годы был пользователем/администратором Apache, но только использовал nginx на Raspberry Pi и т.д., где мне было важно лишь обслуживать файлы из корневого каталога документов. С Apache вы просто определяете <Directory>
и устанавливаете autoindex
, и PHP может обрабатывать файлы на любом уровне. Я не могу заставить это работать в nginx.
Я решил настроить nginx на своем ноутбуке, чтобы отразить функциональность, которую я имею с Apache на различных серверах. Основная настройка и конфигурация php-fpm работают нормально. Проблема в том, что когда я создаю локейшен для тестовых каталогов с autoindex, я могу нормально перемещаться по структуре каталогов, но PHP не может найти файл для загрузки несмотря на то, что он определяет точный файл для загрузки, как показано в журналах доступа и ошибок.
Я, вероятно, просмотрел 20 сообщений здесь и на StackOverflow и в блогах, например, PHP-приложения в подкаталогах в Nginx, руководство nginx по, например, $request_filename и location, но все сообщения имеют вариацию того, что PHP не открывает мой файл или php-fpm не может найти файл, не рассматривая, как это сделать на уровне нескольких каталогов.
Я перепробовал почти все варианты fastcgi_param SCRIPT_FILENAME $xxxxxx
, и ни один не изменяет ситуацию, записи в журнале не меняются, правильный файл находится и передается в php-fpm, а php-fpm говорит “Не могу найти правильное имя файла, которое вы отправили?”
Папка tmp
в следующем дереве каталогов является папкой для разработки. У меня установлен autoindex
, и я работаю из подкаталогов, чтобы тестировать, разбираться, реализовывать и т.д. …
# tree -d /srv
/srv
├── http
│ ├── cgi-bin
│ ├── css
│ ├── htdocs
│ │ ├── gif
│ │ └── include
│ ├── js
│ ├── sh
│ ├── tmp
│ │ ├── db
│ │ │ └── mongo
│ │ │ ├── css
│ │ │ ├── include
│ │ │ ├── js
│ │ │ └── sav
│ │ └── php
│ │ └── utclocal
│ └── vendor
│ ├── composer
│ ├── mongodb
<snip>
htdocs
является корнем документов, и я могу нормально обслуживать .php
файлы из него. Эта проблема возникла в процессе работы над проблемой обработки даты/времени в журнальном файле, добавления пропущенного года, создания экземпляра date
и конвертации между UTC/местным временем и т.д. из журналов, отправленных с платы Milkv-Duo RISC, которая работает на busybox и не имеет понятия о местном времени. Я настроил autoindex
и базовую аутентификацию на /tmp/
и вложенный location
для обработки .php
файлов. Аутентификация и переход нормальные, но я не могу обслуживать файлы, открывая их с любого уровня ниже /tmp/
.
Конфигурация, которую я использую:
worker_processes auto;
worker_cpu_affinity auto;
events {
multi_accept on;
worker_connections 1024;
use epoll;
}
http {
charset utf-8;
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
log_not_found off;
types_hash_max_size 4096;
client_max_body_size 16M;
keepalive_timeout 65;
include conf.d/*.conf;
server {
listen 443 ssl;
server_name wizard.mydomain.com localhost;
ssl_certificate 'ssl/server.crt';
ssl_certificate_key 'ssl/server.key';
ssl_protocols TLSv1.2;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root /srv/http/htdocs/;
index index.php index.html index.htm;
}
include /etc/nginx/php_fastcgi.conf;
location ~ /css/[^/]+\.css$ {
root /srv/http;
access_log off;
log_not_found off;
}
location /tmp/ {
root /srv/http;
autoindex on;
autoindex_exact_size off;
satisfy all;
allow 192.168.6.0/24;
allow 127.0.0.1;
deny all;
auth_basic "wizard restricted";
auth_basic_user_file /etc/nginx/basic_auth;
location ~ [^/]\.(php|html|txt)(/|$) {
include fastcgi_params;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}
location ~ /js/[^/]+\.js$ {
root /srv/http;
access_log off;
log_not_found off;
}
location ~ /sh/[^/]+\.sh$ {
root /srv/http;
access_log off;
log_not_found off;
}
location = favicon.ico { access_log off; log_not_found off; }
}
include vhosts.d/*.conf;
}
Подключенный php_fastcgi.conf
выглядит следующим образом:
location ~ [^/]\.(php|html|htm)(/|$) {
# 404
try_files $fastcgi_script_name =404;
# default fastcgi_params
include fastcgi_params;
## fastcgi settings
root /srv/http/htdocs/;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
}
location /tmp/
и вложенный location ~ [^/]\.(php|html|txt)(/|$)
являются блоками, которые я пытаюсь разобраться. Каждый раз, когда я нажимаю на .php
файл при перемещении по каталогам под /tmp/
, файл (например, /srv/http/tmp/php/utclocal/utclocal.php
) находится, журналы показывают правильное имя файла, предоставленное правильным родительским каталогом, но затем PHP сообщает об ошибке No input file specified.
в stderr
, жалуясь, что правильное имя файла не может быть найдено. Журналы доступа и ошибок показывают следующее:
access.log
127.0.0.1 - david [26/Nov/2024:18:11:04 -0600] "GET /tmp/php/utclocal/ HTTP/1.1" 200 286 "https://wizard.mydomain.com/tmp/php/" "Mozilla/5.0 (X11; Linux x86_64; rv:132.0) Gecko/20100101 Firefox/132.0" "-"
error.log
2024/11/26 18:11:06 [error] 132925#132925: *3660 FastCGI sent in stderr: "Unable to open primary script: /srv/http/tmp/php/utclocal/utclocal.php (No such file or directory)" while reading response header from upstream, client: 127.0.0.1, server: wizard.mydomain.com, request: "GET /tmp/php/utclocal/utclocal.php HTTP/1.1", upstream: "fastcgi://unix:/run/php-fpm/php-fpm.sock:", host: "wizard.mydomain.com", referrer: "https://wizard.mydomain.com/tmp/php/utclocal/"
Файл, указанный в error.log
, /srv/http/tmp/php/utclocal/utclocal.php
, является вполне правильным файлом, доступен для чтения всем и существует:
$ ls -al /srv/http/tmp/php/utclocal/utclocal.php
-rw-r--r-- 1 david david 1526 Nov 26 16:32 /srv/http/tmp/php/utclocal/utclocal.php
Из прочитанного видно, что есть проблема между вложенным location ~ [^/]\.(php|html|txt)(/|$)
под /tmp/
и location ~ [^/]\.(php|html|txt)(/|$)
, который находится на более высоком уровне и обрабатывает /
. Я думаю, что понимаю приоритет для последней строки префикса в конфигурационном файле, которая сохраняется и управляет порядком, в котором выполняется сопоставление регулярных выражений для lokation, и если точное соответствие найдено, используется этот блок, но если нет, используется блок сопоставления строки префикса.
Здесь я не понимаю, как изменить файл nginx.conf
, чтобы правильно обрабатывать вложенный /tmp/
локейшен, чтобы я мог открывать любые файлы php, html или txt под /tmp/
. Вложенный REGEX для location ~ [^/]\.(php|html|txt)(/|$)
должен совпадать, так что этот блок должен использоваться. По какой-то причине, и, возможно, это проблема с конфигурацией, которую я не вижу, любой .php
, .html
или .txt
файл, на который я нажимаю, не находится php-fpm. Я бы по крайней мере ожидал, что файлы непосредственно под /tmp/
должны обслуживаться, но это не так, и это заставляет меня думать, что ранее определенный локейшен для .php
файлов срабатывает?
Поскольку количество компонентов каталога может варьироваться под /tmp/
, как мне нужно обработать конфигурацию или выполнить перезапись, чтобы имена файлов правильно обрабатывались php-fpm. Нужно ли мне использовать alias
вместо root
или location @rewrite { .. }
? Или я неправильно подхожу к этой вложенной настройке под /tmp/
? Любая помощь будет очень признательна.
Извините за длину вопроса, но я хотел попытаться включить всю соответствующую информацию, необходимую для решения проблемы. Если нужно что-то еще, оставьте комментарий, и я отредактирую и предоставлю все необходимое.
Ответ или решение
Проблема с обработкой PHP-файлов в Nginx при использовании autoindex
Вопрос, который вы поднимаете, связан с настройкой Nginx для корректного отображения PHP-файлов внутри директории с включенным autoindex. Отмеченная вами ошибка "No input file specified." обычно связана с неправильной передачей параметров для PHP-FPM. Давайте детально рассмотрим вашу конфигурацию и предложим возможные решения.
Актуальность проблемы
Работа с Nginx, особенно для пользователей, привыкших к Apache, может стать вызовом. В отличие от Apache, где конфигурация часто происходит через директивы <Directory>
, в Nginx используется более сложная система блоков location
.
Анализ вашей конфигурации
Ваш текущий конфигурационный файл имеет несколько значительных элементов, которые могут вызывать проблемы:
-
Обработка PHP в location /tmp/:
location /tmp/ { root /srv/http; autoindex on; ... } location ~ [^/]\.(php|html|txt)(/|$) { include fastcgi_params; fastcgi_pass unix:/run/php-fpm/php-fpm.sock; fastcgi_param SCRIPT_FILENAME $request_filename; }
-
Используемые переменные:
Вы используете переменную$request_filename
, которая может не совпадать с тем, что ожидает PHP-FPM.
Возможные решения
Чтобы устранить проблему, попробуйте следующие шаги:
-
Используйте корректную передачу SCRIPT_FILENAME:
Измените строку в блоке Nginx для передачиSCRIPT_FILENAME
. Попробуйте следующее:fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
-
Правильный root в директории /tmp/:
Убедитесь, что вы правильно указали путь дляroot
. Если вы используетеroot /srv/http;
, это приводит к тому, что Nginx будет ожидать, что документы располагаются в/srv/http/tmp/
. Однако, на самом деле они в/srv/http/tmp/
, и это может вызвать путаницу. Попробуйте следующий вариант:root /srv/http/tmp;
-
Согласование location блоков:
Вам может понадобиться изменить порядок или пересмотреть структуру ваших блоковlocation
. Вместо использования вложенного блока, можно использовать общий блокlocation
для обработки всех PHP-файлов:location ~ .*\.php$ { root /srv/http/tmp; # Обратите внимание на путь include fastcgi_params; fastcgi_pass unix:/run/php-fpm/php-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; try_files $fastcgi_script_name =404; # Попробуйте обрабатывать ошибки 404 }
-
Проверка прав доступа:
Если Nginx не может получить доступ к файлам, несмотря на то, что они существуют, убедитесь, что у пользователя, под которым работает Nginx, есть права на чтение каталога и файлов. Выполните команду:ls -ld /srv/http/tmp/php/utclocal/
и проверьте, что права доступа достаточны.
-
Отладка и логирование:
Для получения дополнительной информации включите отладочное логирование в Nginx. Это предоставит больше данных о происходящем, когда вы запрашиваете PHP-файлы:error_log /var/log/nginx/error.log debug;
Заключение
Эти изменения должны помочь лучше настроить Nginx для работы с PHP-файлами в директориях, где включен autoindex. Если после внесения указанных выше изменений проблема не будет решена, рекомендуется также проверить конфигурацию PHP-FPM и убедиться, что она совместима с вашими настройками Nginx.
Не забывайте пересоставлять конфигурацию Nginx после изменений:
nginx -t && systemctl reload nginx
Если возникнут дополнительные вопросы или потребуется дальнейшая помощь, не стесняйтесь обращаться!