Nginx rewrite requests to subdomain.tld/files/* to external domain - nginx

I'd like to rewrite all requests to Nginx matching http://*.examle.tld/files/* to http://$1.otherdomain.tld/files/?file=$2. I'd also like to rewrite the same request without the subdomain i.e. http://example.tld/files/* to http://otherdomain.tld/files/?file=$1
The reason for this is to use production files from local development without having to sync folders.
This is what I've got so far, however without success:
location / {
...
rewrite ^http://(\w+)\.(.*)/files/(.*) http://$1.otherdomain.tld/inc/reader.php?file=$3;
rewrite ^.*/files/(.*) http://$1.otherdomain.tld/inc/reader.php?file=$1;
...
}
Thank you for any assistance.

You cannot use the server name as part of the rewrite directive's regex. If you have a server block with a wild card server_name as described here, you can use a named capture for use later within the block.
For example:
server {
server_name ~^(?<sub>\w+\.)?example\.tld$;
location /files/ {
rewrite ^/files(.*)$ http://${sub}otherdomain.tld/files/?file=$1 permanent;
}
}
See this document for details.

Related

Correct way to remove path from location in nginx with proxy pass

I currently have the following configuration to proxy requests off a single domain to multiple backends:
server {
listen 80;
location /team/app1/location/region/ {
proxy_pass https://this.is.the.backend.app.example/path1/healthcheck;
}
location /team/app2/location/region/ {
proxy_pass https://this.is.the.backend.app.example/path2/healthcheck;
}
location /team/app3/location/region/ {
proxy_pass https://this.is.the.backend.app.example/path3/healthcheck;
}
}
The paths are pretty arbitrary, essentially I just want to be able to proxy from:
https://proxydomain.com/team/app1/location1/region
To:
https://this.is.the.backend.app.example/path3/healthcheck
So
/team/app1/location1/region
Would need to be stripped from the request and just proxy the request to the intended backend. I assume the path is being appended in someway as I just get 404s...
I can pass to a domain without trailing path like so - but when I try and proxy to a domain with trailing paths it gets complicated:
server {
listen 80;
location /one {
proxy_pass http://x.x.x.x/;
}
location /two {
proxy_pass http://x.x.x.x/;
}
}
I have tried the following configuration too - to try and rewrite the url:
rewrite ^/team/app3/location/region/(.*)$ $1 break;
Hopefully it makes sense what I am trying to achieve - any guidance would be greatly appreciated.
Thanks
You were on the right track. The rewrite will look like:
location /team/app3/location/region/ {
rewrite ^/team/app1/location/region/(.*)$ /path3/$1 break;
proxy_pass https://this.is.the.backend.app.example/;
}
You should add the new path path3 in the rewrite rule. With this NGINX will rewrite the $uri and append it to the proxy_pass. In case app3 and path3 are a fixed pattern you can tune the location block as well as the rewrite to simplify your configuration. But I would generally start with the approach mentioned above.
AND we keep in mind. Regex matching in locations will consume CPU. So sometimes it is better to have them fixed / static. Especially if you are using them in health checks and query them every 5s or so.
Thanks for that - definitely helped getting me down the correct track:
In the end the working config was:
location /team/app3/location/region {
rewrite ^/team/app3/location/region(.*) /path3/healthcheck$1 break;
proxy_pass https://this.is.the.backend.app.example;
}
Which correctly proxied through to:
https://this.is.the.backend.app.example/path3/healthcheck

Chage the part of the URL using nginx

I m using nginx webserver.
I want to change the url before it hits the server from
https://www.example.com/abc/contact-us
to
https://www.example.com/#/contact-us
Thanks in advance.
For a single URI redirection, an exact match location and return statement may be most efficient:
location = /abc/contact-us {
return 301 /#/contact-us;
}
To redirect all URIs beginning with /abc use a rewrite directive:
location ^~ /abc/ {
rewrite ^/abc(.*)$ /#$1 permanent;
}
The location block is largely redundant, but means nginx only looks at the regular expression when it needs to. See this document for more.

NGINX multiple server_name, but have robots.txt file for each server_name?

I have to create a server_name as a listener for origin pulls by my CDN.
The CDN wants to pull from origin.mydomain.com
I already have 100s of lines of code under www.mydomain.com that showcases all the rewrites, rules and such, and I need to use all this code again.
My easy solution would be to have
server_name www.mydomain.com origin.mydomain.com
To easily have NGINX listen for the requests to the "origin" subdomain.
My fear is that google discovers the subdomain and starts crawling it. I'd like to block google from the "origin" subdomain somehow. Since declaring multiple server_name, I am not sure I can just place robots.txt file somewhere, since using same root folder as live site.
Is there an easy way to do this?
All feedback appreciated.
Cheers
Ryan
Use two server blocks and use the include directive to pull in the common code. For example:
server {
server_name www.mydomain.com;
include /path/to/common/config;
location = /robots.txt {
root /path/to/friendly/dir;
}
}
server {
server_name origin.mydomain.com;
include /path/to/common/config;
location = /robots.txt {
root /path/to/unfriendly/dir;
}
}
So you have two robot.txt files in different directories - or use rewrite ... last to map the URI to different local files.

proxy_pass in nginx to publish webapp under a different directory

I have this location element:
location ~* ^/publicapp {
proxy_pass https://myserver.domain.local;
}
The server myserver.domain.local hosts a web application located under /myapp.
I want to make it publicly available via https://www.mywebsite.com/publicapp. How do I tell nginx to translate /myapp to /publicapp?
Please keep in mind that I use ~* to allow case-insensitivity. Thus, I cannot use a URI with proxy_pass.
Kind regards,
Kevin
Try this:
location ~* /publicapp/ {
rewrite ^/publicapp/(.*)$ /myapp/$1 break;
proxy_pass https://myserver.domain.local;
}
This will rewrite your path and use new one at the .local server.
It works using
rewrite ^/publicapp/(.*) /myapp/$1 break;
At least it does with my very simple application.
Now I have to figure out how to do proper link translation (sorry for using ISA Server/TMG terms, don't know if it's the same in nginx).
Thanks to pythagor :-)
edit:
Works only if I keep a trailing slash after the url in the browser (https://www.mywebsite.com/publicapp/).
another edit:
To make sure URLs end with a slash:
rewrite ^([^.]*[^/])$ $1/ permanent;
Taken from: here (first answer)

How to redirect any request to a specific page if the visitor was using a certain name?

How can I get visitors redirected to a specific html page if the name used to resolve the server address was a specific one? I tried
if ($http_host ~ /forbiddenname/)
{
rewrite ^(.*)$ /updateyourlinks.html break;
}
inside the Server section, but doesn't work...
After some research I found that I should use instead of an if a virtual host... what I've added to nginx configuration is another server
server {
listen 80;
server_name *.badname.com;
rewrite ^ http://goodname.com/updateyourlinks.html;
}
and this apparently works

Resources