Nginx | 2 Domains (1x Node App, 1x Static HTML) on one server - html

I am having trouble running one node app and one static page (just html) on two seperate domains at the same time. No matter what I tried the static domain gets always redirected to the node app (on port 3000)
Here are the "sites-available" files :
Node App :
server {
listen [::]:80;
listen 80;
server_name www.domain1.com domain1.com;
# and redirect to the https host (declared below)
return 301 https://domain1.com$request_uri;
}
server {
listen 443;
server_name domain1.com www.domain1.com;
ssl on;
# Use certificate and key provided by Let's Encrypt:
ssl_certificate /etc/letsencrypt/live/domain1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain1.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 Host $http_host;
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;
}
}
And the static one :
server {
listen [::]:80;
listen 80;
#server_name www.domain2.com domain2.com;
root /var/www/html/domain2;
index index.html index.htm;
return 301 https://domain2.com$request_uri;
}
server {
listen [::]:443 ssl;
listen 443 ssl;
root /var/www/html/domain2;
index index.html index.htm;
ssl_certificate /etc/letsencrypt/live/domain2.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain2.com/privkey.pem;
}
The default config file is empty. Any help/hint would be greatly appreciated.
It worked fine until I generated a Let's encrypt certificate for domain2, put both domains in seperate configs and removed the default.
Thank you in advance!

The problem is that you have no server_name directive in your static domain configuration. As a result, the request is always caught by your default server block, which appears to be your node app.
See for details:
How nginx processes a request
Server names
Configuring HTTPS servers

Related

Tons of timeouts from Node.JS Express API hosted on Nginx behind Cloudflare

I have a Node.JS Express API (MySQL) hosted on Nginx behind Cloudflare (2 instances running). I'm getting a lot of 504 timeout on Roblox and upstream timed out on Nginx. I have never seen a request I sent with Postman fail. I think it happens more under load. These instances are processing processing 11M requests a week. This is hosted on a 16 core, 64 GB RAM, dedicated server with 2-3 load average
Nginx error log spams these:
upstream timed out (110: Connection timed out) while reading response header from upstream
no live upstreams while connecting to upstream
upstream prematurely closed connection while reading response header from upstream
The upstream timed out errors are the concern as they are the majority of the errors.
Generally, I don't do too much processing on the API. I have less then a dozen endpoints that are mostly simple DB selects.
Can someone direct me in the right area to resolve this? Is it my Nginx config, do I need more instances, is it my design, is it Roblox, is it Cloudflare? I read Node.js can handle this (under one instance), so I tried to adjust worker connections in Nginx which caused more no live upstream errors. I cannot wrap my head around what the bottle neck is.
Site Config
proxy_cache_path /tmp/NGINX_cache/ keys_zone=backcache:10m;
map $http_upgrade $connection_upgrade {
default upgrade;
' ' close;
}
upstream nodejs {
# Use IP Hash for session persistence
ip_hash;
keepalive 90;
# List of Node.js application servers
server localhost:9000;
server localhost:9001;
}
# HTTP: www and non-www to https
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
# HTTPS: non-www to www
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /example/example.com.cert.pem;
ssl_certificate_key /example/example.com.key.pem;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
# HTTPS: www
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /example/example.com.cert.pem;
ssl_certificate_key /example/example.com.key.pem;
server_name www.example.com;
location / {
return 301 $scheme://www.example.example$request_uri;
}
location /api {
proxy_pass https://nodejs;
proxy_cache backcache;
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;
proxy_read_timeout 90;
proxy_redirect https://nodejs https://www.example.com;
}
location /api_staging {
proxy_pass https://localhost:8000;
proxy_cache backcache;
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;
proxy_read_timeout 90;
proxy_redirect https://localhost:8000 https://www.example.com;
}
location /api_development {
proxy_pass https://localhost:7000;
proxy_cache backcache;
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;
proxy_read_timeout 90;
proxy_redirect https://localhost:7000 https://www.example.com;
}
}
Nginx Config
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 1000;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
client_max_body_size 100M;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}
Cloudflare Edits
Proxied is on
Full strict SSL
All Roblox IPs are allowed through firewall

Nginx reverse proxy works fine with Safari and Firefox but doesn't work with Chrome

