Nginx location to FLASK route - nginx

I have 2 docker containers running. 1 is FLASK and 2 is Nginx.
This is the configuration of the Nginx location
location /search/?(.*) {
proxy_pass http://backend:8080/search/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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_pass_request_headers on;
}
The FLASK is running on port 8080 and the route #app.route('/search', methods=['GET']) and running with app.config['SERVER_NAME'] = 'mydomain.com'
When I try to send a GET request to "mydomain.com" (going through the NGINX) from external I get
Cannot GET /search
When I remove app.config['SERVER_NAME'] = 'mydomain.com' from the FLASK I can send GET to EXTERNAL_IP:8080 (Directly to the backend not though the NGINX).
But when I leave the app.config['SERVER_NAME'] = 'mydomain.com' and try to GET mydomain.com:8080 I get 404 Not Found
What am I missing here?
I want all requests to go though the NGINX and I want to use mydomain.com

I think your main mistake is that you trying to match the whole request URI including the query part while location directive (as well as the rewrite one) works with the normalized URI which doesn't include the query part at all (check the location directive documentation to find out what URI normalization is). Looks like you are also trying to use a regex while regex location should be declared using a ~ (or ~*) modifier. Nevertheless you don't need any regex locations at all for your particular case. To proxy a single API endpoint preservig the Host HTTP header value, you can try this one:
location = /search {
proxy_pass http://backend:8080;
proxy_set_header Host $http_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;
}
You don't need to specify an URI with the proxy_pass directive since you are not changing your request URI. If your API endpoint is /search/ rather than /search, change the location accordingly. If it is an URI path prefix rather than a single API endpoint, use a prefix location /search/ { ... } instead of exact match location.

Related

Nginx Location Regex for keycloak

I have a keycloak, react web and a spring boot app are living behind nginx.
The frontend (react) and the backend (spring boot) are calling the keycloak service over the nginx proxy at the flowing urls:
realms/.../..etc
admin/.../..etc
js/.../.../..etc
resources/.../...etc
All those urls are reverse proxing to:
Http://keylock:8180
I don't want to implements multiple locations in nginx for all those urls!
I am thinking about url rewriting to
auth/realms/...
auth/dmin/..
...
Or another clean solution with regex, but i don't know how.
You can use the rewrite module for this.
location /auth {
rewrite ^/auth(/|$)(.*) /$2/ break;
proxy_pass http://keylock:8180;
}
In fact, with this method, I get the second part of the url and proxy it.
For example, when request send to /auth/realms/... the url rewrite to /realms/... and send it to keycloak http://keylock:8180/realms/...
this worked for me
location ~ ^/(realms|js|resources|admin)/ {
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-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header Host $http_host;
proxy_pass http://keycloak;
proxy_redirect off;
}

Return website host url instead of api url

I have a Nginx server with reverse proxy for my API. How can I return the website host URL instead of returning the API URL api.example.com, because when I make a request from website it returns the API URL not the website URL app.example.com.
location /api/1 {
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 https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Connection 'updgrade';
proxy_set_header Host $host;
proxy_pass https://api.example.com/rest;
proxy_ssl_server_name on;
}
p/s: sorry for my bad english
if you want to change url in returned your application code and your application behind the proxy makes references to api.example.com instead of app.example.com, you need to change your application logic to return correct URL in this use case.
Or use sub_filter module, But you need to check your nginx was built with this module.

Accessing WSO2-APIM using Nginx

