SSL, Socket.io, NGINX , Node.js - node.js

I am running a node js application and having problems with NGINX lately, I could solve all of them somehow but here is the latest. When I listen my sockets from
var socket = io.connect('https://www.example.co.uk');
Any one has an idea where this problem comes?
This is my nginx file
# Sockets redirect
upstream rest_node_js {
server 127.0.0.1:8088;
}
server {
listen 443 ssl;
server_name example.co.uk;
ssl_certificate /etc/ssl/private/cert.pem;
ssl_certificate_key /etc/ssl/private/cert.key;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 5m;
location / {
proxy_pass http://rest_node_js;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_buffers 8 32k;
proxy_buffer_size 64k;
}
}
server {
listen 80;
server_name example.co.uk;
return 301 https://example.co.uk$request_uri;
}
server {
listen 80;
server_name www.example.co.uk;
rewrite ^/(.*) https://example.co.uk/$1 permanent;
}
server {
listen 443;
server_name www.example.co.uk;
rewrite ^/(.*) https://example.co.uk/$1 permanent;
}

Related

Ubuntu + Nginx + NodeJS: 502 Bad Gateway

Currently I am trying to build a small nodejs API which should work on my server behind an already existing and working nginx setup.
nginx.conf:
server {
listen 80;
listen [::]:80;
server_name *.mydomain.com;
if ($host = www.mydomain.com) {
return 301 https://$host$request_uri;
}
if ($host = mydomain.com) {
return 301 https://$host$request_uri;
}
if ($host = hello.mydomain.com) {
return 301 https://$host$request_uri;
}
return 404;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name mydomain.com www.mydomain.com;
root /var/www/html;
index index.html;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
ssl_client_certificate /etc/ssl/cloudflare.crt;
ssl_verify_client on;
location / {
try_files $uri/index.html $uri.html $uri/ $uri =404;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name hello.mydomain.com;
root /var/www/hello;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
ssl_client_certificate /etc/ssl/cloudflare.crt;
ssl_verify_client on;
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://127.0.0.1:3000$request_uri;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
index.js:
const express = require('express');
const app = express();
app.get("/", (request, response) => {
response.end("hello world");
});
app.listen(3000, () => console.log('listening'));
So i have mydomain.com and www.mydomain.com and they have nothing to do with nodejs and work fine.
The nodejs site lies behind hello.mydomain.com and just returns a 502: Bad Gateway error. When I am on my server (where everything lies) and just do:
curl localhost:3000
I get the right response. So the nodejs code works (I even approved it locally), but the nginx is not able to act as a proxy and "speak" with the local nodejs express.
Does anyone know why this does not work? I already searched through many tutorials, but I just cannot find the solution. :/

Nginx Reverse Proxy Not Matching Hostname

I have a simple API that I currently have in Apache defined by:
<VirtualHost *:80>
ServerName http://exampleapi.org
ServerAlias http://exampleapi.org
ProxyPreserveHost On
ProxyPass /api http://localhost:3000
</VirtualHost>
I needed to migrate it Nginx for various reasons so in /etc/nginx/conf.d/<domain>.confI went with:
server {
listen 80;
listen [::]:80;
server_name http://exampleapi.org;
# API endpoint
location = / {
proxy_pass http://127.0.0.1:4000;
}
}
The problem appears to be that I have another file/site in /etc/nginx/conf.d/<domain2>.confand it's always matching that, as I can clearly see from the access logs. So where in the other config is it matching everything? (Note the site name like example.com has been obfuscated with <domain>).
server {
server_name SITE_URL <domain>;
server_tokens off;
access_log /var/log/nginx/access.log;
# Max request size
client_max_body_size 20M;
large_client_header_buffers 4 256k;
root /usr/local/learninglocker/current/webapp/ui/dist/public;
# xAPI endpoints
location ~* ^/data/xAPI(.*)$ {
proxy_pass http://127.0.0.1:8081/data/xAPI$1$is_args$args;
}
# API endpoints
location = /api {
rewrite /api / break;
proxy_redirect off;
proxy_pass http://127.0.0.1:8080;
}
location ~* ^/api(.*)$ {
proxy_pass http://127.0.0.1:8080$1$is_args$args;
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;
}
# All other traffic directed to statics or Node server
location / {
try_files $uri #node_server;
}
# Node UI server
location #node_server {
proxy_pass http://localhost: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;
}
# Load configuration files for the default server block.
error_page 404 /404.html;
location = /40x.html {
root /usr/share/nginx/html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# We don't need .ht files with nginx.
location ~ /\.ht {
deny all;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = <domain>) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name SITE_URL <domain>;
return 404; # managed by Certbot
}
The server_name directive is the host header value to be looking for. It does not include the protocol.
server {
listen 80;
listen [::]:80;
server_name exampleapi.org;
# API endpoint
location / {
proxy_pass http://127.0.0.1:4000;
}
}
Also, note I changed location = / to location / because with the = it would only match that exact path nothing else which I assumed was not the plan.

How to set up nginx reverse proxy with multiple node apps

I have two Vue.js apps that I want to run on the same domain (e.g., https://localhost:8080/app1 and https://localhost:8080/app2). Both apps run in separate docker containers, and i have set up a third docker container running nginx with a reverse proxy in order to have ssl.
I am able to visit the apps at the wanted locations, but there are some resources missing (images, fonts etc). I realize that my nginx server looks for them at https://localhost:8080/my_resource, but I can't figure out how to forward these to the correct locations (i.e., https://localhost:8080/app1/my_resource, and similar for app2).
I've tried using the "try_files" directive in nginx, like so:
location / {
try_files $uri $uri/ http://app1:8080 http://app2:8080
}
but it does not work.
Here is my nginx config file
server {
listen 80;
listen [::]:80;
server_name localhost;
return 301 https://$server_name$request_uri;
}
# Change the default configuration to enable ssl
server {
listen 443 ssl;
listen [::443] ssl;
ssl_certificate /etc/nginx/certs/my_app.crt;
ssl_certificate_key /etc/nginx/certs/my_app.key;
server_name localhost;
server_tokens off;
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;
location / {
if ($http_referer = "https://localhost:8080/app1/") {
proxy_pass http://app1:8080;
break;
}
if ($http_referer = "https://localhost:8080/app2/") {
proxy_pass http://app2:8080;
break;
}
}
location /app1/ {
proxy_pass http://app1:8080/;
}
location /app2/ {
proxy_pass http://app2:8080/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
And this is my docker-compose
version: "3.6"
services:
app1:
image: "app1"
expose:
- "8080"
command: ["serve", "-s", "/app/app1/dist", "-l", "8080"]
app2:
image: "app2"
expose:
- "8080"
command: ["serve", "-s", "/app/app2/dist", "-l", "8080"]
nginx:
image: "nginx"
ports:
- "8080:443"
depends_on:
- "app1"
- "app2"
Thanks for any input :)
After a lot of trial and error, I found a solution. I do not think this is the optimal solution, but it's working. Here is my nginx configuration:
# Pass any http request to the https service
server {
listen 80;
listen [::]:80;
server_name localhost;
return 301 https://$server_name$request_uri;
}
# Configure the ssl service
server {
listen 443 ssl;
listen [::443] ssl;
ssl_certificate /etc/nginx/certs/my_app.crt;
ssl_certificate_key /etc/nginx/certs/my_app.key;
server_name localhost;
server_tokens off;
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;
location / {
proxy_intercept_errors on;
error_page 404 = #second;
proxy_pass http://app1:80;
}
location #second {
proxy_pass http://app2:80;
}
location /app1/ {
rewrite ^/app1(.*) /$1 break;
proxy_pass http://app1:80;
}
location /app2/ {
rewrite ^/app2(.*) /$1 break;
proxy_pass http://app2:80;
}
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

Nginx - URL with www dont redirect

I have nginx installation which is working as proxy for a site. Please see config below
proxy_cache_path /tmp/cache levels=1:2 keys_zone=STATIC:10m inactive=10m max_size=1g;
server {
listen 80;
server_name domain.com www.domain.com;
client_max_body_size 20M;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://domainserver.com:8000;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
}
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}
location = /home-garden {
rewrite 301 http://domain.com/category/forsale/home-and-garden/;
}
}
What I want to do is
URL
http://www.domain.com/home-garden should redirect to http://domain.com/new-home-garden
Also,
http://domain.com/home-garden should redirect to http://domain.com/new-home-garden
Let me know if I gave enough information and if someone can help me
You'll need to add a new server block to catch www.domain.com and then redirect to domain.com. This is the first server block below. Note that this will redirect all requests from www.domain.com to domain.com. If this is not the intention, it can be customised.
Then, you'll need to remove www.domain.com from the server_name directive in the second server block.
For the redirect, define a new location block as shown below.
proxy_cache_path /tmp/cache levels=1:2 keys_zone=STATIC:10m inactive=10m max_size=1g;
server {
listen 80;
server_name www.domain.com;
return 301 http://domain.com$request_uri;
}
server {
listen 80;
server_name domain.com;
client_max_body_size 20M;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://domainserver.com:8000;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
}
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}
location ^~ /home-garden {
rewrite 301 http://domain.com/new-home-garden/;
}
}

