Nginx block access to php files - php

I've created a simple php file to display info fetched from my MYSQL database. Right after that i use a rewrite rule in Nginx to make the link seo friendly and to mask the .php file that fetches it.
Ex: http://localhost/myfile.php?seo=how-to-install-linux
After rewrite rule the i can access it like:
http://localhost/how-to-install-linux
My rewrite rules are:
location / {
rewrite ^/([a-zA-Z0-9_$\-]+)$ /myfile.php?seo=$1 last;
rewrite ^/(.*)/$ /$1 permanent; <- just to block trailing slash
}
My problem is that i also want to block any direct access to my php file and i want only the seo friendly url to work.
location = /myfile.php {
deny all;
}
This rule blocks complete access to my php file, including through seo friendy url.
Is there a way to make it work for the seo friendly version using NGINX?
My other settings are:
location ~ \.php$ {
try_files $uri =404;
include fcgi.conf;
fastcgi_pass unix:/var/run/ajenti-v-php7.0-fcgi-drnou-php7.0-fcgi-0.sock;
}
I only use Nginx, no Apache installed.

You can use the internal directive to prevent a location from being accessed directly. See this document for details.
For example:
location = /myfile.php {
internal;
include fcgi.conf;
fastcgi_pass unix:/var/run/ajenti-v-php7.0-fcgi-drnou-php7.0-fcgi-0.sock;
}

Related

Nginx rewrite for root only when passing parameters

I want to make a Nginx rewrite rule for parameters pretending to be top-level directories. For instance, I want example.org/myval to be redirected to example.org/foo.php?param=myval, but at the top level I already have some other files (like index.php) I would like to be reachable.
My attempt is:
location = ^/(?!.*)$ {
rewrite ^/$ https://example.org/index.php break;
}
location = ^/(.*) {
rewrite /(.*) /foo.php?param=$1 last;
}
the 1st rule catching only root, the second trying to catch pretending top-levels (but failing),so all I get when accessing non-(something.php) files is a 404. Any ideas?
EDIT:
Later I have the PHP block:
location ~ ^/(index|signup|login|).php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
which I've come to know contains the try_files part (but shouldn't match anything else); I don't know where does the 404 come from.

how to make nginx redirect

I'm trying to do the following:
There is a site where you can find a user in the format http://localhost/username . I tried to make a rule that if there is no file on the server, then it will redirect to index.php?username=username. But the problem is that it redirects everything, even js and css. I want to do it like this, if the file was on the server, then it would access it, and if not, then it would make a request
index.php?username=username
There is this piece of code:
rewrite ^/(.+)$ /index.php?type=userinfo&username=$1 last;
Use try_files to determine if the file already exists, and branch to a named location containing your rewrite rule, if it does not.
For example:
location / {
try_files $uri $uri/ #rewrite;
}
location #rewrite {
rewrite ^/(.+)$ /index.php?type=userinfo&username=$1 last;
}

Return content based on REQUEST_URI by PHP

Say, My domain is 'www.miraj.com'. If users click on the link 'www.miraj.com/childhood-of-miraj' then I want to check my database if there is any post having the title 'childhood-of-miraj' it should be shown otherwise 404 page will be shown. But since there is no directory(folder) named 'childhood-of-miraj' it immediately returns 404 page. How can I do that?
This depends on the httpd you are using (Apache or Nginx).
For Apache, you should edit your .htaccess file to look like this:
RewriteEngine On # Turn on the rewriting engine
RewriteRule ^([A-Za-z-]+)/?$ FileToHandleDatabaseSearch.php?title=$1 [NC,L]
This will transform the URL on fly www.miraj.com/childhood-of-miraj to www.miraj.com/FileToHandleDatabaseSearch.php?childhood-of-miraj on the server, not in browser address bar.
FileToHandleDatabaseSearch.php
if (isset($_GET['title'])) {
//...Search DB for $title
//If title exists display page with title
//If title does not exist display 404 page not found
}
For NGINX you edit that in the conf file
www.miraj.com.conf in /etc/nginx/sites-available should look like this
server {
listen 80;
listen [::]:80;
root /path/to/project/root;
server_name www.miraj.com;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
rewrite ^([A-Za-z-]+)/?$ FileToHandleDatabaseSearch.php?title=$1 last;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
}
You would want to prefix the paths to be object-specific to avoid URL conflicts. For example if childhood-of-miraj is a movie title let the rewrite conditions be rewrite ^/movies/([A-Za-z-]+)/?$ "/path/to/project/root/FileToHandleDatabaseSearch.php?title=$1" last;
You can visit Apache Rewrite Rules for more .htaccess rules you can employ and Nginx Rewrite Rules for more Nginx rules you can employ.

