Nginx location / overrides all other locations - nginx

I'm trying to write a simple nginx config. What I need is:
if file exists in root serve this file
If url is /default/url then show /some/path2/index.html
Otherwise redirect to /default/url
my config is as follows
server {
listen 127.0.0.1:80;
server_name my.domain.com;
root /some/path/html;
location / {
return 302 /default/url;
}
location = /default/url {
rewrite ^/(.*)$/some/path2/index.html;
}
location /default/e_schema {
proxy_pass http://other.host.com;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
It redirects to /default/url instantly regardless of url.
I was trying to put the location / block on the bottom and on the top. I've tried to use location ~ /.* to lower priority but nothing helps. If I remove location / at all everything is fine my requirements 2 and 3 is ok.
According to this answer https://serverfault.com/questions/656628/nginx-catch-all-other-locations-than-given/656634 it should work.

You have put an "=" in the location block
location = /default/url {
Could you try removing this? I believe it may be setting the url

The problem was here
location = /default/url {
rewrite ^/(.*)$/some/path2/index.html;
}
this makes internal redirect to /some/path2/index.html which is within / path so it triggers the location / block which redirects to /default/url and so on.
My solution was to make empty block to exclude the path from location /
location /some/path2/index.html {}

Related

NGINX: Convert URI path to query string

My goal is to convert all non / requests of my Nginx server to /?data={uri-path}.
I was trying with the following configuration:
server {
server_name example.com;
listen 80;
location = / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
alias /home/....;
expires $expires;
}
location / {
return 301 http://example.com/?data=$request_uri;
}
}
The problem is I end with an URI like this: http://example.com/?data=?data=?data=?data=?data=?data=
and the browser complains about lots of redirections.
Based on documentation, location = should have the priority but seems I'm doing something wrong.
And feedback is appreciated.
It depends on what location = / does.
If it points to a directory and that directory contains an index.html file, Nginx will internally rewrite the URI, then search for a location to process that revised request.
This will result in a redirection loop.
You could break the loop by adding another location block to handle the final URI, for example:
location = /index.html { root ...; }
If the location = / block is intended to proxy the request, then you are missing a proxy_pass statement.

nginx proxy_pass to all pages

So I am using nginx to reverse proxy to another server. This wasn't serving static files, until I linked them in the location. The location block is super long, but looks similar to the code below. I'm sure that I'm doing this the wrong way, but it works, it's just tedious to write all the paths. I'm wondering if there's a better way.
location / {
proxy_pass www.example.com;
}
location /sytlesheet.css {
proxy_pass www.example.com/stylesheet.css;
}
location /page1 {
proxy_pass www.example.com/page1;
}
#this goes on and on
Is there a way to get everything past the '/' for example 'page1', and pass that to the proxy without manually typing it?
I'm hoping there's something a way to use a variable or something to link all the pages and resources with a single location block:
location / {
proxy_pass www.example.com;
}
location /$variable {
proxy_pass www.example.com/$variable;
}
Thanks!
You should use following code
location / {
# First attempt to serve request as file, then
# as directory, then fall back to proxy
try_files $uri $uri/ #proxy;
}
location #proxy {
proxy_pass www.example.com;
}
Check this out.
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://www.example.com;
}

The meaning of '=' sign in nginx.conf

Let's assume I run a service using nginx on www.example.com. I have the whole traffic on port:80. httpsis required. I decided to remove the service which was on example.com/ and move the user directly to example.com/dir/.
The most popular solution on StackOverflow is to add
location = / {
return 301 /dir/;
}
Unfortunately it does forward to http://www.example.com/dir/ instead of https://www.example.com/dir/. I have also tried:
location = / {
return 301 https://$http_host/dir/;
}
and
location = / {
return 301 https://$host/dir/;
}
but they both fail.
On the other hand, I can find:
location / {
...
}
in this file.
Here I have two questions:
What is the difference between location = / {} and location / {}?
Is there any configuration trick for my problem?
Also, using the “=” modifier it is possible to define an exact match of URI and location. If an exact match is found, the search terminates. For example, if a “/” request happens frequently, defining “location = /” will speed up the processing of these requests, as search terminates right after the first comparison. Such a location cannot obviously contain nested locations.
You can find more information on the location blocks here: Docs
EDIT: as mentioned below in the comments to use HTTPS you must use the ssl parameter for example a server block might be:
server {
listen 443 ssl;
ssl_certificate /path/to/fullchain.crt;
ssl_certificate_key /path/to/key.pem
location / {
proxy_pass http://xxx.xxx.xxx.xxx:80;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

Nginx redirect with rewrite

Assuming I want to redirect URIs like
http://server1:8081/test/admin/option?options
http://server1:8081/test/admin/option/suboption?options
http://server1:8081/test/admin/option/suboption/subsuboption?options
to
http://server2:8080/tomcat/admin/option?options
http://server2:8080/tomcat/admin/option/suboption?options
http://server2:8080/tomcat/admin/option/suboption/subsuboption?options
what nginx rules I have to use? I've tried the following but it doesn't work
location =/test/admin {
proxy_pass http://server2:8080/tomcat/admin;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Try something along these lines ..
location /test/admin {
rewrite ^/test/admin(.*)$ /tomcat/admin$1;
}
location /tomcat/admin {
internal;
proxy_pass http://server2:8080;
[…]
}
That is, rewrite the requests to "tomcat/admin" which you can optionally make open to internal requests only.
In that location block, you can then proxy passthe request.

Nginx resolves the wrong route

I have an nginx-based configuration, where the root of the domain should lead to a static page (a splash page) and anything else should be proxied to an internally accessible machine. The configuration looks roughly as follows:
server {
listen 80;
location = / {
root /var/www;
}
location ~ / {
location /robots.txt {
root /var/www;
}
proxy_pass http://127.0.0.1:9091;
proxy_set_header Host $host;
}
}
The problem is that if the second block of code exists, the first one stops being taken into consideration. In other words, nginx starts looking for an index.html file on the 9091 instance, which does not exist. If the proxy_pass block is commented, then the first part goes into effect.
As far as the documentation is concerned, this should not be the case. If the root of my domain is called, Nginx should stop searching after the first block, since it is explicit. Yet, this is not the case.
What should be done here? I do not want to merge the splash page code, with the rest.
Your config looks very weird, but there is no indication that it shouldn't work as you seem to intend.
Perhaps you could try something like this? Else, please provide your full configuration (perhaps your cut-down example is missing something important that we should know about).
server {
listen 80;
root /var/www;
location = / {
}
location = /index.html {
}
location = /robots.txt {
}
location / {
proxy_pass http://127.0.0.1:9091;
proxy_set_header Host $host;
}
}
Try this:
Replace splash.html to your splash page filename.
# Set root directory for requests
root /var/www;
# Rewrite / to /splash.html
rewrite ^/$ /splash.html break;
location = /splash.html { }
location = /robots.txt { }
location ~* / {
proxy_pass http://127.0.0.1:9091;
proxy_set_header Host $host;
}
I guess you have index directive somewhere and this is how index is works.
It should be noted that using an index file causes an internal redirect, and the request can be processed in a different location.
Your first location matches, but then index module cause internal redirect to /index.html and request ends up in second location block.
I would write something like this:
server {
listen 80;
root /var/www;
location = /index.html {
}
location = /robots.txt {
}
location / {
proxy_pass http://127.0.0.1:9091;
proxy_set_header Host $host;
}
}

Resources