wag0325
By:
wag0325

Nginx fails to redirect '/' to '/index.php'

May 27, 2017 745 views
Nginx WordPress

Nginx fails to call index.php file at '/' endpoint. In /etc/nginx/sites-available/default, I have added location / section to rewrite to '/index.php' (see below). However, when I enter my-site.com to the url bar, I get 403 Forbidden error ([error] 18041#18041: *2 directory index of "/var/www/html/" is forbidden).

When I enter my-site.com/index.php, it works correctly. Also, I'm able to see a page other than 403 Forbidden if I add an 'index.html' fie to my document directory, /var/www/html. Even with fastcgi_index index.php; and removed 'index.html', I don't see the index.php file in '/' endpoint.

/etc/nginx/sites-available/default

server {
    listen 80;
    listen [::]:80;
    server_name my-site.com www.my-site.com;
    return 301 https://$server_name$request_url;
}

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

    include snippets/ssl-my-site.com.conf;
    include snippets/ssl-params.conf;

    root /var/www/html;

    index index.php index.html index.htm index.nginx-debian.html;

    server_name my-site.com www.my-site.com;

    location ~ [^/].php(/|$) {
        fastcgi_split_path_info ^(.+?.php)(/.*)$;

        if (!-f /var/www/html$fastcgi_script_name) {
            return 404;
        }

        include fastcgi_params;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
        fastcgi_pass unix:var/run/php/php7.0-fpm.sock;
        #fastcgi_pass  127.0.0.1:9000;
        fastcgi_read_timeout 300;
    }

    location ~ /.ht {
        deny all;
    }

    location ~ /.well-known {
        allow all;
    }

   location /phpmyadmin {
                index index.php;
    }

    # Rewrite rules for WordPress Multi-site.
    if (!-e $request_filename) {
            rewrite /wp-admin$ $scheme://$host$uri/ permanent;
            rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last;
            rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ $1 last;
    }
}
1 comment
  • UPDATED /etc/nginx/sites-available/default

    server {
        listen 80;
        listen [::]:80;
        server_name pinkbulletin.com www.pinkbulletin.com;
        return 301 https://$server_name$request_url;
    }
    
    server {
        listen 443 ssl http2;
            listen [::]:443 ssl http2;
    
            include snippets/ssl-pinkbulletin.com.conf;
            include snippets/ssl-params.conf;
    
            root /var/www/html;
    
            index index.php index.html index.htm index.nginx-debian.html;
    
            server_name pinkbulletin.com;
    
        location / {
                    # try_files $uri $uri/ =404;
                    #try_files $uri $uri/ /index.php?q=$uri&$args;
            try_files $uri $uri/ /index.php?q=$uri&$args;
            #index  index.html index.htm index.php;
            #try_files $uri $uri/ /index.php?$args;
        }
    
            location ~ [^/].php(/|$) {
                    fastcgi_split_path_info ^(.+?.php)(/.*)$;
            if (!-f /var/www/html$fastcgi_script_name) {
                return 404;
            }
    
            include fastcgi_params;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
            #fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
            fastcgi_pass  127.0.0.1:9000;
            fastcgi_read_timeout 300;
        }
    
        location ~ /.ht {
            deny all;
        }
    
        location ~ /.well-known {
            allow all;
        }
    
        location /phpmyadmin {
            index index.php;
        }
    
        # Rewrite rules for WordPress Multi-site.
        if (!-e $request_filename) {
                rewrite /wp-admin$ $scheme://$host$uri/ permanent;
                rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last;
                rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ $1 last;
        }
    }
    
    # redirect www to non-www
    server {
        listen 443; 
        listen [::]:443;
        server_name www.pinkbulletin.com;
    
        return 301 https://pinkbulletin.com$request_uri;
    }
    
    
3 Answers

@wag0325

Generally, for /, you'd have a location block like this:

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

...which is missing in the configuration that you've posted. That's a standard / location block for just about any CMS or blog using PHP.

I'd recommend adding that block to your configuration, and then restarting NGINX.

  • I've grabbed the latest copy of /etc/nginx/sites-available/default and added to the comment. I'm still seeing having issues after restarting Nginx and php-7.

@wag0325

I've setup quite a few WordPress and WordPress MS instances on NGINX and I've never ran in to an instance where q=$uri&$args was needed instead of just ?$args.

So instead of:

try_files $uri $uri/ /index.php?q=$uri&$args;

I would recommend using:

try_files $uri $uri/ /index.php?$args;

...

That being said, I would recommend creating a backup of default, and starting clean. Once you've got a backup of default, run the following command.

This will wipe this file clean, so make sure you have a backup.

truncate -s 0 /etc/nginx/sites-available/default

Once that's done, open it back up:

nano /etc/nginx/sites-available/default

and paste in:

server {
    listen 80;
    listen [::]:80;
    server_name pinkbulletin.com www.pinkbulletin.com;

    return 301 https://$server_name$request_url;
}

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

    include snippets/ssl-pinkbulletin.com.conf;
    include snippets/ssl-params.conf;

    root /var/www/html;

    index index.php index.html;

    server_name pinkbulletin.com www.pinkbulletin.com;

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

    location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;

        fastcgi_pass  127.0.0.1:9000;
        fastcgi_index index.php;

        include fastcgi_params;
    }

    location ~ /.ht {
        deny all;
    }

    location ~ /.well-known {
        allow all;
    }

    location /phpmyadmin {
        index index.php;
    }

    if (!-e $request_filename) {
        rewrite /wp-admin$ $scheme://$host$uri/ permanent;
        rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last;
        rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ $1 last;
    }
}

