Nginx removing second slash in location block - nginx

I'm trying to set up nginx with proxy_pass when a unique URL is visited:
location ~ /proxy/(?<var>.+) {
proxy_pass $var;
}
When I visit http://example.com/proxy/http://google.com I get a 500 Internal Server Error, and the error log has the below entry:
invalid URL prefix in "http:/google.com", client: 2.33.214.165,
server: example.com, request: "GET /proxy/http://google.com HTTP/1.1",
host: "example.com"
Is there any reason why nginx doesn't include the second / in the URL?

try this: merge_slashes
though the context is server wide, so if you still need to merge slashes elsewhere you will have to improve your regexp in the location splitting the proxy target into schema and host+uri. something like this:^/proxy/(?<schema>.+)://(?<rest>) and then proxy_pass $schema://$rest may work.

Related

Nginx list contents of network share via UNC?

I've seen a couple other questions that talk about listing contents of a directory by using autoindex on. I'm trying to use this in conjunction with a network share and it is not working.
server {
listen 80;
server_name downloads.example.com;
root c:/webroot/downloads/;
location / {
index index.html;
}
location /drivers/ {
alias //10.1.0.20/drivers;
autoindex on;
}
}
I can access downloads.example.com and get the static index as expected, but when I try to access downloads.example.com/drivers/ I get a 500 Internal Server Error. My Nginx error log shows the following entry:
2019/09/20 07:57:10 [crit] 4760#2720: *4 GetFileAttributesEx()
"//10.1.0.20/drivers" failed (58: The specified server cannot perform
the requested operation), client: 10.1.0.1, server:
downloads.example.com, request: "GET /drivers/ HTTP/1.1", host:
"downloads.example.com", referrer: "http://downloads.example.com/"
I can access \\10.1.0.20\drivers from this machine via File Explorer without issues.
Why isn't this working?
I was able to get this to work by creating a symbolic link instead of using UNC directly from NGinx.
mklink -d c:\drivers \\10.1.0.21\drivers
Then use c:\drivers as the alias in the config.

nginx proxy_pass to flask works while /static fail to find jquery

I'm a noob an nginx (and apache and php ...)
I've this flask app that works fine from:
http://127.0.0.1:5000
and also externally from
http://myhost.com:5000
I would like to use that from
myhost.com/rest_1
to make room to others rest, like myhost.com/rest_2 .. 3 and so on.
The app resides in
/opt/rest_1
and uses some resources from it's /static folder like css and jquery.
I've this
/etc/nginx/sites-available/rest_1.conf
server {
listen 80;
listen [::]:80;
server_name myhost.com;
server_name_in_redirect off;
location /rest_1 {
rewrite ^/rest_1(.*) /$1 break;
proxy_pass http://127.0.0.1:5000/;
}}
and it's link to sites-enabled.
nginx restart and reload with no errors.
Other configurations are default from installation.
When i try to connect to
myhost.com/rest_1
I can see an incomplete page partially working, looking at nginx log:
/var/log/nginx/error.log:
*8 open() "/usr/share/nginx/html/static/w3.css" failed (2: No such file or directory), client: xx.xx.xx.xx, server: myhost.com, request: "GET /static/w3.css HTTP/1.1", host: "myhost.com", referrer: "http://myhost.com/rest_1"
So, it is clear to me that '/usr/share/nginx/html/' is got from elsewhere... and should also have a proper name that piece of folder (I'm a noob!!)
How to tell to the engine to redirect to the correct path on
/opt/rest_1
to get back all /static functionalities ?
OS: ubuntu server 16.04
nginx: 1.10.3
Thanks.
Cause you donĀ“t set one location resource for your static content. Your app is referencing an CSS from de root folder and not from rest_1.
Your CSS Call was http://myhost.com/STATIC, so it not match in the location that you set and try inside the default.
So you can solve it in your app or you can set it in your nginx as below:
location /static {
root /opt/rest_1;
}

Nginx. Rewrite to static file. Not trivial

actually my first question on stackoverflow, because case is not so easy.
I want nginx to rewrite all requests to static file appending requested url, and i achieved this easily with this rule
location / {
index index.html;
try_files $uri #rewriteapp;
}
location #rewriteapp {
rewrite ^(.*)$ /index.html#!$1 break;
}
BUT this is resulting in 404 and in log i see exactly how this should work, but it isn't.
2016/11/21 11:53:33 [error] 5220#6856: *1 "C:/Projects/ProCongress/web/index.html#!/index.html" is not found (3: The system cannot find the path specified), client: 127.0.0.1, server: congress, request: "GET / HTTP/1.1", host: "congress"
web/index.html#!/index.html - this part is acutally absolultley right, and should work correctly, but isn't...

Error with IP and Nginx as reverse proxy

