Can't Connect to Meteor Web Socket through React Native - nginx

I am currently hosting a bundled Meteor app on Digital Ocean with nginx using this tutorial
I am using the react-native-meteor package in React Native to connect to this server. When the server is hosted on localhost, Meteor.connect(ws://192.168.0.2:3000/websocket) works.
Also, when the app is running on Digital Ocean, I am able to connect to the meteor server's webpage with https://XXX.XXX.X.XX after bypassing security warning and the websocket with wss://XXX.XXX.X.XX/websocket.
However, running Meteor.connect(wss://XXX.XXX.X.XX/websocket) or Meteor.connect(ws://XXX.XXX.X.XX/websocket) do not work.
Here is the nginx config:
server_tokens off; # for security-by-obscurity: stop displaying nginx version
# this section is needed to proxy web-socket connections
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# HTTP
server {
listen 80 default_server; # if this is not a default server, remove "default_server"
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html; # root is irrelevant
index index.html index.htm; # this is also irrelevant
server_name XXX.XXX.X.X; # the domain on which we want to host the application. Since we set "default_server" previously, nginx will answer all hosts anyway.
# redirect non-SSL to SSL
location / {
rewrite ^ https://$server_name$request_uri? permanent;
}
}
# HTTPS server
server {
listen 443 ssl spdy; # we enable SPDY here
server_name XXX.XXX.X.X; # this domain must match Common Name (CN) in the SSL certificate
root html; # irrelevant
index index.html; # irrelevant
ssl_certificate /etc/nginx/ssl/budget.pem; # full path to SSL certificate and CA certificate concatenated together
ssl_certificate_key /etc/nginx/ssl/budget.key; # full path to SSL key
# performance enhancement for SSL
ssl_stapling on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
# safety enhancement to SSL: make sure we actually use a safe cipher
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK';
# config to enable HSTS(HTTP Strict Transport Security) https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security
# to avoid ssl stripping https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping
add_header Strict-Transport-Security "max-age=31536000;";
# If your application is not compatible with IE <= 10, this will redirect visitors to a page advising a browser update
# This works because IE 11 does not present itself as MSIE anymore
if ($http_user_agent ~ "MSIE" ) {
return 303 https://browser-update.org/update.html;
}
# pass all requests to Meteor
location / {
proxy_pass http://0.0.0.0:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # allow websockets
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $remote_addr; # preserve client IP
# this setting allows the browser to cache the application in a way compatible with Meteor
# on every applicaiton update the name of CSS and JS file is different, so they can be cache infinitely (here: 30 days)
# the root path (/) MUST NOT be cached
if ($uri != '/') {
expires 30d;
}
}
}
Any help is appreciated!

You should update your question to show the error message (open you browser javascript console then refresh your link and recreate the error condition)
... your nginx config must include these settings
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
in your nginx config as per
location / {
proxy_pass http://GKE_NGINX_NODEJS_ENDUSER_SERVER_IP:3000/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
# Include support for web sockets:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
in addition to above assure you have this in your server block
server {
server_name example.com;
and not the IP of the server as per :
server_name XXX.XXX.X.X; # this domain must match Common Name (CN) in the SSL certificate
there are many moving parts ... assure you have defined the environment variable METEOR_SETTINGS prior to launching your app when you execute node
METEOR_SETTINGS={
"public": {
"rootUrl": "https://example.com",
< ... more here ... >
},
"cordova": {
"localhost": "http://localhost:12416"
},
< ... more here ... >
}

Related

Nginx returns web requests with internal IP address

I am deploying InvenioRDM as local.
Here is a gist of the limitations.
InvenioRDM as local instance for prototyping
Application is strictly IP address and port bound
Aim is to link IP to URL in a seamless manner
The work so far:
InvenioRDM local instance exposes application frontend only
Approaches:
i) Mimic production: The Nginx configuration was initially setup that
mirrored the production. The production environment is purely
containers. Very complex so i decided to try a simpler approach.
ii) Transparent Proxy: Use Nginx to pass on everything and replace
the URLs at ingress (proxy_pass) and egress (proxy_redirect). The
benefit is to simplify the web server configuration as the
application does handle http requests.
My default.conf is as follows.
# HTTP server
server {
# Redirects all requests to https. - this is in addition to HAProxy which
# already redirects http to https. This redirect is needed in case you access
# the server directly (e.g. useful for debugging).
listen 80; # IPv4
server_name server.name;
return 301 https://$host$request_uri;
}
#HTTPS Server
server {
listen 443 ssl;
server_name server.name;
charset utf-8;
keepalive_timeout 5;
ssl_certificate /etc/ssl/test.crt;
ssl_certificate_key /etc/ssl/test.key;
ssl_session_cache builtin:1000 shared:SSL:50m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AE$
#ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
proxy_request_buffering off;
proxy_http_version 1.1;
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;
proxy_pass https://127.0.0.1:5000;
proxy_read_timeout 90;
proxy_redirect https://127.0.0.1:5000 https://server.name;
}
}
My issue is that when accessing publicly on the IP address server.name (hidden for obvious reasons), it returns with the internal Class A IP address (10.X.X.X) of the machine which is offcourse not accessible publicaly. What am I missing here.
I am new to this, and I am at my wits end.

Howto block nginx web site access if browsers have no ssl certificate

I am a newb and i installed jupyterhub with nginx reverse proxy on my ubuntu 18.04 server. I built my own root CA and self signed certificate with openssl. Https connections works very well if my rootCA is installed on my others computers. I want to block access for the computers who don't have my rootCA.
the file /etc/nginx/nginx.conf is untouched and my config file /etc/nginx/sites-available/jupyter.conf is:
# top-level http config for websocket headers If Upgrade is defined,
# Connection = upgrade If Upgrade is empty, Connection = close
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# HTTP server to redirect all 80 traffic to SSL/HTTPS
server {
listen 80;
server_name 192.168.4.70 mlserver.net localhost;
# Tell all requests to port 80 to be 302 redirected to HTTPS
return 302 https://$host$request_uri;
}
# HTTPS server to handle JupyterHub
server {
listen 443;
ssl on;
server_name 192.168.4.70 mlserver.net localhost;
ssl_certificate /etc/ssl/certs/mlserver.net.crt;
ssl_certificate_key /etc/ssl/private/mlserver.net.key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
#ssl_stapling on;
# Managing literal requests to the JupyterHub front end
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# websocket headers
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Scheme $scheme;
proxy_buffering off;
}
}
How can i edit this file to block access for computers who dont have certificate ?
What nginx directive add ?
Thanx.
I want to block access for the computers who don't have my rootCA.
This is not possible. The server has no information if the client has successfully validated the server certificate (i.e. clients which have the rootCA) or if a client simply skipped certificate validation (clients which don't have rootCA).
One could try to add a HSTS header so that browsers will not simply allow to ignore certificate problems. But this can also be bypassed on the client side without the server noticing, it just makes it a bit harder.
If you want to control who can access the notebook you would need proper authentication of the clients instead. Knowledge of the rootCA is not client authentication.

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.

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"
/>

WSO2 APIM: Subdomains for different contexts

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
},

Resources