Socket.io with NGINX and https2 - node.js

I have node.js app which is served by NGINX. I can't connect socket.io and keep getting 404 for POST requests to establishing a connection.
It's working locally, so it must be an NGINX problem.
# HTTP - redirect all requests to HTTPS:
server {
listen 80;
listen [::]:80;
return 301 https://$host$request_uri;
}
# HTTPS - proxy requests on to local Node.js app:
server {
listen 443 ssl http2;
server_name example.com;
ssl on;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Forwarded-Proto https;
proxy_pass http://127.0.0.1:8080;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
Thanks for any help.

Since Websockets are using the Upgrade header introduced in HTTP 1.1, you'll need to specifically use this protocol in your route and set the Connection header to upgrade.
You'll also need to specify a proxy_pass directive with a unique name.
Your config would be something like that:
upstream sockets {
server localhost:8080;
}
# HTTP - redirect all requests to HTTPS:
server {
listen 80;
listen [::]:80;
return 301 https://$host$request_uri;
}
# HTTPS - proxy requests on to local Node.js app:
server {
listen 443 ssl http2;
server_name example.com;
ssl on;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $host;
proxy_pass http://sockets;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_ssl_session_reuse off;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}

Take a look a the NGINX docs.
https://www.nginx.com/blog/websocket-nginx/
enter chttp {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server 192.168.100.10:8010;
}
server {
listen 8020;
location / {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}

Related

serve react create app and Nodejs app with reverse proxy Nginx

Trying to have both apps one react create the other Nodejs run behind Nginx proxy. The followings are my configs:
server {
listen 443 ssl;
server_name site.com;
ssl_certificate /etc/site.com.pem;
ssl_certificate_key /etc/site.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location /nodejs {
root /usr/share/nodejs;
proxy_pass http://my.url.com:3009;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $remote_addr;
}
location / {
root /usr/share/react-create;
proxy_pass http://my.url.com:3011;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $remote_addr;
}
React app is being served at root but nodejs app files are not being served correctly:
// Please try with this configuration.
upstream nodejs {
server http://my.url.com:3009;
}
upstream reactjs {
server http://my.url.com:3007;
}
server {
listen 443 ssl;
server_name site.com;
ssl_certificate /etc/site.com.pem;
ssl_certificate_key /etc/site.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location /node {
root /usr/share/nodejs;
proxy_pass http://nodejs/api;
proxy_set_header Host $host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $remote_addr;
}
location /react {
root /usr/share/react-create;
proxy_pass http://reactjs;
proxy_set_header Host $host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $remote_addr;
}
First let Nginx handle serving your react static files form their build file, and reorder the location matching for Nginx and let the nodejs or the api server for later catch for Nginx:
server {
listen 443 ssl;
server_name site.com;
ssl_certificate /etc/site.com.pem;
ssl_certificate_key /etc/site.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
root /path/to/project-base/build-live/;
index index.html;
location / {
try_files $uri /index.html =404;
}
location /api {
proxy_pass http://myapistream;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
}
}

NGINX is too slow

I have my server setup on AWS EC2 instance. My APIs on the IP work perfectly, i.e. on
http://myIpAddress:3000 // Working fine
But when I configure my nginx server and pass proxy then my domain is not working as I expected:
https://myDomainAddress // Working too slow
Here is my nginx file:
server {
listen 80;
server_name myDomainAddress;
return 301 https://myDomainAddress$request_uri;
}
upstream main {
server myIpAddress:3000; #ip to nodejs server
}
server {
listen 443;
server_name myDomainAddress;
client_max_body_size 8M;
ssl on;
ssl_certificate myCert.crt;
ssl_certificate_key myKey.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://main;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;
}
}

Allow only https for multiple domains in Nginx

I want to point example.com to localhost:3000 and api.example.com to localhost:3010. Following this and this tutorial I managed to get it to work but it's not very secure. Do you guys have an idea how to restrict it to https only? If I go to http://example.com I get a "Not Secure" by the URL in Chrome.
Here's my default sites Nginx config (the one in /etc/nginx/sites-enabled/default):
server {
# HTTP — redirect all traffic to HTTPS
listen 80;
listen [::]:80 default_server ipv6only=on;
return 301 https://$host$request_uri;
# Enable HTTP/2
listen 443 ssl http2;
listen [::]:443 ssl http2;
}
Made a config file in /etc/nginx/conf.d/example.com.conf
server {
server_name example.com;
# Use SSL certificates from Letsencrypt
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Include SSL config from cipherli.st
include snippets/ssl-params.conf;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
Made another config file in /etc/nginx/conf.d/api.example.com.conf
server {
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include snippets/ssl-params.conf;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3010/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
The first thing I notice is that your server_name directive is identical in both files, even though you imply that you want your server_name in api.example.com.conf to be api.example.com.
Also, I think you have to specify the ports within the same server blocks as the server_name directive. Maybe try something like below. Since your default conf file does not specify a server_name, I don't think it'll be referenced at all.
/etc/nginx/conf.d/example.com.conf
server {
listen 80 default_server;
listen [::]:80;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
# Use SSL certificates from Letsencrypt
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Include SSL config from cipherli.st
include snippets/ssl-params.conf;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
/etc/nginx/conf.d/api.example.com.conf
server {
listen 80;
listen [::]:80;
server_name api.example.com;
return 301 https://api.example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include snippets/ssl-params.conf;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3010/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}

NGINX not routing https requests

I have a reverse proxy with nginx routing to a node web server
I setup (I thought) SSL on the web server, but it looks like when my browser attempts to resolve the https request, no connection ever starts.
I wanted to ask a couple of questions
Where do I setup the SSL? on the reverse proxy where the request is first hit? or the node server where authentication occurs?
What is wrong with my configuration (if that is the problem
https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-on-ubuntu-14-04
This is the tutorial I used
Code included (sorry I totally forgot to include)
server {
listen 443 ssl;
server_name domain www.domain.com;
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-$
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
location / {
proxy_pass http://app_server_ip:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
server {
listen 80;
server_name domain.com www.domain.com;
return 301 https://$host$request_uri;
}
1.On the reverse proxy
2.You should configure nginx file as similar following (using upstream parameter):
upstream api-app {
least_conn;
server 127.0.0.1:3000 weight=1 max_fails=0;
}
server {
listen 80;
listen 443 ssl;
server_name api.domain.net;
ssl_certificate /etc/letsencrypt/live/api.domain.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.domain.net/privkey.pem;
client_max_body_size 2000M;
large_client_header_buffers 32 128k;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://api-app;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}

nginx config - forward http to https, forward www.domain.tld to domain.tld and two subdomains

I'm trying to configure nginx to:
http://www.domain.tld --> https://domain.tld
http://domain.tld --> https://domain.tld
http://api.domain.tld --> https://api.domain.tld
The 'www'-webroot serves static HTML (AngularJS) and the API serves an Node.JS app that should 'upstream' from localhost:3000. I guess I'm in the right direction, however it doesn't seem to work for me. Here's what I've got so far:
upstream api_server {
server localhost:3000;
keepalive 64;
}
server {
listen 80;
server_name api.domain.tld;
return 301 https://api.domain.tld$request_uri;
}
server {
listen 80;
server_name *.domain.tld www.domain.tld;
return 301 https://domain.tld$request_uri;
}
server {
listen 443 ssl;
server_name api.domain.tld;
ssl_certificate /etc/ssl/ssl_cert.crt;
ssl_certificate_key /etc/ssl/ssl_key.key;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
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://api_server/;
proxy_redirect off;
}
server {
listen 443 ssl;
server_name *.domain.tld www.domain.tld;
ssl_certificate /etc/ssl/ssl_cert.crt;
ssl_certificate_key /etc/ssl/ssl_key.key;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
root /var/www/webroot/;
}
Right now this is all in my /etc/nginx/conf.d/domain.tld.conf file.
Any help would be really appreciated.
EDIT:
I've figured it out myself (a bit of help from Tan Hong Tat), so the example is updated.
If you've got any improvements please do tell, I'll update it.
Redirect HTTP to HTTPS in the server block for HTTP. Remove the listen 80 in the HTTPS server block.
server {
listen 80;
server_name domain.tld www.domain.tld;
return 301 https://domain.tld$request_uri;
}
server {
listen 80;
server_name api.domain.tld;
return 301 https://api.domain.tld$request_uri;
}
server {
listen 443 ssl;
server_name domain.tld www.domain.tld api.domain.tld;
location / {
proxy_redirect off;
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 Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_cache one;
proxy_cache_key sfs$request_uri$scheme;
proxy_pass http://domain_tld_api_server;
}
}

Resources