Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nginx rewrite all to index.php except whitelist

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.

like image 381
xiankai Avatar asked Jul 24 '12 02:07

xiankai


1 Answers

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.

like image 119
complex857 Avatar answered Sep 22 '22 17:09

complex857