WSO2 APIM: Subdomains for different contexts - nginx

We have the WSO2 API Manager 1.10.0 deployed and working. Although we are trying to figure out if it is possible to have multiple subdomains for it.
For example:
store.domain.com
publisher.domain.com
carbon.domain.com
Is this at all possible? We've seen this https://docs.wso2.com/display/Carbon442/Adding+a+Custom+Proxy+Path, but this is for different applications, we want to do this only with the API Manager.
In front of the API Manager, we are using nginx with reverse proxy. Below, you can find a snippet from nginx to help while understanding the problem.
server {
listen 80;
server_name store.domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
ssl on;
ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH";#:AES128+EDH";
ssl_protocols TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=63072000";
server_name store.domain.com;
ssl_certificate /etc/nginx/ssl/domain.com/self-ssl.crt;
ssl_certificate_key /etc/nginx/ssl/domain.com/self-ssl.key;
access_log /var/log/nginx/store.log;
underscores_in_headers on;
location / {
proxy_pass http://wso2server:9443/store/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
When attempting to access with HTTP (for the store context) all works fine, but as soon as we switch this over to HTTPS this fails with the following error in nginx upstream prematurely closed connection while reading response header from upstream however, we see nothing in API Manager logs.
Thanks in advance!
Best Regards

You can solve your issue by one of following methods.
Adding proxy_redirect configs to Nginx. So nginx will rewrite all the URLs to proper URL. Please refer the following config segment.
proxy_redirect http://wso2server/ http://store.domain.com/;
Also you can achieve the same by adding reverse proxy configurations in API Manager store. To do this Open "repository/deployment/server/jaggeryapps/store/site/conf/site.json" and see the following config section
"reverseProxy" : {
"enabled" : false, // values true , false , "auto" - will look for X-Forwarded-* headers
"host" : "sample.proxydomain.com", // If reverse proxy do not have a domain name use IP
"context":"",
//"regContext":"" // Use only if different path is used for registry
},

Related

Nginx reverse proxy on Synology DSM stopped working after update to DSM 6.2.2 Update 3

I have a DS415+ with a custom setup for reverse proxy for several services running in Docker containers following this post on Reddit. Everything worked perfectly until I updated to DSM 6.2.2 Update 3. Since then, trying to access these services results in timeouts, although curl-ing localhost:port or DiskStation_LAN_address:port works fine.
I tried renewing the certificates from LetsEncrypt, taking out some of the options one at a time, clearing the connection via:
proxy_set_header Connection "";
Nothing worked...
This is my custom server.conf file:
server {
listen 80;
listen [::]:80;
server_name XXXXXXX.XXXXXXXX.XXX;
# Include this if you want to get a letsencrypt certificate for the domain you're using
location ^~ /.well-known/acme-challenge/ {
auth_basic off;
root /var/lib/letsencrypt;
default_type "text/plain";
}
# Include this if you want to automatically redirect to HTTPS
location / {
return 301 https://XXXXXXX.XXXXXXXX.XXX$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name XXXXXXX.XXXXXXXX.XXX;
large_client_header_buffers 4 32k;
# Include these if you want to use a specific certificate,
# you'll need to find the location of the letsencrypt after you get it...
# so this might need to be updated afterwards
ssl_certificate /usr/syno/etc/certificate/_archive/XXXXXX/fullchain.pem;
ssl_certificate_key /usr/syno/etc/certificate/_archive/XXXXXX/privkey.pem;
# add_header Strict-Transport-Security "max-age=15768000; includeSubdomains; preload" always;
# Include this if you want basic authentication required
# auth_basic “Restricted”;
# auth_basic_user_file /etc/nginx/.htpasswd;
# Sonarr, requires Sonarr update webhome configuration to match
location /sonarr {
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;
proxy_set_header Connection "";
proxy_intercept_errors on;
proxy_http_version 1.1;
proxy_pass http://localhost:8989;
proxy_redirect default;
}
}
Does anyone have any suggestions for diagnosing why the timeout occurs, and hopefully a solution? As I said, the services are running and can be accessed using the NAS address + port, but can't be accessed from outside. nginx is version 1.15.7. Many thanks in advance!
I feel so stupid... turns out that, for whatever reason, the port forwarding rules on my router had reset. Once I restored them, everything works perfectly well.

Reverse Proxy to VPC-Based AWS Elasticsearch Domain Without Bypassing AWS Cognito

I apologize, in advance - I'm extremely new to Nginx.
I have two VPC-based AWS Elasticsearch Domains, we'll call dev and prod. I want both domains to be inaccessible to the open internet, but available in some networks outside the VPC. To that end, I set them up as VPC-based Elasticsearch domains and planned to use a reverse proxy accessible only from the networks I wish. I've setup the dev cluster, which has no authentication, using an NGINX reverse proxy with the following config:
events{
}
http{
server {
listen 80;
server_name kibana-dev.[domain name];
location / {
proxy_http_version 1.1;
proxy_set_header Connection "Keep-Alive";
proxy_set_header Proxy-Connection "Keep-Alive";
proxy_pass https://[vpc id].[vpc region].es.amazonaws.com/_plugin/kibana/;
proxy_redirect https://[vpc id].[vpc region].es.amazonaws.com/_plugin/kibana/ https://kibana-dev.[domain name]/;
}
location ~ (/app/kibana|/app/timelion|/bundles|/es_admin|/plugins|/api|/ui|/elasticsearch|/app/opendistro-alerting) {
proxy_pass https://[vpc id].[vpc region].es.amazonaws.com;
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 $http_host;
}
}
}
This works fine.
For the prod domain, however, I'm running into an issue. I want all users, even those that use the proxy, to have to authenticate with AWS Cognito (so I don't just want to, for example, create an access policy with an IP exception for the proxy's IP address, as that bypasses Cognito).
I have used a similar NGINX config for my "prod" Elasticsearch instance, but with no luck. The Cognito login page redirects to the VPC-based URL after authentication. I've tried manually adding my proxy's URL to the Cognito app's Callback URLs, but it still redirects by default to the VPC-based URL. I've also tried manually changing the redirect URI in the Cognito URL to refer to my proxy, but I've found that after authenticating I'm redirected to the Cognito login page again - perhaps a header or something isn't getting through?
How (or can) I get this running in Nginx, so that users can access the "prod" Elasticsearch domain while still being required to authenticate with AWS Cognito?
Thank you!
Doh! I should have read the documentation more carefully. AWS provides an example Nginx conf file for a Kibana proxy with Cognito:
{
server {
listen 443;
server_name $host;
rewrite ^/$ https://$host/_plugin/kibana redirect;
ssl_certificate /etc/nginx/cert.crt;
ssl_certificate_key /etc/nginx/cert.key;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
location /_plugin/kibana {
# Forward requests to Kibana
proxy_pass https://$kibana_host/_plugin/kibana;
# Handle redirects to Cognito
proxy_redirect https://$cognito_host https://$host;
# Update cookie domain and path
proxy_cookie_domain $kibana_host $host;
proxy_cookie_path / /_plugin/kibana/;
# Response buffer settings
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
location ~ \/(log|sign|fav|forgot|change|saml|oauth2) {
# Forward requests to Cognito
proxy_pass https://$cognito_host;
# Handle redirects to Kibana
proxy_redirect https://$kibana_host https://$host;
# Update cookie domain
proxy_cookie_domain $cognito_host $host;
}
}

Running Apache OpenMeetings with Nginx Reverse Proxy?

I am trying to install Apache OpenMeetings. I however wants to use Nginx as the reverse proxy to run the application on port 443 using Let's Encrypt free SSL.
If I try to load the application on port 5080, I successfully get the interface, but when try using the domain name on port 443 HTTPS, It is not loading the resources.
Image with Errors.
Here's my nginx virtual host file.
upstream openmeetings {
server 127.0.0.1:5080;
}
server {
listen 80;
server_name openmeetings.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name openmeetings.example.com;
ssl_certificate /etc/letsencrypt/live/openmeetings.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/openmeetings.example.com/privkey.pem;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/openmeetings.access.log;
location / {
proxy_pass http://openmeetings;
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_redirect off;
}
}
I faced same problem. (vit Openmeetings 5.0.0-M4)
I found next:
Openmeetings use ajax over WebSocket.
adding
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
to http section
and
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
to location
It solve status 400 problem
Then I meet problem with Content Security Policy
I feel like connect-src policy configured automatic on first connect to server.
So after change used domain I need restart Openmeetings.
Problem with media stream play
On Check setup recording produce long browser console message ending with
onaddstream is deprecated! Use peerConnection.ontrack instead.
...
Remote ICE candidate received
Look like it incompatibility with old Firefox 54.0 on Linux
On latest Firefox 75.0 on Windows it works!
It is also necessary to rewrite server.xml referring to
nginx managed SSL with Tomcat 7
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="x-forwarded-for"
remoteIpProxiesHeader="x-forwarded-by"
protocolHeader="x-forwarded-proto"
/>

Nginx Sub domain setup

I'm trying to setup Nginx so I can have sub domains like
www.MySite.com - Main website (Works correctly)
jenkins.MySite.com - sub domain for Jenkins
gitlab.MySite.com - sub domain for Gitlab
I've tried following various tutorials and I seem to have included everything required to make this work, but still to no avail.
I've followed this: https://www.digitalocean.com/community/tutorials/how-to-configure-nginx-with-ssl-as-a-reverse-proxy-for-jenkins
and various other sources online.
[Nginx Server Block]
I've edited my nginx.conf file, I've created a new nginx/sites-available conf file for Jenkins and symlinked it to sites-enabled.
This is my default jenkins JENKINS_ARGS
JENKINS_ARGS="--webroot=/var/cache/jenkins/war --httpListenAddress=127.0.0.1 --httpPort=$HTTP_PORT -ajp13Port=$AJP_PORT"
This is an example of my jenkins server block in nginx
server
{
listen 80;
return 301 https://$host$request_uri;
}
server
{
listen 443;
server_name jenkins.MySite.com;
#ssl_certificate /etc/nginx/cert.crt;
#ssl_certificate_key /etc/nginx/cert.key;
#ssl on;
#ssl_session_cache builtin:1000 shared:SSL:10m;
#ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
#ssl_prefer_server_ciphers on;
access_log /var/log/nginx/jenkins/access.log;
location /
{
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;
# Fix the “It appears that your reverse proxy set up is broken" error.
proxy_pass http://127.0.0.1:8080;
proxy_read_timeout 90;
proxy_redirect http://127.0.0.1:8080 https://jenkins.MySite.com;
}
}
I've also created an A record in DigitalOcean - Network
and also a CNAME
Much help would be appreciated.
Thanks
All these 3-setups need separate ngnix config files and supervirosor files as you did for main site. make soft link of those files and put them in respective etc/nginx/sites-avai and sites-enable and also soft link the supervisor files to etc/supervisor/conf.d
To check whether the nginx file is properly configured, you need to test it.
sudo nginx -t

Can shiny determine the use who logged in to nginx reverse proxy

I've successfully implemented an nginx reverse proxy for my shiny-server in order to have SSL and user authentication. However, there is still a gap that I can't figure out. Is there a way for my shiny app to determine which user is actually logged in?
Here's my /etc/nginx/sites-available/default
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name myserver.com;
ssl_certificate /etc/nginx/cert.crt;
ssl_certificate_key /etc/nginx/cert.key;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/shiny.log;
location / {
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;
# Fix the “It appears that your reverse proxy set up is broken" error.
proxy_pass http://localhost:3838;
proxy_read_timeout 90;
proxy_redirect http://localhost:3838 https://myserver.com;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
}
}
With the last two lines of my location I expect to have a header with the user name. I found that tip here. I found this which allows me to see my header information but none of the headers I see are my user name.
Edit:
With Bert Neef's citation, I see why the above didn't work. However, the server does have access to the HTTP_SEC_WEBSOCKET_KEY header which is unique across sessions. It seems that if we can get Nginx to log that value then the server can look at that code to match up the header to an actual user. That being said, I don't know if that is feasible and I don't know how to get Nginx to log that value.
Based on the Shiny Docs this a Shiny Server Professional feature only and you need to use the whitelist_headers directive to get those headers:
4.9 Proxied Headers
Typically, HTTP headers sent to Shiny Server will not be forwarded to the underlying Shiny application. However, Shiny
Server Professional is able to forward specified headers into the
Shiny application using the whitelist_headers configuration directive,
which can be set globally or for a particular server or location.
Update: just tested the whitelist-headers option in a non-pro shiny server install, and I can't get the custom headers to show. I did verify the headers were send on by nginx by using netcat to show me the incoming data (nc -l 8080 and a quick change to proxy_pass in the nginx.conf file).
Update 2: can't get NGINX to log the HTTP_SEC_WEBSOCKET_KEY header (the authorization header is logged after specifying it in the log specification) and I can't see it in the traffic between nginx and Shiny Server, I think it either boils down to getting Shiny Server Professional or to modifying the shiny source code to pass the authorization header to the application.

Resources