I configured my Nginx as simple reverse proxy.
I'm just using basic setting
location / {
proxy_pass foo.dnsalias.net;
proxy_pass_header Set-Cookie;
proxy_pass_header P3P;
}
The problem is that after some time (few days) the site behind nginx become unaccessible. Indead nginx try to call a bad ip (the site behind nginx is at my home behind my box and I'm a using a dyn-dns because my ip is not fixe). This dyn-dns is always valid (I can call my site directly) but for obscure reason Nginx get stuck with that..
So as said, nginx just give me 504 Gateway Time-out after some time. It looks like the error come when my ip change at home.
Here is a sample of error log:
[error] ... upstream timed out (110: Connection timed out) while connecting to upstream, client: my.current.ip, server: myreverse.server.com, request: "GET /favicon.ico HTTP/1.1", upstream: "http://my.old
.home.ip", host: "myreverse.server.com"
So do you know why nginx is using ip instead of the DN ?
If the proxy_pass value doesn't contain variables, nginx will resolve domain names to IPs while loading the configuration and cache them until you restart/reload it. This is quite understandable from a performance point of view.
But, in case of dynamic DNS record change, this may not be desired. So two options are available depending on the license you possess or not.
Commercial version (Nginx+)
In this case, use an upstream block and specify which domain name need to be resolved periodically using a specific resolver. Records TTL can be overriden using valid=time parameter. The resolve parameter of the server directive will force the DN to be resolved periodically.
http {
resolver X.X.X.X valid=5s;
upstream dynamic {
server foo.dnsalias.net resolve;
}
server {
server_name www.example.com;
location / {
proxy_pass http://dynamic;
...
}
}
}
This feature was added in Nginx+ 1.5.12.
Community version (Nginx)
In that case, you will also need a custom resolver as in the previous solution. But to workaround the unavailable upstream solution, you need to use a variable in your proxy_pass directive. That way nginx will use the resolver too, honoring the caching time specified with the valid parameter. For instance, you can use the domain name as a variable :
http {
resolver X.X.X.X valid=5s;
server {
server_name www.example.com;
set $dn "foo.dnsalias.net";
location / {
proxy_pass http://$dn;
...
}
}
}
Then, you will likely need to add a proxy_redirect directive to handle redirects.
Maybe check this out http://forum.nginx.org/read.php?2,215830,215832#msg-215832
resolver 127.0.0.1;
set $backend "foo.example.com";
proxy_pass http://$backend;
In such setup ip address of "foo.example.com" will be looked up
dynamically and result will be cached for 5 minutes.

Nginx 502 when serving error page content?

I've been setting up Nginx as a reverse proxy for an app on the server. Part of this includes a maintenance page that has external content (like images). I was able to find a method for setting up an error page with images returning 200, but it looks like a reverse proxy will change the whole environment. Here's the original solution from nginx maintenance page with content issue
error_page 503 #maintenance;
location #maintenance {
root /path_to_static_root;
if (!-f $request_filename) {
rewrite ^(.*)$ /rest_of_path/maintenance.html break;
}
return 200;
}
The Reverse Proxy is configured as:
location / {
proxy_pass http://127.0.0.1:9007/;
proxy_redirect off;
}
The Problem is that when a file is found to exist in the "maintenance" root, something goes wrong and the server returns a 502. Anyone know what the cause could be?
Some speculation I'm wondering if server listens on port 80, it somehow passes any good file request back into the proxy. If that were true, how would that be avoided?
Edit
Here's the error in the nginx log. I am directly trying to access 50x.html. Not sure why this would occur?
2012/02/17 19:39:15 [error] 21394#0: *13 connect() failed (111: Connection refused) while connecting to upstream, client: (my ip address), server: _, request: "GET /50x.html HTTP/1.1", upstream: "http://127.0.0.1:9007/50x.html", host: "domain.com"
It looks like it is indeed trying to GET from the app and not the root. How can I bypass this?
Edit 2
I originally thought I had found an answer where a change was made for nginx v1.0.12 but it did not solve the problem. It involved a similar situation but my guess is the fix was too specific.
You shouldn't need to involve the backend (I.E., shouldn't use proxy pass) since your maintenance page should be a static html file that Nginx can serve directly.
Assuming you have a setup configured as ...
server {
listen 80;
server_name example.com;
root /path/to/webroot;
# Regular locations etc
...
}
Create a folder called "503_status" and put your maintenance page in there as "503.html".
With that in place, create a file called "maintenance.default" under the Nginx directory with the following content ...
error_page 503 /503_status/503.html;
# Candidate for redirection if not ending with one of these extensions.
if ( $request_uri !~ \.(jpg|gif|png|css|js)$ ) {
set $maint "Tr";
}
# Candidate for redirection if not a request for the maintenance page
if ( $request_uri !~ ^/maintenance/$ ) {
set $maint "${maint}ue";
}
# Redirect to a location where the status code will be issued
if ( $maint = True ) {
rewrite ^ /maintenance/ redirect;
}
# Due to Nginx quirk, issue the status code in a location context.
# Make "internal" to prevent direct browsing.
location /maintenance {
internal;
return 503;
}
# 503_status folder as "internal" so no direct browsing
location 503_status {
internal;
alias /server/path/to/503_status/folder;
}
Whenever you put to put the site into maintenance, just include the file as follows ...
server {
listen 80;
server_name example.com;
root /path/to/webroot;
include /server/path/to/maintenance.default;
# Regular locations etc
...
}
This will serve your maintenance page as well as any resources it needs (just make sure extension is in the list). The backend server does not come into play at all.

Resources