How do I get NGINX to properly rewrite and execute on a custom PHP application?

We have a custom PHP application that we wrote and runs on Apache with .htaccess files to handle the url rewrites. We are trying to convert it to work under NGINX with FPM under Plesk Onyx.
The application generates links like:
https://somedomain.com/mypage (same as index/mypage)
https://somedomain.com/index/sitemap
https://somedomain.com/blog/some-article-name
These URL's map to index.php files that take the request_uri and use it to render the page responses.
The structure of the application is nested as follows:
docroot (/)
./index.php //handler for the request in /
./blog/index.php //handler for any request to /blog
Each index.php expects to receive a ?path={request_uri} so that it can map the request to the controllers and actions.
I have tried multiple ways to get NGINX to do this using tryfiles and rewrite, but no luck. Using rewrite I can get / to work, but it wont render /mypage or /index/sitemap.
If I try to hit /index/sitemap it downloads the index.php instead of executing it, and if I try the blog the same thing happens. In fact the only path that works is /, all others just download the index.php file.
Here is my configuration as it is now, where am I going wrong?
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 30d;
add_header Pragma public;
add_header Cache-Control “public”;
try_files $uri #fallback;
}
location / {
#index index.php index.html index.html;
rewrite ^/([^?]*) /index.php?path=$1 break;
rewrite ^blog/([^?]*) /blog/index.php?path=$1 break;
#try_files $uri #fallback;
}
Your configuration has multiple issues. I will ignore the first location block as it seems to have nothing to do with your question.
The first rewrite will always match, so the second rewrite will never be consulted. The second rewrite will never match anyway, as nginx URIs always begin with a /. The [^?] is meaningless, because rewrite uses a normalised URI which does not include the ? or query string. Using rewrite...break means that the rewritten URI is processed within the same location, which is an error as this location is not equipped to process PHP files. See this document for more.
A solution using try_files might look like this:
location / {
try_files $uri $uri/ /index.php?path=$uri&$args;
}
location /blog {
try_files $uri $uri/ /blog/index.php?path=$uri&$args;
}
location ~ \.php$ { ... }
See this document for more.

nginx redirect loop, remove index.php from url

I want any requests like http://example.com/whatever/index.php, to do a 301 redirect to http://example.com/whatever/.
I tried adding:
rewrite ^(.*/)index.php$ $1 permanent;
location / {
index index.php;
}
The problem here, this rewrite gets run on the root url, which causes a infinite redirect loop.
Edit:
I need a general solution
http://example.com/ should serve the file webroot/index.php
http://example.com/index.php, should 301 redirect to http://example.com/
http://example.com/a/index.php should 301 redirect to http://example.com/a/
http://example.com/a/ should serve the index.php script at webroot/a/index.php
Basically, I never want to show "index.php" in the address bar. I have old backlinks that I need to redirect to the canonical url.
Great question, with the solution similar to another one I've answered on ServerFault recently, although it's much simpler here, and you know exactly what you need.
What you want here is to only perform the redirect when the user explicitly requests /index.php, but never redirect any of the internal requests that end up being served by the actual index.php script, as defined through the index directive.
This should do just that, avoiding the loops:
server {
index index.php;
if ($request_uri ~* "^(.*/)index\.php$") {
return 301 $1;
}
location / {
# ...
}
}
Try that
location ~ /*/index.php {
rewrite ^/(.*)/(.*) http://www.votre_domaine.com/$1 permanent;
}
location /index.php {
return 301 http://www.example.com/;
}
If you already have first line mentioned below in your Nginx configuration file you don't have rewrite it again.
index index.php index.html index.htm;
rewrite ^(/.).html(?.)?$ $1$2 permanent;
rewrite ^/(.*)/$ /$1 permanent;
try_files $uri/index.html $uri.html $uri/ $uri =404;
This will remove .html from the URL and additionally will also remove "index" from home page or index page. For example -
https://www.example.com/index will be changed to https://www.example.com
Try
location = /whatever/index.php {
return 301 $scheme://www.example.com/whatever/;
}
Another benefit from doing it this way is that nginx does a return faster than a rewrite.

Categories