How to configure NGINX to proxy to web server behind VPC - nginx

I have a webserver behind a VPC and normally we setup an SSH tunnel and connect to localhost with a web browser. However to make it easier to connect to the site via a mobile device I was thinking of using our NGINX installed on the bastion/gateway server to proxy requests to the web server behind the VPC. Does anyone have a configuration of what is needed in NGINX to do this?
Thanks!

Sounds like a simple reverse proxy - to expose your internal web server e.g. 172.31.0.1 to the outside at /some/path/:
location /some/path/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://172.31.0.1;
}

Related

nginx proxy pass ip from url

I have multiple web servers with IP address say 172.18.1.1 to 172.18.1.20, hosting different website on 443(https) and A nginx server which I need to use for proxying above servers.
Example :
My nginx server IP is https://10.220.5.39:9200 by giving web server in URL , I need to show the websites
i.e. https://10.220.5.39:9200/proxy/172.18.1.1, should get website of https://172.18.1.1
AND
https://10.220.5.39:9200/proxy/172.18.1.2, should get website of https://172.18.1.2
location /proxy/(?<uniqueId>[^/]+).* {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass https://$uniqueId/;
}
But it is not working , I can not use redirect , since client will not have access to web servers directly
Also some website use css file from route i.e. href="/static/theme.css"
because of which in browser console we are getting
not found https://10.220.5.39:9200/static/theme.css
Is this even possible with nginx

flask application using flask_oidc with nginx reverse proxy in docker deployed on EC2 giving Not authorized error after authentication with keycloak

I have the following setup:
1: Keycloak docker container running on an EC2 instance. (I have configured it temporarily to accept http connections)
2: My Flask applicatioĊ„ together with nginx reverse proxy running in docker on another EC2 instance.
I have created the realm and client on keycloak and configured the redirect uri.
I am able to get my flask application to reach the Keycloak instance for authentication.
I added from werkzeug.middleware.proxy_fix import ProxyFix and app.wsgi_app = ProxyFix(app.wsgi_app)to get the redirect_uri to work.
However, when the redirection happens, I get a 'Not authorized' error (i can also see 401 in nginx log).
I have set the OVERWRITE_REDIRECT_URI as OVERWRITE_REDIRECT_URI = 'https://authenticationdemo.mydomain/oidc_callback'
I configured nginx to forward the https request with endpoint oidc_callback to my flask application route /oidc_callback (i do not implement my own callback).
location /oidc_callback{
proxy_pass http:/<flask_app_name_in_docker>:<port>/oidc_callback;
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 X-Forwarded-Host $host;
proxy_redirect off;
}
I am not able to solve this problem as I am not able to figure our where the callback is going wrong. I can see the log from nginx with GET /oidc_callback?state=<...somevalue..>&session_state=<...somevalue>&code=<..somevalue...>
But after redirection this does not work.
I tried both by
using ip addresses in the redirect uri
domain name same as my certificates and configuring hosts file on the EC2 instance with keycloak to point to the correct ip address of the EC2 instance with flask application
Both are not working.
I am not able to figure out if something is going wrong in passing back the authentication information or is there some basic config wrong.
Can somebody please point to the correct approach?
I already looked up and tried information in other related questions:
Flask_oidc gives Errno 99 Cannot assign requested address when run in Docker container
flask-oidc-redirect-uri-value-being-overwritten-somewhere
flask-oidc-with-keycloak-oidc-callback-default-callback-not-working
(and read many other similar ones)
I am not looking for a custom callback. I just need the default callback behavior as it is without a reverse proxy.
Update:
I figured out that the problem was due to the failing check for matching 'OIDC_VALID_ISSUER' in the function _is_id_token_valid(self,id_token) in flask_oidc. Putting port number in the url for issuer in client_secrets was causing the problem. Removing it solved the problem.

Linode NodeBalancer Vs Nginx

