Nginx auth_basic and rewrite in subdirectory does not work - nginx

I'm trying to add a project to a subfolder of existing webserver with Nginx. Here's my simple config:
server {
listen 80 default_server;
server_name localhost;
root /var/www;
[...]
location = /my-project { return 301 /my-project/; }
location /my-project/ {
alias /var/www/my-project/web/;
index index.php;
location ~ /[^/]+/control(/|$) {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/htpasswd;
if (-f $request_filename) { break; }
rewrite ^(.*)$ /my-project/index.php last;
}
if (-f $request_filename) { break; }
rewrite ^ /my-project/index.php last;
location ~ ^/[^/]+/index\.php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/fcgi.sock;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
}
}
}
Because there is an rewrite directive inside /control location block, the auth_basic never gets triggered, because Nginx executes rewrites before authentication. In which way should I modify the config, that auth does work?
PS: try_files doesn't seem to work, because it serves files from root (/) webfolder!? When I replace the if and following rewrite with try_files $uri /my-project/index.php?$query_string; I get a 404, because Nginx tries to serve the file /var/wwwindex.php (have a look at missing slash and the root folder /var/www instead of alias).
EDIT 18.09.2013:
As VBart suggests I'm using now the following configuration to get authentication to work
location ~ ^/(?<dir>my-project)(?<path>/.*)$ {
root /var/www/$dir/web;
location ~ ^/[^/]+/control(/|$) {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/htpasswd;
try_files $path /$dir/index.php?$query_string;
}
try_files $path /$dir/index.php?$query_string;
location ~ ^/[^/]+/index\.php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/fcgi.sock;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
}
}

Use:
error_page 404 =200 /my-project/index.php;
instead of ugly rewrites:
if (-f $request_filename) { break; }
rewrite ^(.*)$ /my-project/index.php last;
Reference:
http://nginx.org/r/error_page
http://wiki.nginx.org/IfIsEvil
http://wiki.nginx.org/Pitfalls
P.S. try_files doesn't work with alias because of bug: http://trac.nginx.org/nginx/ticket/97, but you can replace alias with root directive: http://nginx.org/r/root

Related

ubuntu 16.04 nginx change phpmyadmin url not working

