Nginx domain resolving issue - nginx

I had a proxy server which redirects communications to some api on customer side via https. When I use configuration with set upstream variable (proxy_pass $upstream_endpoint$request_uri;), the DNS resolving for this domain (dynamic changing IP adress) is working well but I get response 403 unauthorized.
When I use configuration without upstream (proxy_pass https://api-test.example.com/api/), point directly to customer domain it works well, I am getting response 200 but DNS resolver is not working anymore..
Nginx config:
location /api-test.example.com/api/ {
resolver 10.100.10.1 valid=5s;
set $upstream_endpoint https://api-test.example.com;
proxy_pass $upstream_endpoint$request_uri;
#proxy_pass https://api-test.example.com/api/;
proxy_ssl_name api-test.example.com;
proxy_ssl_server_name on;
proxy_set_header Host api-test.example.com;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

By adding a URI to the proxy_pass statement, the requested URI is rewritten before passing it upstream. See this docuement for details.
So the URI /api-test.example.com/api/foo is rewritten to /api/foo.
You can achieve the same behaviour with a rewrite...break statement. See this document for details.
location /api-test.example.com/api/ {
rewrite ^/api-test.example.com(.*)$ $1 break;
set $upstream_endpoint https://api-test.example.com;
proxy_pass $upstream_endpoint;
...
}

Related

Nginx redirect subfolder to another port showing original port

How to enable Nginx redirect subfoler to another port using original port? e.g.,
Service1: http://127.0.0.1:5000
Service2: http://127.0.0.1:8080
Exposed IP port via Nginx is 127.0.0.1:6060
The goal is when accessing http://127.0.0.1:6060/sub, it will access http://127.0.0.1:8080, but the URL user see is still http://127.0.0.1:6060/sub.
I tried two configurations, but they didn't work.
server {
listen 6060;
server_name 127.0.0.1;
location /sub/ {
# method 1: use proxy pass, browser says "static resources not found"
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host:6060;
proxy_pass http://127.0.0.1:8080;
# method 2: use rewrite, the URL will be http://127.0.0.1:8080
rewrite ^/pct/(.*)$ http://127.0.0.1:8080 redirect;
}
location / {
proxy_pass http://127.0.0.1:5000;
}
Thanks.

Ngnix proxy_pass dosen't work when url contains path

im trying to mock sites from my own FS. i want to intercept any http request and redirect it to my server that will return the needed file.
i have wrote a simple default sever:
server {
listen <<SERVICE_PORT>> default_server;
server_name _;
location / {
proxy_set_header X-ORIGINAL-URI $request_uri;
proxy_set_header X-ORIGINAL-REFERRER $http_referer;
proxy_set_header X-ORIGINAL-HOST $http_host;
proxy_pass <<BROWSE_RESOURCE_URL>>/browsing/resource/;
proxy_redirect off;
}
}
when a url as "http://exapmle.com" enters it works fine. but when any path is added as "http://exapmle.com/bar" it dose not pass the to <<BROWSE_RESOURCE_URL>>/browsing/resource/. currently i recive 404 but not from my server.
offcurce i dont need the orignal uri to be concated to my proxy_pass at all.
why dosent it work for me?
From Nginx's documentation:
A request URI is passed to the server as follows:
If the proxy_pass directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI matching the location is replaced by a URI specified in the directive
So, for your given configuration, when you request http://example.com/bar:
The normalized request URI will be /bar
The URI specified in the proxy_pass directive will be /browsing/resource/
The final URI that will be passed to the backend server is /browsing/resource/bar.
You have not configured the backend server to understand /browsing/resource/bar. So it only understands /browsing/resource/. That's why your backend server returned a 404 not found.
Because you don't want Nginx to combine the request URI with the URI specified in the proxy_pass directive, you can use another feature of the proxy_pass directive as mentioned in the Nginx's documentation:
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):
...
In this case, the URI specified in the directive is ignored and the full changed request URI is passed to the server.
So you will instruct Nginx to rewrite all request URIs to the same URI /browsing/resource/ as follows:
location / {
proxy_set_header X-ORIGINAL-URI $request_uri;
proxy_set_header X-ORIGINAL-REFERRER $http_referer;
proxy_set_header X-ORIGINAL-HOST $http_host;
rewrite ^ /browsing/resource/ break;
proxy_pass <<BROWSE_RESOURCE_URL>>;
proxy_redirect off;
}

Nginx redirects instead of doing reverse proxy with proxy_pass

I have an nginx running on a docker container, which serves a web client.
I want to proxy requests from the client, so that the nginx will pass the POST requests to the server, since the actual destination endpoint is not accessible to the client.
This is the location directive:
location /zipkin {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header Host $host;
proxy_pass http://my-ip:9411/;
}
The client makes requests to http://localhost:8080/zipkin/api/v2/span, which I want the nginx to pass (without redirection) to http://my-ip:9411/api/v2/span.
What happens in practice is that I get a 301 response (to http://localhost:8080/api/v2/span), and the POST is never sent to the destination.
Edit: another try that returns 404 -
location /zipkin/ {
rewrite ^/zipkin/(.*) /$1 break;
proxy_pass http://my-ip:9411$uri; # tried 9411;, 9411/, 9411$uri, 9411$uri/
}
Here $uri is /api/v2/span.
The solution in the end was:
location ~ ^/zipkin(/?)(.*) {
proxy_pass http://my-ip:9411/$2;
}
One of my tries was ^/zipkin(.*) but it evidently didn't work.
Probably the / after the /zipkin is problematic, so (/?) removes it,
And that leaves the (.*) the clean part of the url which needs to be attached to the proxy_passed url.

How to add url prefix after host in nginx?

I have this location:
location /foo {
proxy_pass http://backend/;
proxy_set_header Host $host;
}
When I get static from http://frontserver/foo, my requests of backed url prefix: http://frontserver/..., but I'd like to see http://frontserver/foo/....
If I make something like proxy_set_header Host $host/foo; I get 400 error.
How can I make it correctly?
You should not add the URI in the proxy_set_header but in your proxy_pass directive instead. It accepts a full URI
location /foo {
proxy_pass http://backend/foo; # will work
proxy_set_header Host $host;
}
proxy_pass nginx docs
Sets the protocol and address of a proxied server and an optional URI to which a location should be mapped. As a protocol, “http” or “https” can be specified. The address can be specified as a domain name or IP address, and an optional port:
Adding it to proxy_set_header would ultimately make your reverse proxy send a hostname that includes a uri, which isn't a valid hostname.

nginx proxied redirects use the port number of the proxy, not the host

I'm setting up a web/app/db stack, and the nginx proxy configuration isn't working the way I thought it would.
so here is an example of the stack...the url of the application is:
https://testapp.com
here is the nginx config:
server {
listen 8886;
server_name _;
root /usr/share/nginx/html;
include /etc/nginx/default.d/*.conf;
#ELB
if ($http_user_agent = 'ELB-HealthChecker/2.0') {
return 200 working;
}
#HTTP to HTTPS
if ($http_x_forwarded_proto != 'https') {
return 301 https://$host$request_uri;
}
location / {
set $proxy_upstream_name "testapp.com";
port_in_redirect off;
proxy_pass http://internal-alb.amazonaws.com:8083/;
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;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header Access-Control-Allow-Origin $http_origin;}
The app is proxied to an internal AWS alb, and it forwards it to a single (at this point) application server.
I'm able to get the site to serve. However, the application creates a redirect on login, and I get the following response.
Request URL:https://testapp.com/login
Request Method:POST
Status Code:302
Remote Address:34.192.444.29:443
Referrer Policy:no-referrer-when-downgrade
Response Headers
content-language:en-US
content-length:0
date:Mon, 11 Sep 2017 18:35:34 GMT
location:http://testapp.com:8083/testCode
server:openresty/1.11.2.5
status:302
The redirect fails because it's being served on 443, not 8083.
For some reason the app or the proxy isn't updating the port as it doing it's reverse proxy thing, so that the redirect has the proxied port NOT the actual application port 443.
What do I need to do with nginx config to get it to redirect correctly.
thanks.
myles.
The normal behaviour of the nginx is to rewrite the upstream address to the address the page was served from. It looks like instead of using your upstream address (http://internal-alb.amazonaws.com:8083/), your app is responding using a mixture of the two (http://testapp.com:8083). You can either change the app behaviour, or, to fix it at the nginx level, can use the proxy_redirect directive.
I'm reasonably sure the directive to fix this is proxy_redirect http://testapp.com:8083/ https://testapp.com/;

Resources