I have a NodeBalancer created to route my request on Tomcat server via HTTP. I see that NodeBalancer is doing good but now I have to install Nginx server to server static contact and as well as reverse proxy to redirect my http traffic to HTTPS.
I have a below scenario--
User-----via http---->NodeBalncer(http:80) ---->Nginx--->Redirect to HTTPS---->NodeBalancer(https:443)------> Tomcat on HTTP:8080
Below is sample flow
1) User send a request using HTTP:80
2) NodeBalancer received request on HTTP:80 and forward to Nginx
3) Nginx redirect request to HTTPS
4) Now NodeBalancer received request on HTTPS:443 and forward to Serving Tomcat on HTTP:8080 after terminating SSL on NodeBalancer.
Now, if I need to serve all static content like (images/|img/|javascript/|js/|css/|stylesheets/) then before forwarding all HTTPS request via NodeBalance to serving Tomcat I need to forward them via Nginx to serve static content.
I can do it via pointing NodeBalncer to Nginx but then what about Tomcat clustering because NodeBalancer will always forward all HTTPS request to Nginx and I have to maintain session stickiness using Nginx which is pretty much like LoadBalancing via Nginx. I see everything can be done via Nginx server itself. Instead of terminating all user request to NodeBalancer I can directly use Nginx.
I did execute some scenarios by installing Nginx and redirecting HTTP to HTTPS and independently serving static content also but I stuck with provided NodeBalancer to serve my purpose. I am planing to drop Linode NodeBalncer and use Nginx as LoadBalancer as well as service static content.
Looking some expert advise/comments on this or suggest me if my approach is wrong.
Serving the static content and the redirect to https are two different issues. Your general approach sounds fine. I personally would do everything using Nginx and lose the NodeBalancer but that's for a personal website. If this is for business then you need to consider monitoring etc and NodeBalancer might provide some features you want to keep.
Send all traffic from NodeBalancer to Nginx and use Nginx as both the load balancer and to terminate all SSL traffic. Heres a simple examples that terminates SSL and serves images. In this case we're routing all traffic to the tomcat upstream server on port 80 which is load balanced using IP hash so you get sticky sessions. You would be adding a load balancer here.
upstream tomcat {
ip_hash;
server 192.168.1.1:80;
server 192.168.1.2:80;
server 192.168.1.3:80;
}
server {
listen 443;
server_name www.example.org;
ssl on;
ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;
location / {
proxy_cache example_cache;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Host www.example.org:80;
proxy_pass_request_headers on;
proxy_pass http://tomcat;
}
location /images/ {
root /var/www/images/;
autoindex off;
}
}
To achieve sticky sessions you have several options that you need to read up on. IP load balancing is probably the simplest to setup.

404s on AWS deployed MEAN app

I have a MEAN.io application deployed to AWS EC2. Its running via Nginx proxy pass on a 8087 port, config is as follows:
location /myapp/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://0.0.0.0:8087/;
}
The problem I have is that in the browser some POST/PUT requests sent via AJAX are returning 404 errors and default nginx error page. Those requests are not even making it through to Node.js server as I can see in the logs that they are not recorder. There is definately a route provided for those requests, as the app works totally fine on localhost. The same POST/PUT requests seem to work fine when queried directly using 'curl' in the console.
I am not an nginx / AWS expert, so I wanted to ask simple question - is there anyway nginx could be caching those requests and why would they return different HTTP code when queried from 'curl' or via AJAX in the browser?
I think you have a problem with the way you have configured your nginx server, please do check the following rules for nginx.
url rewriting
public folder and
static content

nginx reverse proxy and ports

I had a question regarding a proxy pass. A lot of tutorials show a configuration like this in some way or form, with a port identifed:
location / {
proxy_pass http://x.x.x.100:80;
proxy_set_header X-Real-IP $remote_addr;
}
Can someone explain to me why the port needs to be used? Does it need to be a specific number, or is it even necessary?
The explicityly specified port is:
not necessary IF you're reverse proxying to something on the default http (80) or https (443) ports
necessary if you're reverse proxying to something running on any non-default port (common when your application server and webserver are on the same host)
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass shows examples shows examples without the portnumber

Resources