nginx autoindex передает php-файлы php-fpm, но php-fpm не может их найти.

Вопрос или проблема

Работаю с 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.

Анализ вашей конфигурации

Ваш текущий конфигурационный файл имеет несколько значительных элементов, которые могут вызывать проблемы:

  1. Обработка 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;
    }
  2. Используемые переменные:
    Вы используете переменную $request_filename, которая может не совпадать с тем, что ожидает PHP-FPM.

Возможные решения

Чтобы устранить проблему, попробуйте следующие шаги:

  1. Используйте корректную передачу SCRIPT_FILENAME:
    Измените строку в блоке Nginx для передачи SCRIPT_FILENAME. Попробуйте следующее:

    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  2. Правильный root в директории /tmp/:
    Убедитесь, что вы правильно указали путь для root. Если вы используете root /srv/http;, это приводит к тому, что Nginx будет ожидать, что документы располагаются в /srv/http/tmp/. Однако, на самом деле они в /srv/http/tmp/, и это может вызвать путаницу. Попробуйте следующий вариант:

    root /srv/http/tmp;
  3. Согласование 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
    }
  4. Проверка прав доступа:
    Если Nginx не может получить доступ к файлам, несмотря на то, что они существуют, убедитесь, что у пользователя, под которым работает Nginx, есть права на чтение каталога и файлов. Выполните команду:

    ls -ld /srv/http/tmp/php/utclocal/ 

    и проверьте, что права доступа достаточны.

  5. Отладка и логирование:
    Для получения дополнительной информации включите отладочное логирование в Nginx. Это предоставит больше данных о происходящем, когда вы запрашиваете PHP-файлы:

    error_log /var/log/nginx/error.log debug;

Заключение

Эти изменения должны помочь лучше настроить Nginx для работы с PHP-файлами в директориях, где включен autoindex. Если после внесения указанных выше изменений проблема не будет решена, рекомендуется также проверить конфигурацию PHP-FPM и убедиться, что она совместима с вашими настройками Nginx.

Не забывайте пересоставлять конфигурацию Nginx после изменений:

nginx -t && systemctl reload nginx

Если возникнут дополнительные вопросы или потребуется дальнейшая помощь, не стесняйтесь обращаться!

Оцените материал
Добавить комментарий

Капча загружается...