Nginx proxy-pass to other domain extracting domain part from URI - nginx

I'm trying to use Nginx as a proxy server which should redirect all requests to different domains based on the URI parameters.
Say we have two servers org1-domain.com and org2-domain.com. The incoming request is mynginxproxy.com/api/org2/users. In this case, Nginx should proxy the request to the org2-domain.com.
Here's my Nginx config file:
user nginx;
worker_processes 1;
events {
worker_connections 10240;
}
http {
server {
listen 8080 ssl;
server_name nginx-proxy;
location ^/\w*/(.*)/.*$ {
proxy_pass https://$1-domain.com:8080;
}
}
}
So I'm using a regex in the location directive in order to get org parameter from the URI and use it in the proxy_pass directive. But I'm always getting this error:
host not found in upstream "-domain.com" in /etc/nginx/nginx.conf:15
I also tried other options for regex in the location directive:
location ~ ^/\w*/\w*/(.*)/(.*)$ {
location ~* /(.*)$ {
location ~* /(.*)$ {
But in all those cases I'm always getting the same host not found error.
I also tried to use rewrite rules instead of proxy_pass but in this case, Nginx just returns me a 302 redirect response which is not suitable for my case.
BTW proxy_pass without regex works fine if I'm redirecting directly to the org2-domain.com:
location / {
proxy_pass https://org2-domain.com:8080;
}
But I need somehow to extract org from the URI and construct the DNS name for proxy_pass directive.

Related

NGINX location with and without extension to proxy_pass

I'm learning nginx rules.
I have been reading about the location module: http://nginx.org/en/docs/http/ngx_http_core_module.html#location
I would like to catch and proxy_pass either if the user types the path with or without extension.
/user and /user.php both should proxy to mytestingsite.co/user.php
I tried this but it just work for /user.php
location ~ /user {
proxy_ssl_server_name on;
proxy_pass "mytestingsite.co/user.php";
}
Location you've shown in your question won't work at all. Besides you do not specify the access scheme (http or https), you can't specify an URI after the upstream name inside the regex location, this configuration will give you the following error:
nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in ...
Regex you are using will match anything with the /user substring, e.g. /api/user/ or /username.
If you want to match /user and /user.php URIs only, and pass the /user.php URI to the upstream server, you can use the following location:
location ~ ^/user(\.php)?$ {
rewrite ^ /user.php break;
proxy_ssl_server_name on;
proxy_pass https://mytestingsite.co;
}

Nginx - how to proxy_pass particular url to a different host while keeping context?

I have a fairly simple nginx conf for a front-end and backend application:
server {
listen 8080;
server_name nginx_server;
port_in_redirect off;
location / {
root /dir/html;
index index.html index.htm;
}
location /api/ {
proxy_pass http://my-api:8080/;
}
}
My main host is https and this works fine. When I hit https://myapp.com/api/a/b/c, my backend receives /a/b/c, which is what I want.
Now, I want to send the requests to a particular /api context to a different server:
location /api/a/b {
rewrite /api/(.*) /$1 break;
proxy_pass http://another-api:8080;
}
So now, if I hit https://myapp.com/api/a/b?param=1 I want to hit http://another-api:8080/a/b?param=1 and also https://myapp.com/api/a/b/c/d should hit http://another-api:8080/a/b/c/d
This is working when I test using Postman, but for some reason, in Chrome, when my frontend app tries to hit https://myapp.com/api/a/b/c/d I get a console error: (blocked:mixed-content)
How can I fix this?

Nginx - Reverse proxy everything after location specification

I'm trying to use nginx to reverse proxy a specific location specification, as below:
server {
listen 80;
server_name example.com;
location /example {
proxy_pass http://localhost:8080/test;
}
}
Now, when I try and access a resource at http://example.com/example/css/styles.css I expect it to try and access http://localhost:8080/test/css/styles.css. But alas - I get a 404 from nginx.
When I try and access http://example.com/example it shows me what's on http://localhost:8080/test (so I know the base url segment is working) minus anything being imported into that page from a relative url (e.g. styles and JS files)
How do I get the reverse proxy to work with child url segments?
Per Ivan's comment on the original question, here is a working configuration with trailing slashes added:
server {
listen 80;
server_name example.com;
location /example/ {
proxy_pass http://localhost:8080/test/;
}
}

NGINX proxy_pass rewrite asset uri

I'm trying to do a basic NGINX reverse proxy by subdomian, to localhost/folder and am stumped getting it to rewrite my assets+links.
My http://localhost:8080/myapp/ works like a charm, but via NGINX+subdomain it fails on the subfolder assets.
I believe I'm stumped on the 'rewrite' clause for NGINX.
How can I rewrite the HTML going to the client browser to drop the /myapp/ context?
server {
listen 443 ssl;
server_name app1.domain.com;
location / {
rewrite ^/myapp/(.*) /$1 break; # this line seems to do nothing
proxy_pass http://localhost:8080/myapp/;
}
}
I'm expecting my resultant HTML (via https://app1.domain.com) to be rewritten without the subfolder /myapp/, so when assets are requested they can be found instead of a 404 against https://app1.domain.com/myapp/assets/. It should just be https://app1.domain.com/assets/ (which if I manually go there they work)
--thanks.
Feeding from Ivan's response and finalizing my solution as:
server {
listen 443 ssl;
server_name app1.domain.com;
location / {
sub_filter '/myapp/' '/'; # rewrites HTML strings to remove context
sub_filter_once off; # ensures it loops through the whole HTML (required)
proxy_pass http://localhost:8080/myapp/;
}
}
As nginx proxy_pass documentation states:
In some cases, the part of a request URI to be replaced cannot be determined:
...
When the URI is changed inside a proxied location using the rewrite directive, and this same configuration will be used to process a request (break):
location /name/ {
rewrite /name/([^/]+) /users?name=$1 break;
proxy_pass http://127.0.0.1;
}
In this case, the URI specified in the directive is ignored and the full changed request URI is passed to the server.
So with this configuration block after you rewrite /myapp/assets/some_asset URI to /assets/some_asset and use a break flag, nginx ignores /myapp/ suffix on a proxy_pass directive and passes /assets/some_asset request to your backend. However strange it is, what you need is to use this rewrite rule instead:
rewrite ^(/myapp/.*)$ $1 break;
Another (may be even better) solution is to use two location blocks:
location / {
proxy_pass http://localhost:8080/myapp/;
}
location /myapp/ {
proxy_pass http://localhost:8080;
}

Nginx: how to add /something to a uri and still keep it working

I have a nginx instance running. My config is something like the following.
server {
listen 80;
listen 443;
location / {
...
proxy_pass http://127.0.0.1:8080;
...
proxy_redirect http://127.0.0.1:8080 example.com;
}
}
I have some software running in 8080 and I want that the user enters example.com/somepath and be able to be redirected to the root 127.0.0.1:8080 through my domain. The software should receive all urls without /somepath but the browser should still show /somepath in the name.
I am quite new so sorry for the basic question I could not find any relevant info on how to do this exactly: I tried rewrite rules and setting location /mysoftware { tests with no luck.
The client browser uses /somepath/... to access /...in the application. This means that nginx must rewrite the URI before passing it upstream.
The proxy_pass directive has a basic rewrite capability. See this document for details. For example:
location /somepath/ {
proxy_pass http://127.0.0.1:8080/;
...
}
Alternatively, you might use a rewrite ... break statement. See this document for details. For example:
location /somepath {
rewrite ^/somepath/?(.*)$ /$1 break;
proxy_pass http://127.0.0.1:8080;
...
}
The difficult part is preventing your application from breaking out of /somepath. The proxy_redirect directive can handle the 3xx responses from your application. But the location of resource files (.css and .js) and the target for hyperlinks, can cause problems for applications that are not aware that they need to stay inside a subdirectory.

Resources