Score:0

nginx 404 .php extension with fpm

eg flag

When I visit a non-existent url with .php extension I get a ngnix 404 error page, however url without .php extension it works as expected using the try_files. Where the 404 is handled via php application.

It has happened since I added this code as suggested

fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
    return 404;
}

Reason for adding this was to fix error in logs: FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream This error was happening when I visited non-existent.php file. I read lots of posts about the problem being to do with 'SCRIPT_FILENAME' being missing but this wasn't the case for me.

example.conf

server {
  listen 443 ssl;
  listen [::]:443 ssl;

  server_name example.com;

  root /var/www/example/public/public;

  access_log  /var/log/nginx/example.access.log main_ext;
  error_log  /var/log/nginx/example.error.log warn;

  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

  include /etc/nginx/include.d/ssl.conf;

  # Laravel
  rewrite ^/index.php/(.*) /$1 permanent;
    
  location = / {
    try_files /page-cache/pc__index__pc.html /index.php?$query_string;
  }

  location / {
    try_files $uri $uri/ /page-cache/$uri.html /index.php?$query_string;
  }

  location ~ [^/]\.php(/|$) {
    include /etc/nginx/include.d/php.conf;
    fastcgi_pass unix:/var/run/php/php8.0-fpm-example.sock;
  }
}

php.conf

# Check file exists
try_files $uri =404;

# https://www.nginx.com/nginx-wiki/build/dirhtml/start/topics/examples/phpfcgi/
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
    return 404;
}

fastcgi_index index.php;

# Mitigate https://httpoxy.org/ vulnerabilities
fastcgi_param HTTP_PROXY "";

fastcgi_intercept_errors off;

# include the fastcgi_param setting
include fastcgi_params;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Example URL: https://example.com/foo - Works fine shows pretty 404 inside php app. https://example.com/foo.php - Shows default ngnix 404.

vautee avatar
kr flag
Could you add these URL examples that work / won't work to your question?
eg flag
Sure I have added these.
Score:1
gr flag

If you want those URIs to be processed as any other non-existent URIs, change try_files $uri =404; to the try_files $uri /index.php?$query_string; in your php.conf file.


If your PHP app really makes use of PATH_INFO FastCGI variable (which I doubt about), you should use

fastcgi_split_path_info ^(.+\.php)(/.+)$;

try_files $fastcgi_script_name /index.php?$query_string;

set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;

(see this nginx trac ticket).

eg flag
I needed to remove the if statement to return 404 but not actually needed anymore. But that makes sense now cheers.
Ivan Shatsky avatar
gr flag
I was going to mention that `if { ... }` is not needed anymore while writing the answer but forget about it. Anyway you figured it out yourself :)
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.