NGINX Proxy to another internal NGINX - nginx

I have a single entrypoint into a microservice application which is done via NGINX proxying in the main frontend application.
I have another frontend microservice (Let's call it FE2) that is not accessible from outside.
My NGINX config of the primary frontend looks the following:
set $fe2 "<kubernetes service address of my second frontend app>";
location /fe2 {
rewrite ^/fe2/(.*)$ /$1 break;
proxy_pass http://$fe2;
proxy_redirect / /fe2;
proxy_set_header Host $host;
}
So in theory, what should happen is that all requests that come to /fe2 should be proxies to my second frontend application via the rewrite and proxypass directives.
The proxy_redirect directive is there in place to handle all the redirects that are in place in my second frontend application.
The first thing I am concerned about are the elements of my second frontend that have href properties - will they be able to send requests to proper endpoints (xxx/fe2/somepage instead of just xxx/somepage)? The second frontend application is a webpack bundle, so all the page changes should not even reach NGINX.
Second thing is more of an issue - I already deployed this setup, but noticed that when I go to xxx/fe2/ the page is just blank, and the error message states Uncaught SyntaxError: Unexpected token '<' (at main.someid.js:1:1) . The file has a .js extension, but the actual code inside is HTML, so I don't know what's going on in there(
I know that the question is complicated, but have any of you folks tried the same setup, or are there any alternatives using NGINX?
I would appreciate any help on this matter!

Related

Nginx proxy_pass to change root domain only behind ALB

I need to make a domain migration for an app hosted on ElasticBeanstalk behind ALB. This app uses various subdomains so I need to keep the subdomain and the request and change only the domain... I tried to setup a Nginx proxy_pass directive but I might have made mistakes as it does not work:
Practically what I want to achieve is a proxy for every type of request (post, get, put, delete...) that would redirect requests like anySubdomain.potato.net/anything/else to anySubdomain.carrot.io/anything/else
On the DNS side both wildcard subdomains *.potato.net and *.carrot.io are pointing to the same ElasticBeanstalk environment. So far I added this instruction into my Nginx configuration files, but it does not work as the potato.net domain is not redirected and lands directly on the hosted app without beeing proxied:
location ~ ^/(?<subdomain>\.potato\.net)/(?<path>.*)?$ {
# this is the desired directive at the end:
# proxy_pass https://$subdomain.carrot.io/$path;
# for test purposes I add the debug path below to output
# some info and make sure it was proxied:
proxy_pass https://$subdomain.carrot.io/proxydebug/$path;
}
Is there something wrong in that directive?

How to proxy between 2 apps containing shared paths in a DRY way

I'm a newbie with Ngnix and I am looking for some advice to avoid repeating location blocks and preserve functionality.
I used to have one react application react.mydomain.cc
On my Nginx configuration file I was proxing everything from / to react.mydomain.cc
location / {
try_files $uri #approute;
}
location #approute {
proxy_ssl_server_name on;
set $react "http://react.mydomain.cc";
proxy_pass $react$request_uri;
}
Now, I want to replace part of the old application with a new one without having to make changes to the old.
The logic would be.
If the users goes to www.mydomain.cc he should be proxied to the new app http://new-react.mydomain.cc
The same other paths like:
/about
/contact
/blog
/whoiam
/photos
and a few more
These pages are also active through the other subdomain http://react.mydomain.cc/about but not accessible through nginx domain, www.mydomain.cc
If the user goes to
/notes
/playground
/app/*
/internal/*
he should be proxied to the old app.
Example: the user goes to www.mydomain.cc/notes and he is proxied to http://react.mydomain.cc/notes. Then he click on the link /about and he is proxied to the new app http://new-react.mydomain.cc/about even when the old app has /about.
Can anyone help me to avoid having to repeat 20 times location blocks? I'm trying to achieve the same but in a cleaner way.
Please, let me know if edition is needed to clarify. Remember I am new.

nginx proxy all request through authentication service

Consider a dockerized environment containing the following containers:
Backend API
Front-end REACT App served using pushstate-server
Authentication Service
Nginx Container
My nginx.conf contains the following:
server {
listen 8080;
location / {
auth_request /auth;
proxy_pass http://frontend:5000;
}
location = /auth {
proxy_pass http://auth:6000;
}
error_page 403 = #error403;
location #error403 {
rewrite ^ /login$1;
proxy_pass http://frontend:5000;
}
}
When the auth_request /auth; line is commented out, everything works just fine and all frontend pages can be accessed.
As soon as I introduce the auth_request I can see the authentication service return a 403 however, it does not look like Nginx proxies to the login page.
What am I doing wrong?
There are two issues here:
Firstly, the authorization header is not forwarded to the authentication service. This was fixed with
location = /auth {
proxy_pass http://auth:6000;
proxy_pass_header Authorization;
}
Secondly, when a request is made to the frontend, nginx tries to authenticate with the auth container. As I am not authenticated, this fails and returns a 403. The nginx server then proxies to the login page on the REACT container, however, there are further request behind the scenes to retrieve css and js resources from the same container, for which the nginx gateway tries to authenticate. Again, as I am not authenticated retrieving these resources fails, so the page does not render.
A dirty solution was to add:
location /static/js/main.1e2389bc.js {
proxy_pass http://web:5000;
}
location /static/css/main.aa587518.css {
proxy_pass http://web:5000;
}
This retrieves the necessary files to render the login page with trying to authenticate. This is a bad solution as there may be other resources (favicon, other media etc.) so more blocks would need to be added. I am sure there is a simple solution using regex to sort this out in a simple way.
However, I ended up with a cleaner solution. Authenticate on requests to the backend API. This ensured that no sensitive information was displayed on the frontend without being authenticated and removed the hassle of hacking a solution to render the login page.

How do I tell TYPO3 what it's URL is when using a reverse proxy?

I have:
A url www.my-website.com
A machine running TYPO3 with some hostname like typo3-website.my.internal.domain.com
A machine running Nginx which uses proxy_pass to send requests from www.my-website.com to typo3-website.my.internal.domain.com
A DNS A record for www.my-website.com pointing to the reverse-proxy machine.
When a backend user is working in the Page module, and they do right-click 'Show' on a page, it tries to open the page at the hostname of the machine TYPO3 is running on.
I want it to open the page under the actual website URL instead.
What setting do I need to change to make this work?
Things I have already tried which did not help:
Setting the trusted hosts pattern
'reverseProxyIP' => '*'
'reverseProxyHeaderMultiValue' => 'last'
I needed to create a domain record. That partially fixed it.
This still leaves problems where images use the wrong URL in the backend.
This means, that, for example, the little dotted lines in the page tree module do not display.
To fix that, I used a clue from this forum thread. I needed to set the HTTP_HOST variable to my domain and send it to PHP fpm:
location ~ \.php$ {
try_files $uri = 404;
include ${pkgs.nginx}/conf/fastcgi.conf;
fastcgi_pass unix:/var/run/phpfpm/default.sock;
# Assorted fastcgi_blah
fastcgi_param HTTP_HOST "www.my-domain.com";
}
If you're trying to get TYPO to see the request as a request for a specific domain, you may want to use the following on your proxy block:
proxy_set_header Host $proxy_host;

Edit a header value in nginx

Background
So I've got a server running a tomcat application hidden behind an Apache proxy. The proxy provides a more user friendly url as well as SSL encryption with automatic redirects so that the app is only accessible on https.
I'm busy migrating this to an nginx proxy.
One of the issues I've had is that upon login, my app sends back a "LocationAfterLogon" header in the http response in the form of
http://192.168.x.x:8080/myapp/index.jsp.
That IP address returned is from the proxied server not visible on the internet. So then the browser gets a connection error trying to navigate to it.
As a workaround, I've used nginx directives:
proxy_hide_header: to hide the LocationAfterLogin header coming back from the proxied server
add_header: to add a new LocationAfterLogin url.
So my config looks as follows
#header for location after logon of demo app
add_header LocationAfterLogon http://example.com/demo/index.jsp;
#hide the real LocationAfterLogon
proxy_hide_header LocationAfterLogon;
The Problem
I need to be able to do a regex replace or similar on LocationAfterLogon because it won't always be to index.jsp, depending on which url was intercepted by the login page.
I am aware that I can also rewrite the tomcat app to send back a relative URL instead, but I'd like to do it all in nginx config.
I've also read about nginx more_set_headers. Haven't tried it yet. Does it allow me to edit the headers?
Apache has the Header edit directive which I was using previously, so I'm looking for something like that.
TL;DR
Is is possible to edit a header location using regex replace or similar in Nginx?
You can use the map directive to rewrite your header:
map $upstream_http_locationafterlogon $new_location {
~regexp new_value;
}
proxy_hide_header LocationAfterLogon;
add_header LocationAfterLogon $new_location;
See the documentation: http://nginx.org/en/docs/http/ngx_http_map_module.html

Resources