Now, make a backup of /etc/nginx/fastcgi_params, and then run:

truncate -s 0 /etc/nginx/fastcgi_params

Now open it up:

nano /etc/nginx/fastcgi_params

and paste in:

fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 512k;
fastcgi_buffers 512 16k;
fastcgi_busy_buffers_size 1m;
fastcgi_temp_file_write_size 4m;
fastcgi_max_temp_file_size 4m;
fastcgi_intercept_errors off;

fastcgi_param SCRIPT_FILENAME   $request_filename;
fastcgi_param PATH_INFO         $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED   $document_root$fastcgi_path_info;
fastcgi_param QUERY_STRING      $query_string;
fastcgi_param REQUEST_METHOD    $request_method;
fastcgi_param CONTENT_TYPE      $content_type;
fastcgi_param CONTENT_LENGTH    $content_length;
fastcgi_param SCRIPT_NAME       $fastcgi_script_name;
fastcgi_param REQUEST_URI       $request_uri;
fastcgi_param DOCUMENT_URI      $document_uri;
fastcgi_param DOCUMENT_ROOT     $document_root;
fastcgi_param SERVER_PROTOCOL   $server_protocol;
fastcgi_param REQUEST_SCHEME    $scheme;
fastcgi_param HTTPS             $https if_not_empty;
fastcgi_param HTTP_PROXY        "";
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE   nginx/$nginx_version;
fastcgi_param REMOTE_ADDR       $remote_addr;
fastcgi_param REMOTE_PORT       $remote_port;
fastcgi_param SERVER_ADDR       $server_addr;
fastcgi_param SERVER_PORT       $server_port;
fastcgi_param SERVER_NAME       $server_name;
fastcgi_param REDIRECT_STATUS   200;

Save the file, exit and then restart NGINX.

Once you've got those changes applied, let's see what happens then. If any errors pop up, check the logs again by running:

tail -20 /var/log/nginx/error.log

and paste that to a code block and we'll continue to troubleshoot :-).

  • @jtittle

    Thank you so much for the detailed steps and codes. After following your guideline and updating return 301 https://$servername$requesturl; to return 301 https://$servername$requesturi;, I'm now seeing a 502 Bad Gateway error. It seems like it's has to do with fastcgi_pass 127.0.0.1:9000;. However, as I've reviewed other tutorials, they also suggest using 127.0.0.1:9000 over unix:/var/run/php/php7.0-fpm.sock.

    *error.log *

    2017/05/28 01:45:46 [error] 20024#20024: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 98.7.110.100, server: pinkbulletin.com, request: "GET / HTTP/2.0", upstream: "fastcgi://127.0.0.1:9000", host: "pinkbulletin.com"

    • @wag0325

      You'll need to change the listen directive in your PHP-FPM pool file. If you've not created your own, the default will be in:

      /etc/php/7.0/fpm/pool.d
      

      Once you're inside that directory, you'll see a file called www.conf, open that up:

      nano /etc/php/7.0/fpm/pool.d/www.conf
      

      Now you'll want to find:

      listen =
      

      By default, you'll probably see a socket defined, just remove that and make it so that the above directive looks like this:

      listen = 127.0.0.1:9000
      

      Once that change is made, save the file and restart PHP-FPM:

      service php7.0-fpm restart
      
      • @jtittle

        After the updating the www.conf file, now it's outputting "Access to the script '/var/www/html' has been denied" error. I have tried uncommenting the security.limit_extensions in www.conf file as listed under this answer.

        error.log

        2017/05/28 03:09:18 [error] 20507#20507: *2 FastCGI sent in stderr: "Access to the script '/var/www/html' has been denied (see security.limit_extensions)" while reading response header from upstream, client: 211.0.145.107, server: pinkbulletin.com, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "pinkbulletin.com"
        

        /etc/php/7.0/fpm/pool.d/www.conf

        user = www-data
        group = www-data
        listen = 127.0.0.1:9000
        security.limit_extensions = .php .php3 .php4 .php5 .php7
        

        /var/www/html

        root@ubuntu-512mb-nyc3-01:/var/www# ls -la
        total 12
        drwxr-xr-x  3 root     root     4096 May 27 15:04 .
        drwxr-xr-x 14 root     root     4096 Mar 13 03:26 ..
        drwxr-xr-x  5 www-data www-data 4096 May 27 21:35 html
        
        • @wag0325

          Has anything else been modified in your configuration, such as php.ini, or any other files (other than those we modified from my previous reply)?

          Also, for the purpose of testing, comment out security.limit_extensions, so that it looks like:

          ; security.limit_extensions = .php .php3 .php4 .php5 .php7
          

          Then restart PHP-FPM.

          Also, make sure all files and directories inside of ./html are also owned by the same user and group.

          chown -R www-data:www-data /var/www/html
          

          ...

          To test everything, I just setup a Droplet with NGINX, MariaDB, and PHP-FPM. The only difference between my configuration and yours is that I'm not using SSL and am just listening on port 80.

          Everything is working as expected, so what I'm trying to do is see what all you've changes other than the server block and the few values in the default config file for the default pool.

Have another answer? Share your knowledge.