I am accessing my wso2 apim,store and publisher using Nginx.
and want to access using the following:
wso2 api manager to be accessed using nginx url as:
https://nginx-ip/wso2am/carbon
wso2 store to be accessed using nginx url as:
https://nginx-ip/wso2am/store
wso2 store to be accessed using nginx url as:
https://nginx-ip/wso2am/publisher
I tried using nested location block inside location block but wasn't successful.
So, now I am working by having a location block for all of them separately but the same also doesn't works.
Here is my nginx configuration file for store:
location /wso2am/store/
{
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://wso2-ip:9443/store/;
proxy_redirect https://$http_host/store/ /wso2am/store/;
proxy_cookie_path / /wso2am/;
limit_rate 25M;
#limit_req zone=wso2am burst=100 nodelay;
}
For the above configuration the GUI for store doesn't appears properly.
Similarly for publisher and carbon(for apim management console).
And the nested nginx configuration is as follows:
location /wso2am/ {
location /wso2am/store/
{
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://wso2-ip:9443/store/;
proxy_redirect https://$http_host/oauth2/callback /oauth2/callback;
proxy_redirect https://$http_host/ /wso2am/store/;
proxy_redirect https://$http_host/wso2am/ /wso2am/store/;
proxy_redirect https://$http_host/store/ /wso2am/store/;
proxy_cookie_path / /wso2am/;
limit_rate 25M;
}
}
Where do I have to change in headers or any other location to go correct?
Update 1:
My wso2am store and publisher are working after incorporating the comments and using the following nginx conf:
location /wso2am/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://wso2-apim-ip:9443/;
proxy_redirect https://$http_host/carbon/ /wso2am/carbon/;
proxy_redirect https://$http_host/store/ /wso2am/store/;
proxy_redirect https://$http_host/publisher/ /wso2am/publisher/;
proxy_cookie_path / /wso2am/;
}
Note: But using the above configuration,I login to apim-carbon,I get logged in and then if I click on any of the options on the home page such as list,add.I get logged out and the reason behind it after investigation was the CSRF token is not being sent in the request while accessing it using Nginx.
How can the csrfprevention.js issue be resolved keeping it true.?
Disclamer: this is an incomplete answer, for I am myself digging into this question
I faced the very same issue with both wso2am and wso2ei. I am pretty sure that we need to edit /repository/conf/carbon.xml in this section (I must admit that the comments are not crystal clear):
<!--
Webapp context root of WSO2 Carbon management console.
-->
<WebContextRoot>/wso2am</WebContextRoot>
<!--
Proxy context path is a useful parameter to add a proxy path when a Carbon server is fronted by reverse proxy. In addition
to the proxy host and proxy port this parameter allows you add a path component to external URLs. e.g.
URL of the Carbon server -> https://10.100.1.1:9443/carbon
URL of the reverse proxy -> https://prod.abc.com/appserver/carbon
appserver - proxy context path. This specially required whenever you are generating URLs to displace in
Carbon UI components.
-->
<MgtProxyContextPath>/</MgtProxyContextPath>
<ProxyContextPath>/wso2am</ProxyContextPath>
The following works if your Nginx listen to 443 in SSL mode (couldn't do it with HTTP because of the redirections -> make a self signed certificate if you plan to use it on a local network)
location /wso2am {
proxy_pass https://wso2_apimanager_container:9443;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_ssl_verify off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /wso2am/store {
proxy_pass https://wso2_apimanager:9443/store;
}
location /wso2am/publisher {
proxy_pass https://wso2_apimanager:9443/publisher;
}
location /wso2am/admin {
proxy_pass https://wso2_apimanager:9443/admin;
}
}
It works but I am not completely sure why. Can someone explain to me in which aspect <MgtProxyContextPath> differs from </MgtProxyContextPath> and from <WebContextRoot>?
allow proxy for admin publisher and store: to make /publisher, /store and /admin accessible, you need to edit the end of their respective site.json located in /repository/deployment/server/jaggeryapps/name_of_the_service/site/conf/site.json . For /publisher, you would write:
"reverseProxy" : {
"enabled" : "auto", // values true , false , "auto" - will look for X-Forwarded-* headers
"host" : "some.ip.or.domain", // If reverse proxy do not have a domain name use IP
"context":"/wso2am/publisher",
//"regContext":"" // Use only if different path is used for registry
},
Still have issue with the login though
You can follow this guide [1] to configure WSO2 API Manager with Nginx.
[1] -
https://docs.wso2.com/display/AM260/Configuring+the+Proxy+Server+and+the+Load+Balancer

Nginx - proxy_pass to google storage bucket does not use the index directive

I am trying to set my root(/) location to be passed to a google bucket.
Here is my configuration:
listen 80;
location / {
rewrite /(.*) /$1 break;
proxy_pass https://storage.googleapis.com/my-google-bucket-name/$1$is_args$args;
proxy_redirect off;
index my_main.html;
proxy_set_header Host "storage.googleapis.com";
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 Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
This seems to work but the index directive does not set the default page (to my_main.html)
e.g. when i go to http://my_enginx_url/ instead of reaching "my_main.html" i reach the google bucket root page that shows an XML file with all the files in that bucket.
P.S
Both
http://my_enginx_url/another_page.html,
http://my_enginx_url/yet_another_page.html
are working fine.
Any ideas?
Because the index directive tells Nginx the names of files to look for within your file system which are appropriate for serving a request ending with a /
You are proxying the request to another server, so it's not applicable here.
To achieve your desired result create another location directive above your current one and use = to tell Nginx this is to handle only requests for an exact match with http://my_enginx_url/
Something like this:
location = / {
proxy_pass https://storage.googleapis.com/my-google-bucket-name/my_main.html;
......
}

Nginx, proxy_pass on route with params and id's

I am trying to set a set a difficult proxy pass within Nginx. The URL itself requires a bunch id's and then has a query string at the end.
location /api/v1/schools/(.*)/courses/(.*)/years/(.*)/api_end_point/(.*) {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host some-cool-api.test.io;
proxy_pass https://10.0.0.2/$1$is_args$args;
}
I tried the above but it's not matching the route
here is an example of what the URL will look like:
"/api/v1/schools/51/courses/231/years/3595/api_end_point?thing_1=0&thing2=0&thing_3=0&thing_4=0&thing_5=0&thing_6=0&thig_7=11250&thing_8=0"
Any idea's on how to do the above?

Resources