Nginx reverse proxy root URI issue - nginx

I have an application running in Kubernetes with the following topology:
Some-ingress-controller--> nginx reverse proxy -->dynamically generated services.
I have set the NGINX reverse proxy with the following test configuration
location /mysite1/ {
proxy_set_header Host $host;
proxy_set_header Referer $http_referer;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $remote_addr;
proxy_pass http://myservice1.default.svc:9000/;
}
So far everything works fine - when I go to my website http://example.com/mysite1/ I see what I expect from the myservice1 application hosted at http://myservice1.default.svc:9000/. However, the application myservice1 issues requests to various internal (internal meaning they are part of the same container) resources on /get_resourceX. When the myservice1 application tries to access these resources they will be accessed at http://example.com/get_resourceX/ and not at http://example.com/mysite1/get_resourceX as they should - and that is my problem.
What could work is to simply reverse proxy all the relevant resource names as well. However, then I would need to do the same for http://example.com/mysite2, http://example.com/mysite3 etc. which is impractical since these are generated dynamically.
Another possible solution is to check the http Referrer header and see whether it originates from mysite1 - but that seems awfully hackish.
How can I easily have myservice1 requests issued to /get_resourceX served by itself? Is there a generic way to set the root path for the myservice1 application to myservice1?

Related

NGINX as Transparent Reverse Proxy via Upstream Proxy to External Host Issues

Due to a mess of work networks i need to setup an NGINX reverse proxy to an external website that goes via the company MPLS proxy.
This is so other apps can point to an internal DNS address via HTTPS and then that address can either point to an internal STUB App which does not go through a proxy, or it's pointed to and ALB Listening on HTTPS that is pointed to the Reverse Proxy EC2 running listening on HTTP which sends it out to the External Host as a NGINX Transparent Reverse Proxy via HTTPS.
On the EC2 Instance if i do curl -x http://111.222.333.444:1234 https://external.host.name:5678 i get back an expected result from hitting the external host but i cannot get the same responce back from my nginx x host the upstream proxy seems to be denied access "Access Denied (policy_denied)"
Since i am not on my work computer i have to manually type out my current configuration so sorry if i make a mistake (Ip Addresses and Hosts obscured for obvious security reasons)
Also to rule out SELINUX issues i've set setenforce 0 for the moment untill i can get a working connection.
There are HTTP_PROXY and HTTPS_PROXY variables on the box set to another broxy, but i don't believe NGINX is using them, though i could be wrong.
My current configs after several hours of playing around:
under /etc/nginx/conf.d/proxy.conf
upstream proxy {
server 111.222.333.444:1234
}
under /etc/nginx/default.d/reverse-proxy.conf
location / {
proxy_buffering off;
proxy_pass http://proxy;
proxy_redirect http://proxy https://external.host.name:5678;
proxy_set_header Host external.host.name;
proxy_set_header Referer $http_referer;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-For $scheme;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
}
I believe that's the whole config at current, Sorry if i've forgotten anything. Does anyone have a working config for this type of setup or show me where i'm going wrong please?
Edit:
Further Info, if i do curl http://111.222.333.444:1234/https://external.host.name:5678 I get the same error as the NGINX result
The only difference i can see is the Host Header
on the failed one the Header is "Host: 111.222.333.444:1234"
on the success the Header is "Host: external.host.name:5678" and there's an additional header "X-Forwarded-For: 555.666.777.888"
I have not been able to figure out what the ip in the X-Forwarded-For is as it's not the box i am on
I have tried the following but all i get back from the proxy is Network Error (dns_server_failure)
location / {
proxy_buffering off;
proxy_pass http://111.222.333.444:1234/https://external.host.name:5678;
proxy_set_header Host external.host.name:5678;
proxy_set_header X-Forwarded-For 555.666.777.888;
}

Nginx Custom Header as HTTP request response

