I'm on a NGINX web server and I would like to remove the .php extension from url.
I currently have the following conf :
server {
server_name www.mywebsite.com mywebsite.com;
return 301 https://mywebsite.com$request_uri;
}
server {
listen 443 ssl;
server_name www.mywebsite.com;
return 301 https://mywebsite.com$request_uri;
ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
}
server {
listen 443 ssl;
root /opt/http/nginx/sites/mywebsite/www;
index index.php index.html;
server_name mywebsite.com;
location / {
#rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent;
try_files $uri $uri/ $uri.php?$args;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
}
location ~* \.(pdf)$ {
expires 30d;
}
client_max_body_size 3M;
ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
error_page 403 /index.php;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
access_log /var/log/nginx/www.mywebsite.access.log;
error_log /var/log/nginx/www.mywebsite.error.log;
}
If tried to follow some similar case instructions but nothing seems to work with my conf.
The problem is that this piece of code
location / {
try_files $uri $uri/ $uri.php?$args;
}
is working well in two cases :
The client asks for https://mywebsite.com/page.php : OK
The client asks for https://mywebsite.com/page : OK
without rewriting the url !
What I need is to tell NGINX to rewrite the url if the client tries to access a page with the file extension. For example, if I ask for login.php, nginx rewrites 'login', and so on.
It also has to keep the GET params in the url if it has.
So what is the right conf to do that, given that I keep in my code the links to the php files with extension and not the relative urls (I hope NGINX could rewrite them) ? (if I need to set the relative urls in my code I can but I don't want to break my local)
Thanks to this question and the comments, I was able to figure out a similar issue, same result with some additional constraints like not using ifs or try_files. Here's what I got at the end:
upstream php {
server unix:/var/run/php-fpm/php-fpm.sock;
}
server {
# ...
rewrite ^(/.+)\.php$ $scheme://$host$1 permanent;
location / {
rewrite ^(.*)$ /$1.php;
}
location ~ \.php$ {
include fastcgi.conf;
fastcgi_pass php;
}
Major contributors were the lack of break/last in the rewrites.
location / {
try_files $uri $uri.html $uri/ #extensionless-php;
index index.html index.htm index.php;
}
location ~ \.php$ {
try_files $uri =404;
}
location #extensionless-php {
rewrite ^(.*)$ $1.php last;
}
This will remove both html and php form url .More Detail
I tried too many options until one of them worked for me, I was able to remove the extension with this:
server {
listen 80;
server_name www.example.local;
root /var/www/vhosts/example/httpdocs;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ #ext;
}
location ~ \/\.php {
rewrite "^(.*)\/.php" $1.php last;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
}
location #ext {
rewrite "^(.*)$" $1.php;
}
}
Related
I am using the below NGINX configuration to serve a Laravel application and a WordPress blog. The blog used to be in a sub-domain (blog.example.com), but now moving to example.com/blog.
I am trying to separate both the Laravel application (/var/www/vhosts/example.com/httpdocs/laravel/public) and the WordPress (/var/www/vhosts/example.com/httpdocs/wordpress/) installations into different folders so it is easy to manage. The Laravel routes are working as expected, but the WordPress example.com/blog/wp-admin route is not working. Below is my NGINX configuration.
server {
listen 80;
server_name example.com;
rewrite ^/(.*) https://example.com/$1 permanent;
}
server {
listen 443 ssl;
server_name example.com;
charset utf-8;
ssl on;
ssl_certificate /etc/ssl/example.crt;
ssl_certificate_key /etc/ssl/example.key;
root /var/www/vhosts/example.com/httpdocs/laravel/public;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 403 /index.php;
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_read_timeout 180;
include fastcgi_params;
}
## Wordpress blog configuration
location ^~ /blog/ {
alias /var/www/vhosts/example.com/httpdocs/wordpress/;
if (!-e $request_filename) {
rewrite ^ /blog/index.php last;
}
try_files $uri $uri/ /blog/index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(/blog)(/.*)$;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_read_timeout 180;
include fastcgi_params;
}
}
location ~ /\.(?!well-known).* {
deny all;
}
}
Please could you point me, why I am unable to access wp-admin? Is there a better way to do this? Thanks
Try to do that. Sets the "root" for /blog/ and removes /blog/ from the rewrite.
And also remove the slash at the end of the root directory /xyz/wordpress;
root /var/www/vhosts/example.com/httpdocs/wordpress;
rewrite .* /index.php last;
try_files $uri $uri/ /index.php;
If you have installed a new wordpress at the new folder location then it will not cause any issue.
But if you are moving existing wordpress site to the new folder location then you may need to check your existing .htaccess file.
You may first need to modify the site url in the wordpress table to match with new location and also check the WP settings for permalink. Hope this will solve the issue.
My bad just realised that there is a WordPress plugin named wps-hide-login that prevented using the wp-admin route. Once I renamed the plugin folder, I managed to login OK. Thank you for all your inputs.
On Apache we used to have a URL like MyUrl.com/UserId and in the root index.php code executed that got the request_uri that had the UserId. In Nginx instead it looks for a folder called UserId which doesn’t exist. How can I modify the Nginx config to still use the root index.php file instead of look for a non existent folder?
Here is my current nginx config:
# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/MyUrl.com/before/*;
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name MyUrl.com;
root /home/forge/MyUrl.com;
rewrite_log on;
# FORGE SSL (DO NOT REMOVE!)
ssl_certificate /etc/nginx/ssl/MyUrl.com/766650/server.crt;
ssl_certificate_key /etc/nginx/ssl/MyUrl.com/766650/server.key;
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/dhparams.pem;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
charset utf-8;
# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/MyUrl.com/server/*;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log /var/log/nginx/MyUrl.com-access.log combined;
error_log /var/log/nginx/MyUrl.com-error.log error;
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_read_timeout 180;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
location /api/v1/ {
rewrite_log on;
index index.php;
fastcgi_index index.php;
error_page 405 =200 $uri;
if (!-e $request_filename){
rewrite /api/v1/(.*)$ /api/v1/api.php?request=$1 break;
}
}
client_max_body_size 128M;
}
# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/MyUrl.com/after/*;
Apache and Nginx use different configuration formats. You need to convert what is currently in your .htaccess file into a format that Nginx understands.
This is an example of an Apache .htaccess configuration:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
In Nginx it could look something like this:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
Take a look at these questions for more details:
Converting .htaccess to nginx (mod_rewrite)
Convert htaccess to nginx rewrite
Also this tool might help with the conversion:
https://winginx.com/en/htaccess
I have a website
https://dev.mywebsite.com/index.php?album=portraits
which displays photo-albums dynamically based on a POST value.
I want to rewrite this URL to this:
https://dev.mywebsite.com/portraits
But my Nginx rewrite rule is not working. Nothing is happening when I enter https://dev.mywebsite.com/index.php?album=portraits. And no page is found when entering https://dev.mywebsite.com/portraits.
I don't know what I am doing wrong.
This is the code I'm trying to use currently:
location / {
rewrite ^/(.*)$ /album.php?album=$1 last;
}
I've also tried this:
location = /portraits {
rewrite ^/portraits?$ /index.php?album=portraits break;
}
and this:
location = /album {
rewrite ^album/([a-z]+)/?$ album.php?album=$1 break;
}
This is the entire nginx site-config file i'm using:
server {
listen 80 default_server;
listen 443 ssl;
root /config/www;
index index.php index.htm index.html;
server_name dev.mywebsite.com;
ssl_certificate /config/keys/cert.crt;
ssl_certificate_key /config/keys/cert.key;
client_max_body_size 0;
location / {
try_files $uri $uri/ /index.html /index.php?$args =404;
}
location / {
rewrite ^/(.*)$ /album.php?album=$1 last;
}
location ~ \.php$ {
#fastcgi_split_path_info ^(.+\.php)(/.+)$;
# With php5-cgi alone:
fastcgi_pass 127.0.0.1:9000;
# With php5-fpm:
#fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include /etc/nginx/fastcgi_params;
}
}
If the file you really have is index.php, then you can rewrite (without any additional location) with:
rewrite ^/portraits$ /index.php?album=portraits last;
Keep the location ~ \.php$ { of course :)
I have the following configuration to listen on port 80, but redirect to https. Then, to route everything through the index.php file, however, when I go to a page it just downloads the index.php file or shows 403 forbidden on the homepage.
Any ideas?
server {
listen 80;
server_name www.mydomain.com mydomain.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443;
server_name www.mydomain.com;
root /var/www/mydomain/public;
ssl on;
ssl_certificate mydomain.crt;
ssl_certificate_key mydomain.key;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
ssl_prefer_server_ciphers on;
location / {
if (!-e $request_filename){
rewrite \.(jpeg|jpg|gif|png)$ /public/404.php break;
}
if (!-e $request_filename){
rewrite ^(.*)$ /index.php break;
}
}
location ~ \.php {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index /index.php;
include /etc/nginx/fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~* ^/(css|img|js|flv|swf|download)/(.+)$ {
root /var/www/mydomain/public;
}
location ~ /\.ht {
deny all;
}
}
The rewrite/break causes the rewritten URI to be processed in the same location (location /) rather than the location ~ \.php. See rewrite documentation.
The location / block looks rather strange with two identical if blocks.
You might consider splitting it into two blocks:
location / {
try_files $uri /index.php;
}
location ~ \.(jpeg|jpg|gif|png)$ {
try_files $uri /public/404.php;
}
If /public/404.php is your default handler for all 404 errors, you could use an error_page directive instead:
error_page 404 /public/404.php;
location / {
try_files $uri /index.php;
}
location ~ \.(jpeg|jpg|gif|png)$ {
try_files $uri =404;
}
See the location, try_files and error_page documentation for more.
I have a Problem with our Nginx configuration, We have Wordpress in our current root directory and i would like to setup owncloud on /owncloud by using a directory outside of our root. I have tried to setup an alias in nginx but i get an "access denied" from nginx or php i'am not sure.
My nginx config:
server {
listen 134.34.60.101:80; ## listen for ipv4; this line is default and implied
# listen [::]:80 default ipv6only=on; ## listen for ipv6
listen 134.34.60.101:443 default ssl;
server_name fachschaft.inf.uni-konstanz.de www.fachschaft.inf.uni-konstanz.de;
#root /usr/share/nginx/www;
root /srv/www/website/current;
index index.php;
# reroute to old svn for now - Sammy 2013-11-26
rewrite ^/svn/fachschaft(/.*)$ https://134.34.58.21/svn/fachschaft$1;
ssl_certificate ssl/chained-nginx.crt;
ssl_certificate_key ssl/key-no-pw.pem;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
if ($ssl_protocol = "") {
rewrite ^ https://www.fachschaft.inf.uni-konstanz.de$request_uri? redirect;
}
#Owncloudsettings:
client_max_body_size 256M; # set max upload size
fastcgi_buffers 64 4K;
rewrite ^/caldav(.*)$ /remote.php/caldav$1 redirect;
rewrite ^/carddav(.*)$ /remote.php/carddav$1 redirect;
rewrite ^/webdav(.*)$ /remote.php/webdav$1 redirect;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location /doc/ {
alias /usr/share/doc/;
autoindex on;
allow 127.0.0.1;
deny all;
}
location ~ /adminier {
# TODO find a better solution...
alias /srv/www/adminier/index.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location /owncloud {
alias /srv/www/owncloud;
try_files $uri $uri/ /index.php?$args;
# fastcgi_split_path_info ^(/owncloud/.+\.php)(/.+)$;
fastcgi_split_path_info ^/owncloud/(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
#Owncloud:
rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
rewrite ^/.well-known/carddav /remote.php/carddav/ redirect;
rewrite ^/.well-known/caldav /remote.php/caldav/ redirect;
rewrite ^(/core/doc/[^\/]+/)$ $1/index.html;
location ~ ^/owncloud/(data|config|\.ht|db_structure\.xml|README) {
deny all;
}
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
#error_page 500 502 503 504 /50x.html;
#location = /50x.html {
# root /usr/share/nginx/www;
#}
# Roots Wordpress Theme Rewrites
# See http://roots.io/roots-101/
location ~ ^/assets/(img|js|css|fonts)/(.*)$ {
try_files $uri $uri/ /content/themes/fsinf-v2/assets/$1/$2;
}
location ~ ^/plugins/(.*)$ {
try_files $uri $uri/ /content/plugins/$1;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
#fastcgi_split_path_info ^(.+\.php)(/.+)$;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
# With php5-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# With php5-fpm:
#fastcgi_pass unix:/var/run/php5-fpm.sock;
#fastcgi_index index.php;
include fastcgi_params;
#}
location ~ ^(.+?\.php)(/.*)?$ {
try_files $1 = 404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$1;
fastcgi_param PATH_INFO $2;
fastcgi_param htaccessWorking true;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
# location ~ /\.ht {
# deny all;
#}
location ~ ^/owncloud/(data|config|\.ht|db_structure\.xml|README) {
deny all;
}
}
Has anyone an idea how it will work?
1) First of all, check
fastcgi_split_path_info ^/owncloud/(.+\.php)(/.+)$;
I think You must use (.+?.php) here, ? will allow to correctly operate with *.php file as user data (I see You use it above). BTW, create info.php with
<?php
phpinfo();
?>
Upload it to You server and try download it from owncloud/remote.php/webdav/SOME_FOLDER/info.php, its must start downloading, not executing.
2) Make sure that fastcgi parameter PATH_INFO set correctly (using that info.php file), if not, try use
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
Don't ask me why it's set in such odd way, there was a bug, I don't remember where I found this solution…
3) Why You are using fastcgi_split_path_info in location /owncloud? This location is not blocking further regex matches (use location ^~ … to avoid it), so php scripts won't get there, it will be matched in location ~ ^(.+?\.php)(/.*)?$ below, which, by the way, seems doesn't have fastcgi_split_path_info.
Can't say more, sorry, I just using owncloud for my home PC
PS) I recommend You use include directive to split one huge config in multiple small configs to increase readability …