nginx rewrite all to index.php except whitelist

16,898

I would use the $uri variable and if in a location block to achieve this.

location / {
    if ( $uri !~ ^/(index\.php|css|images|core|uploads|js|robots\.txt|favicon\.ico) ) {
        rewrite ^ /server/index.php last;
    }
}

Also, as for the pathinfo security problems, (discussion) it's a good practice to add

try_files $uri =403;
fastcgi_split_path_info ^(.+.php)(.*)$;

to the location ~ \.php$ block.

Share:
16,898
xiankai
Author by

xiankai

Updated on June 06, 2022

Comments

  • xiankai
    xiankai almost 2 years

    First of all, I have tried to search for similar questions, but the solutions to those questions were specific lines of code, that I couldn't customise to fit my needs.

    I have a Codeigniter installation, and I'm trying to migrate from Apache to nginx. However, in Apache the .htaccess was pretty simple: it would take a whitelist, and rewrite everything else to index.php.

    RewriteEngine on
    RewriteCond $1 !^(index\.php|css|images|core|uploads|js|robots\.txt|favicon\.ico)
    RewriteRule ^(.*)$ /index.php/$1 [L]
    

    However in nginx, I have tried out the if and try_files directives, as well as messing around with locations, to no avail. I'm still new to how nginx reads the server config, and the tutorials online were somewhat confusing to follow through.

    Additionally, the index.php will not be in the web root, but in a subdirectory server.

    Because of this, I also need to make sure even URI requests beginning with /server do not go to the directory, but to index.php

    This is my nginx virtual host configuration so far:

    server {
        listen 80;
        server_name example.com;
    
        root /home/example/public_html;
    
        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;
    
    
        location / {
            index index.htm index.html index.php;
        }
    
        location ~ \.php$ {
            fastcgi_pass        unix:/var/run/php-fpm/example.sock;
            include             fastcgi_params;
            fastcgi_param       PATH_INFO $fastcgi_script_name;
            fastcgi_param       SCRIPT_FILENAME $document_root$fastcgi_script_name;
    
        }
    
        location ~* ^.*(/|\..*) { 
            try_files $uri $uri/ /server/index.php;
        }
    
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root /usr/share/nginx/html;
        }
    }
    

    Which helps to redirect requests to index.php, but doesn't have a whitelist. I would appreciate it if anyone could generate a working example with a brief explanation of what each part does.