I'm facing a challenge and need some help, please.emphasized text
It's quite simple, I need to set a custom header as a response from an http request to an internal app I have running on the same instance.
I have two applications running on docker in one instance.
I need to set a custom header on the APP 1 and the value of this header is an api call to APP 2.
NGINX config APP 1:
server {
server_name example.com;
location / {
proxy_pass http://localhost:6987;
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-Proto $scheme;
proxy_set_header user-code 0.0.0.0:6500?code=$geoip2Lite_data_city_name;
}
APP 2 it's a simple app that has an end-point that returns a value accordingly to the code query parameter.
This app is running on docker on the same instance.
What I'm looking for, is that all requests that comes to APP 1 have the header user-code with the actual response of the Api call.
Example:
If a user access my app from Lisbon an GET request to http://0.0.0.0:9982?code=Lisbon will be made the response of of this request is 236578552 thus the header user-code will be 236578552
Is that possible to be done in NGINX?
Thank you all in advance, Cheers!

GeoServer web UI redirects to vanilla HTTP

I have the standalone version of GeoServer 2.21.0 running behind an NGINX reverse proxy. Whenever I attempt to do anything with the web UI, Wicket is redirecting me to HTTP when I need it to send me to HTTPS.
The server does serve up map tiles correctly. It's just that the web UI is completely dysfunctional as it's running over HTTPS and GeoServer redirects everything to HTTP for some reason.
I also have the CSRF whitelist set but I'm having problems before CSRF comes into play. If I do so much as go to https://myserver/geoserver it redirects me to http://myserver/geoserver/web/?0 which doesn't work.
I have a GeoServer instance running behind NGINX. NGINX is configured like this:
location / {
proxy_pass http://127.0.0.1:9191/; 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 $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
I have the Proxy Base URL configured to https://myserver/geoserver and Use headers for Proxy URL is enabled.
What might be causing this? A Google search wasn't very helpful.
The answer was proxy_redirect ~*http://[^/]+(/.*)$ $1;
This rules tells NGINX to remove everything from the beginning http all the way up through the hostname in the redirect so that the redirect sends the user to the reverse proxy's (i.e. NGINX) host.
relevant answer

iccube behind reverse proxy

I run icCube behind an nginx acting as a reverse proxy and force https requests. icCube as a backend server is then called through http.
Requests received by jetty (icCube) are currently not https.
I need a well formatted request URI scheme (containing https) as it is used for my SSO authentication made in a custom servlet filter installed in icCube.
I presume an issue with Jetty's configuration because as described in Jetty's document regarding forwarded request: https://www.eclipse.org/jetty/javadoc/9.4.8.v20171121/org/eclipse/jetty/server/ForwardedRequestCustomizer.html
The reverse proxy (nginx) passes the following headers to jetty:
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Proxied-Https on;
proxy_set_header X-Forwarded-Proto $scheme;
I've looked in the icCube configuration class handling the jetty configuration:
crazydev.iccube.server.http.IcCubeHttpComponentConfiguration
And nothing about forwarded requests.
Jetty is shipped with default configuration files and one fits my needs: https://github.com/eclipse/jetty.project/blob/jetty-9.4.x/jetty-server/src/main/config/etc/jetty-http-forwarded.xml
How could I apply forwarding configuration ?
Thanks in advance for your help.
Prior to icCube 6.8.5, there is no way to configure an instance of ForwardedRequestCustomizer.
From icCube 6.8.5, the icCube.xml configuration file will contain a new entry for that purpose:
<forwardedRequestConfiguration>
<forwardedOnly>...</forwardedOnly>
<proxyAsAuthority>...</proxyAsAuthority>
<forwardedHeader>...</forwardedHeader>
<forwardedHostHeader>...</forwardedHostHeader>
<forwardedServerHeader>...</forwardedServerHeader>
<forwardedProtoHeader>...</forwardedProtoHeader>
<forwardedForHeader>...</forwardedForHeader>
<forwardedHttpsHeader>...</forwardedHttpsHeader>
<forwardedSslSessionIdHeader>...</forwardedSslSessionIdHeader>
<forwardedCipherSuiteHeader>...</forwardedCipherSuiteHeader>
</forwardedRequestConfiguration>

Executing Liferay behing a Nginx reverse proxy

I am trying to test the last version of Liferay (Liferay 7.0-ga4) and install it behind a reverse proxy (nginx). I am using docker and docker compose for testing purposes, and I create a dummy domain docker.domain.com.
Liferay works fine if I access directly to its url and no reverse proxy is configured.
Also, I have success to install Liferay behind the nginx server if I use the root location:
location / {
proxy_pass http://liferay:8080;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
Where liferay in the proxy_pass section is the name of the docker container linked in the docker compose. And Liferay's options:
web.server.host=docker.domain.com
web.server.protocol=http
web.server.http.port=80
To configure the reverse proxy in Liferay. The results is correct if I type http://docker.domain.com/:
I can login, accept terms and conditions, ... everything seems fine.
But when I use a location that is not root (i.e /lifeay), I have issues with links, images, and css in general.
With a configuraion in nginx similar to:
location /liferay {
proxy_pass http://liferay:8080;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
And adding as suggested here to Liferay's configuration:
portal.proxy.path=/liferay
When accessing to http://docker.domain.com/liferay all url are messed up and CSS are not shown. Here I attach an screenshot of the final result:
It is interesting the line
http://docker.domain.com/liferay/liferay
Where "liferay" appears two times in the url. Some errors appear at the liferay's tomcat log:
12:48:29,019 WARN [http-nio-8080-exec-3][code_jsp:172] {code="404", msg="/liferay/o/mentions-web/css/mentions.css", uri=/liferay/o/mentions-web/css/mentions.css}
12:48:29,021 WARN [http-nio-8080-exec-8][code_jsp:172] {code="404", msg="/liferay/o/frontend-css-web/main.css", uri=/liferay/o/frontend-css-web/main.css}
....
Obviously some files are not found. I have created a simple example with docker github to test it only spending a few minutes if somebody is interested. Still, I am pretty sure that something is missing in my Liferay configuration, but I am not able to figure out what. At least I am not able to find any clue in the official documentation.
Seems that the problem was with the the trailing slash in proxy_pass. It is what makes a difference. Following this example, the nginx configuration file will be:
location /liferay {
return 302 /liferay/;
}
location /liferay/ {
proxy_pass http://liferay:8080/;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
And now seems that Liferay CSS and URLs are correctly working.

Resources