I use Nginx as reverse proxy to forward my Https request to backend server (which runs in Http protocol with port 7654 in the same server). Everything works well in Safari and Firefox, but Chrome throws an error.
Chrome Error: net::ERR_CERT_AUTHORITY_INVALID
Below is my nginx.conf file. BTW, it also works fine when I use IP address instead of domain name in Chrome. How can I fix this problem?
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name mydomain.name.lan;
root /usr/share/nginx/html;
ssl_certificate "/etc/pki/tls/certs/crt.crt";
ssl_certificate_key "/etc/pki/tls/private/key.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
try_files $uri $uri/ /index.html;
}
location /app/v1/ {
proxy_pass http://localhost:7654;
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 https;
}
}
i can give you an example of working config, which works for all browsers (currently latest releases) which we use at company. TLDR story behind, we have docker swarm deployment, but we have entry point Nginx which runs on host, and has another Nginx inside container which then redirects trafic to specific API gateways and so on..
We are gonna focus on that first level Nginx (which is on host), which actually does all SSL checks and so on .. we use http inside docker (between pods & containers)..
Working example for linux:
server_tokens off;
server {
listen 443 http2 ssl;
server_name development.docker.company.si;
add_header Strict-Transport-Security "max-age=31536000" always;
proxy_buffering off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
set $upstream_local_docker_proxy 10.10.0.2; #static location of inner nginx
ssl_certificate /etc/tls/si.company.docker.development-chain.crt;
ssl_certificate_key /etc/tls/si.company.docker.development-unencrypted.key;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_protocols TLSv1.2 TLSv1.3;
#here we just have /url-location-level-routing/ , in case you want to know
location /my-application-demo/ {
proxy_pass http://$upstream_local_docker_proxy;
proxy_set_header Host local.docker.company-my-application-demo;
rewrite ^/my-application-demo/(.*) /$1 break;
}
}
For a specific case you have, i have a windows config, all u need to do is change windows path of certs to linux and it should work:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
upstream local-company1-api {
server localhost:5000;
}
server {
listen 443 http2 ssl;
server_name company1.company.si;
add_header Strict-Transport-Security "max-age=31536000" always;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
ssl_certificate C:\\tls\\si.company.company1-chain.pem;
ssl_certificate_key C:\\tls\\si.company.company1-unencrypted.pem;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_protocols TLSv1.2 TLSv1.3;
# ----------------------------------------------------------------------------------------------------
location / {
proxy_pass http://local-company1-api/;
proxy_redirect off;
}
}
}
I hope any of this helps.

Error "Request failed with status code 404"