Ubuntu 16.04.5 LTS Xenial 4.18.8-x86_64-linode117
nginx version: nginx/1.10.3 (Ubuntu)
php v7.0.32-0ubuntu0.16.04.1`
/etc/nginx/sites-available/default
location /phpmyadmin {
root /usr/share/;
index index.php index.html index.htm;
location ~ ^/phpmyadmin/(.+\.php)$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
root /usr/share/;
}
}
No symlink at /var/www/html
Worx well....
But I can't seem to figure out how to change phpmyadmin url.
Tried creating a symlink whatever ->/usr/share/phpmyadmin or whatever ->/usr/share/phpmyadmin/ under /var/www/htmldoes not work,
Even if I change /etc/nginx/sites-available/default to:
location /whatever {
root /usr/share/phpmyadmin/;
Created a symlink as mentioned above, restarted both nginx & php7.0-fpm still the new URL tried to download the page...
Looked up different resources on the net but they dont help:
digitalocean's guide
devanswers guide
As well as other here on SO but couldn't find a solution.
Ideas??
UPDATE
By Richard Smith's remark
location /whatever {
alias /usr/share/phpmyadmin;
index index.php index.html index.htm;
if (!-e $request_filename) { rewrite ^ /phpmyadmin/index.php last; }
# Secure phpMyAdmin Instance
auth_basic "Admin Login";
auth_basic_user_file /etc/nginx/.your_pass_file;
client_max_body_size 68M;
location ~ ^/phpmyadmin/(.+\.php)$ {
if (!-f $request_filename) { return 404; }
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
}
location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
alias /usr/share/phpmyadmin;
}
}
Try:
location ^~ /whatever {
alias /usr/share/phpmyadmin;
index index.php index.html index.htm;
if (!-e $request_filename) { rewrite ^ /whatever/index.php last; }
# Secure phpMyAdmin Instance
auth_basic "Admin Login";
auth_basic_user_file /etc/nginx/.your_pass_file;
client_max_body_size 68M;
location ~ \.php$ {
if (!-f $request_filename) { return 404; }
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}
You need to use /whatever/index.php in the rewrite statement. The nested location blocks only need to match the end of the URI. The ^~ modifier avoids conflicts with other regular expression location blocks at the server block level. Use $request_filename in the SCRIPT_FILENAME. Your last nested location block appears to perform no function.
Avoid try_files with alias due to this issue. See this caution on the use of if.

Access index.html in folder without 301 redirect

I have some index.html files sitting in a folder to get some nice urls -
site.com/about
where index.html sits in the about folder. But I am seeing that my site.com/about is being 301 redirected to site.com/about/ I am not sure where the 301 is generated from. It is not in config.
/about/ also has a 301 result.
I guess it makes sense since I am redirecting to the index.html file but should it not be a rewrite? Is there a way to return 200 for /about instead of 301 to about/?
I am using nginx
Server Block:
server {
listen IP;
server_name site.com;
rewrite / $scheme://www.$host$request_uri permanent;
}
server {
listen IP:80;
server_name site.com *.site.com;
root /var/www/vhosts/site.com/htdocs;
charset utf-8;
rewrite_log on;
location / {
index index.html index.php;
try_files $uri $uri/ /$uri.php;
expires 30d;
}
if ($request_uri = /index.php) {
return 301 $scheme://$host;
}
if ($request_uri = /index) {
return 301 $scheme://$host;
}
location /. {
return 404;
}
location ~ .php/ {
rewrite ^(.*.php)/ $1 last;
}
include "ssl_offloading.inc";
location ~ .php$ {
# if (!-e $request_filename) { rewrite / /index.php last; }
if (!-e $request_filename) { rewrite / /404.php last; }
}
}
The index directive and the $uri/ element of the try_files directive, has the side-effect of adding a trailing / to directory names by performing an external redirect.
To avoid the external redirect and return an appropriate index file when presented with a slash-less directory name, implement the index functionality explicitly within the try_files directive:
location / {
try_files $uri $uri/index.html $uri.php;
expires 30d;
}
Notice that .php works only in the last element at this location. If you need to check for $uri/index.php (in addition to $uri.php) you can use a named location block - and move or copy your fastcgi configuration into it.
For example (based on your server block):
root /var/www/vhosts/site.com/htdocs;
error_page 404 /404.php;
location / {
try_files $uri $uri/index.html #php;
expires 30d;
}
location #php {
try_files $uri.php $uri/index.php =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
...
fastcgi_pass ...;
}
location = /index.php { return 301 $scheme://$host; }
location = /index { return 301 $scheme://$host; }
location /. { return 404; }
location ~* \.php(/|$) { rewrite ^(.*)\.php $1 last; }
include "ssl_offloading.inc";

Nginx configuration for a wordpress blog in a subfolder of magento root

I have installed a Magento extension to have a wordpress blog integrated with Magento.
Basically, the WP is in a subdirectory of the Magento root. I want to create multiple sites with subdirectories but I can't make it work due to the nginx configuration.
Wordpress is in his /wp subdirectory (http://example.com/wp/wp-admin/) and the others sites are accessible from http://example.com/wp/ca/wp-admin/ and http://example.com/wp/en/wp-admin/
Here is whats I got so far :
server
{
server_name dev.example.com;
access_log /var/log/nginx/example.access.log;-
error_log /var/log/nginx/example.error.log;
root /var/www/example;
location ^~ /wp {
index index.php index.html index.htm;
try_files $uri $uri/ /wp/index.php?q=$uri&$args;
# Multisite
if (!-e $request_filename) {
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
rewrite ^/wp(/[^/]+)?(/wp-.*) /wp$2 last;
rewrite ^/wp(/[^/]+)?(/.*\.php)$ /wp$2 last;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass 127.0.0.1:9000;
}
}
set $mage_developer true;
set $mage_code es;
set $mage_type store;
include snippets.d/magento-site;-
}
and in snippets.d/magento-site :
# Serve static pages directly,
# otherwise pass the URI to Magento's front handler
location / {
index index.php;
try_files $uri $uri/ #handler;
expires 30d;-
}
# Disable .htaccess and other hidden files
location /. {
return 404;
}
# Allow admins only to view export folder
location /var/export/ {
auth_basic "Restricted";
auth_basic_user_file htpasswd;
autoindex on;
}
# These locations would be hidden by .htaccess normally
location /app/ { deny all; }
location /includes/ { deny all; }
location /lib/ { deny all; }
location /media/downloadable/ { deny all; }
location /pkginfo/ { deny all; }
location /report/config.xml { deny all; }
location /var/ { deny all; }
# Magento uses a common front handler
location #handler {
rewrite / /index.php;
}
# Forward paths like /js/index.php/x.js to relevant handler
location ~ .php/ {
rewrite ^(.*.php)/ $1 last;
}
# Execute PHP scripts
location ~ .php$ {
# Catch 404s that try_files miss
if (!-e $request_filename) { rewrite / /index.php last; }
expires off;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_param MAGE_RUN_CODE $mage_code;
fastcgi_param MAGE_RUN_TYPE $mage_type;
fastcgi_ignore_client_abort on;
fastcgi_read_timeout 900s; # 15 minutes
}
Thanks for your help.
Wanted to pass along a full conf file for anyone who needs to configure this. Please keep in mind, many file paths are unique your your server configuration.
Please note, you'll need to adjust the following parameters based on file paths on your server:
server_name domain.com www.domain.com;
ssl_certificate /sslpath/domain.com.crt;
ssl_certificate_key /sslpath/domain.com.key;
root /webrootpath/domain.com;
rewrite ^/blogpath(.*) /blogpath/index.php?q=$1;
location ^~ /blogpath {
error_log /data/log/nginx/domain.com_error.log;
access_log /data/log/nginx/domain.com_access.log;
Here is the full nginx conf file:
server {
listen 80;
server_name domain.com www.domain.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443;
server_name domain.com www.domain.com;
ssl on;
ssl_certificate /sslpath/domain.com.crt;
ssl_certificate_key /sslpath/domain.com.key;
ssl_session_timeout 30m;
root /webrootpath/domain.com;
index index.php;
location / {
index index.html index.php;
try_files $uri $uri/ #handler;
expires 30d;
}
location #wp {
rewrite ^/blogpath(.*) /blogpath/index.php?q=$1;
}
location ^~ /blogpath {
root /webrootpath/domain.com;
index index.php index.html index.htm;
try_files $uri $uri/ #wp;
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass 127.0.0.1:9000;
}
}
location ~ ^/(app|includes|lib|media/downloadable|pkginfo|report/config.xml|var)/ { internal; }
location /var/export/ { internal; }
location /. { return 404; }
location #handler { rewrite / /index.php; }
location ~* .php/ { rewrite ^(.*.php)/ $1 last; }
location ~* .php$ {
if (!-e $request_filename) { rewrite / /index.php last; }
expires off;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param MAGE_RUN_CODE default;
fastcgi_param MAGE_RUN_TYPE store;
include fastcgi_params;
}
error_log /data/log/nginx/domain.com_error.log;
access_log /data/log/nginx/domain.com_access.log;
}
Well, in the end, it works passing all request to the blog to Apache and creating the site in the virtual hosts corresponding.
location ~ ^/blog {
proxy_pass http://apache:80;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 6000s;
}
If someone succeed to make it work with Nginx only, I'm looking forward to his answer :)
Why run Apache? Doesn't make sense to run 2 webservers.
Try adding this to your nginx conf.
location #wp {
rewrite ^/wp(.*) /wp/index.php?q=$1;
}
location ^~ /wp {
root /var/www/example;
index index.php index.html index.htm;
try_files $uri $uri/ #wp;
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass 127.0.0.1:9000;
}
}

nginx change root folder for specific url

I have a configuration file like this one below:
server {
listen 80;
server_name localhost;
#charset utf-8;
root html/laravel/public;
index index.html index.php;
#browse folders if no index file
autoindex on;
# enforce NO www
if ($host ~* ^www\.(.*))
{
set $host_without_www $1;
rewrite ^/(.*)$ $scheme://$host_without_www/$1 permanent;
}
# serve static files directly
location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ {
access_log off;
#expires max;
}
# removes trailing slashes (prevents SEO duplicate content issues)
if (!-d $request_filename)
{
rewrite ^/(.+)/$ /$1 permanent;
}
# canonicalize codeigniter url end points
# if your default controller is something other than "welcome" you should change the following
# if ($request_uri ~* ^(/lobby(/index)?|/index(.php)?)/?$)
# {
# rewrite ^(.*)$ / permanent;
# }
# removes trailing "index" from all controllers
if ($request_uri ~* index/?$)
{
rewrite ^/(.*)/index/?$ /$1 permanent;
}
# unless the request is for a valid file (image, js, css, etc.), send to bootstrap
if (!-e $request_filename)
{
rewrite ^/(.*)$ /index.php?/$1 last;
break;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /backend/ {
root /html/frontend;
}
location ~ \.php$ {
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
# catch all
# error_page 404 /index.php;
# location ~ \.php$ {
# try_files $uri =404;
# fastcgi_pass unix:/tmp/php.socket;
# fastcgi_index index.php;
# #include fastcgi_params;
# include /home/tamer/code/nginx/fastcgi_params;
# }
# access_log /home/tamer/code/laravel/storage/logs.access.log;
# error_log /home/tamer/code/laravel/storage/logs.error.log;
}
I have to change root folder to html/backend for any url with $host/backend/. All rules for load pages have to be the same, only root folder have to change.
How can I do that?
server {
location / {
root /data/www;
}
location /images/ {
root /data;
rewrite ^/images/(.+?)$ $1 break; #following is the explation
}
}
use break to continue; the root in location will take effect
use last to internal simulate request; the root in location will not take effect
use permanent to 301 redirect;
use redirect to 302 redirect;
adding 127.0.0.1 to server_name to be able to use the link you provided in the comment 127.0.0.1
server_name localhost 127.0.0.1;
also you still need to have the backend location with root inside it.
location /backend/ {
root /html/backend;
}
I'll take a wild guess here:
location /backend/ {
root /html/backend;
try_files $uri $uri/ /index.php?_url=$uri&$args;
}
This means: all requests to .../backend/* will be redirected to the location block of php followed after:
location ~ \.php${ ... }
and php will handle those requests as backend scripts
Nginx Beginner's Guide has this example:
server {
location / {
root /data/www;
}
location /images/ {
root /data;
}
}
So in theory this should work for you:
server {
listen 80;
server_name localhost;
location / {
root html/laravel/public;
}
location /backend/ {
root html/backend;
}
# common config goes here
}
If I understood the question correctly you can use alias to change just the OS search path for a specific location:
Defines a replacement for the specified location. For example, with the following configuration on request of “/i/top.gif”, the file /data/w3/images/top.gif will be sent.
location /i/ {
alias /data/w3/images/;
}
You need to define new location and use alias instead of root or else the behaviour would be funky. Also you need to define location for .php to use $request_filename.
location /backend {
alias /html/backend;
try_files $uri $uri/ /index.php$is_args$args;
location ~ \.php$ {
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}

nginx vhost not serving static files

server {
listen 80;
server_name www.site.dk;
access_log /var/www/www.site.dk/logs/access.log;
error_log /var/www/www.site.dk/logs/error.log;
root /var/www/www.site.dk/;
location / {
index index.php index.html;
if (-f $request_filename) {
break;
}
if (!-f $request_filename) {
rewrite ^/(.+)$ /index.php last;
break;
}
}
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/www.site.dk$fastcgi_script_name;
}
}
I'm trying to get nginx to serve any physical file (css, images, js) without doing anything to it put let php handle all other requests. Everything that is not a physical file should be passed to php.
But it's not working, php is being executed, but calling a .css file is also passed to php as a request.
This will do the job
server {
listen 80;
server_name www.site.dk;
access_log /var/www/www.site.dk/logs/access.log;
error_log /var/www/www.site.dk/logs/error.log;
root /var/www/www.site.dk/;
index index.php index.html;
location / {
try_files $uri $uri/ #fastcgi;
}
location ~ .+\.php$ {
location ~ \..*/.*\.php$ { return 400; }
error_page 418 = #fastcgi;
return 418;
}
location #fastcgi {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
...
}
}

Resources