Same redirect works for one www to non-www domain, but create redirect loop for the second using nginx

I have 2 Meteor apps using Nginx to redirect to different ports. For each app I have configuration files that are the same, but different ports and domains. First one redirects from www to non-www without any problem, but second one shows message :
This webpage has a redirect loop
In my-domain1.conf:
server {
server_name www.saveting.com;
return 301 $scheme://saveting.com$request_uri;
}
server {
listen 80;
server_name saveting.com www.saveting.com;
access_log /var/log/nginx/app.dev.access.log;
error_log /var/log/nginx/app.dev.error.log;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header X-Forwarded-For $remote_addr;
}
}
in the my-domain2.conf:
server {
server_name www.downloadinstagramvideo.com;
return 301 $scheme://downloadinstagramvideo.com$request_uri;
}
server {
listen 80;
server_name downloadinstragramvideo.com www.downloadinstagramvideo.com;
access_log /var/log/nginx/app.dev.access.log;
error_log /var/log/nginx/app.dev.error.log;
location / {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header X-Forwarded-For $remote_addr;
}
}
I tried to make one redirect for all domains using this tutorial, using following code:
server {
server_name "~^(?!www\.).*" ;
return 301 $scheme://www.$host$request_uri;
}
but that didn't work for any at all. What can cause redirect loop in the second one?
The server_name in the second/forth block includes the name of the first/third block, which is wrong. Each server block should have non-overlapping names. Such as:
server {
server_name www.saveting.com;
...
}
server {
server_name saveting.com;
...
}
server {
server_name www.downloadinstagramvideo.com;
...
}
server {
server_name downloadinstragramvideo.com;
...
}

Resources