I'm running a "universal" Nuxt project on NGINX+MYSQL+PHP Ubuntu 18.04 server. Some pages use Axios to get data from a database (JSON files created by PHP). The project is working fine on dev and production mode. Server using nginx as a reverse proxy (localhost:3000 -> localhost:80).
But after I installed HTTPS and SSL certificates (DigitalOcean manual: How To Secure Nginx with Let's Encrypt on Ubuntu 18.04) server starts to show error in production mode:
ERROR Request failed with status code 404
at createError (node_modules/axios/lib/core/createError.js:16:15)
at settle (node_modules/axios/lib/core/settle.js:18:12)
at IncomingMessage.handleStreamEnd (node_modules/axios/lib/adapters/http.js:201:11)
at IncomingMessage.emit (events.js:194:15)
at IncomingMessage.EventEmitter.emit (domain.js:441:20)
at endReadableNT (_stream_readable.js:1125:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
I tried an example of nginx configuration from Nuxt official site. But Error keep appears.
My config file /etc/nginx/site-available/web_site.com
map $sent_http_content_type $expires {
"text/html" epoch;
"text/html; charset=utf-8" epoch;
default off;
}
server {
root /var/www/html;
server_name web_site.com www.web_site.com;
gzip on;
gzip_types text/plain application/xml text/css application/javascript;
gzip_min_length 1000;
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/web_site.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/web_site.com/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
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 Host $host;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location /basemysql {
auth_basic "Admin Login";
auth_basic_user_file /etc/nginx/pma_pass;
}
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 Host $host;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
}
server {
if ($host = www.web_site.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = web_site.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name web_site.com www.web_site.com;
return 404; # managed by Certbot
}
The app fully functional until you try to reload it. An error appears every time I'm trying to reload any page that has Axios.
I found the problem. Redirection from HTTP to HTTPS causing the error.
I deleted these configurations and it works fine.
server {
if ($host = www.web_site.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = web_site.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name web_site.com www.web_site.com;
return 404; # managed by Certbot
}

redirect http request to https on nginx server

I am running an app on a digital ocean server using ubuntu 14.04 and nginx. My app runs via gunicorn. I would like to redirect http request directly to https.
I tried
server {
# Running port
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
and it works on safari. But it does not work on Chrome or Firefox? Any idea what I do wrong?
I attached the entire nginx.conf file below
worker_processes 1;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
sendfile on;
gzip on;
gzip_http_version 1.1;
gzip_comp_level 5;
gzip_proxied any;
gzip_min_length 256;
gzip_vary on;
# Configuration containing list of application servers
upstream app_servers {
server 127.0.0.1:8080;
}
# Configuration for Nginx
server {
# Running port
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
# Settings to serve static files
location /static/ {
# Example:
# root /full/path/to/application/static/file/dir;
root /var/www/example/app/;
location ~* \.(jpg|woff|jpeg|png|gif|ico|css)$ {
expires 30d;
}
location ~* \.(js)$ {
expires 1d;
}
# we do not cache html, xml or json
location ~* \.(?:manifest|appcache|html?|xml|json)$ {
expires -1;
# access_log logs/static.log; # I don't usually include a static log
}
location ~* \.(pdf)$ {
expires 30d;
}
}
# Serve a static file (ex. favico)
# outside /static directory
location = /favico.ico {
root /app/favico.ico;
gzip_static on;
}
}
server {
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/ssl/certs/dhparam.pem;
# Proxy connections to the application servers
# app_servers
location / {
proxy_connect_timeout 300s;
proxy_read_timeout 300s;
proxy_pass http://app_servers;
proxy_redirect off;
# proxy_redirect http:// https://;
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-Host $server_name;
}
}
}
First of all you should not serve anything on http. Everything should be on https, even favico.ico
worker_processes 1;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
sendfile on;
gzip on;
gzip_http_version 1.1;
gzip_comp_level 5;
gzip_proxied any;
gzip_min_length 256;
gzip_vary on;
# Configuration containing list of application servers
upstream app_servers {
server 127.0.0.1:8080;
}
# Configuration for Nginx
server {
# Running port
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/ssl/certs/dhparam.pem;
# Settings to serve static files
location /static/ {
# Example:
# root /full/path/to/application/static/file/dir;
root /var/www/example/app/;
location ~* \.(jpg|woff|jpeg|png|gif|ico|css)$ {
expires 30d;
}
location ~* \.(js)$ {
expires 1d;
}
# we do not cache html, xml or json
location ~* \.(?:manifest|appcache|html?|xml|json)$ {
expires -1;
# access_log logs/static.log; # I don't usually include a static log
}
location ~* \.(pdf)$ {
expires 30d;
}
}
# Serve a static file (ex. favico)
# outside /static directory
location = /favico.ico {
root /app/favico.ico;
gzip_static on;
}
# Proxy connections to the application servers
# app_servers
location / {
proxy_connect_timeout 300s;
proxy_read_timeout 300s;
proxy_pass http://app_servers;
proxy_redirect off;
# proxy_redirect http:// https://;
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-Host $server_name;
}
}
}
Next when you test in chrome or any other browser, make sure to open a Private or a Incognito window.

Configure Nginx to use several directories

There config nginx that when referring to http://example.com/sellers
must give the server from folder /data/sellers
In another case - of folder /data/customers
Nginx config:
server {
listen 80;
server_name localhost;
index index.html index.htm home.html;
location /sellers {
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;
rewrite ^/sellers/?(.*) /$1 break;
root /data/sellers;
}
location / {
root /data/customers;
}
}
Everything works, but is not entirely correct: when accessing the server sellers somehow uses index.html from folder /data/customers/index.html
And all the rest of the folder /data/sellers (this is correct)
What can be wrong? Why nginx takes the wrong index.html file, even though all the rest of Georgia right?
Answer
server {
listen 80;
server_name localhost;
index index.html index.htm home.html;
root /data/customers;
location /sellers {
alias /data/sellers;
}
}