nginx http redirect to localhost - nginx

So I have an application running on http://localhost:3000. I want to expose it to other people using nginx. I redirect http connection to https using the following configuration:
server {
listen 80 default;
server_name www.example.com;
return 301 https://$server_name$request_uri;
}
The issue is when I try to access www.example.com or http://www.example.com, it redirects me to https://localhost/ instead of https://www.example.com.
https://www.example.com redirects as intended.
For your information, www.example.com is an internal domain.
All my configuration :
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
# Disable sending the server identification
server_tokens off;
# Prevent displaying Botpress in an iframe (clickjacking protection)
add_header X-Frame-Options SAMEORIGIN;
# Prevent browsers from detecting the mimetype if not sent by the server.
add_header X-Content-Type-Options nosniff;
# Force enable the XSS filter for the website, in case it was disabled manually
add_header X-XSS-Protection "1; mode=block";
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# Load modular configuration files from the /etc/nginx/conf.d directory.
include /etc/nginx/conf.d/*.conf;
# Redirect unsecure requests to the HTTPS endpoint
server {
listen 80 default;
server_name www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 http2 ssl;
server_name www.example.com;
ssl_certificate cert.pem;
ssl_certificate_key cert.key;
# Force the use of secure protocols only
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# Enable session cache for added performances
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# Added security with HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
# We need to add specific headers so the websockets can be set up through the reverse proxy
location /socket.io/ {
proxy_pass http://localhost:3000/socket.io/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
# All other requests should be directed to the server
location / {
proxy_pass http://localhost:3000;
}
}
}
Thanks in advance for any help,

As #johnsing stated in the comment section, removing default and clearing the cache did the job.

Related

Why is nginx with multiple servername in config not working for second servername

i have a server which hosts several websites. Some normal HTML, some wordpress and some reverse proxy.
Everything is managed by nginx with conf files for each site. All is managed by Ansible which means all config files are build from the same template.
I have a nginx conf like this:
# Ansible managed
user www-data;
pid /run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 65535;
# Load modules
include /etc/nginx/modules-enabled/*.conf;
events {
multi_accept on;
worker_connections 65535;
}
http {
charset utf-8;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
log_not_found off;
types_hash_max_size 2048;
types_hash_bucket_size 64;
client_max_body_size 16M;
server_names_hash_max_size 512;
server_names_hash_bucket_size 128;
# MIME
include mime.types;
default_type application/octet-stream;
# Log Format
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# Logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
# include TLS hardening
include /etc/nginx/snippets/tls-hardening.conf;
# Load configs
include /etc/nginx/conf.d/*.conf;
server {
# catch-all server for both http and https
listen *:80 default_server;
listen *:443 default_server;
server_name _;
# SSL
ssl_certificate /etc/ssl/FQDN.bundle.crt;
ssl_certificate_key /etc/ssl/FQDN.key;
# Redirect to canonical site
#rewrite ^/(.*)$ http://example.com/$1 permanent;
# return 404
return 404;
}
}
The default part shall catch all unconfigured requests.
the configs for normal websites are looking like this:
# Ansible managed
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name FQDN www.FQDN;
root /var/www/FQDN;
index index.html index.htm;
# SSL
ssl_certificate /etc/letsencrypt/live/FQDN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/FQDN/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/FQDN/chain.pem;
# security headers
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline'; frame-ancestors 'self';" always;
add_header Permissions-Policy "interest-cohort=()" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# . files
location ~ /\.(?!well-known) {
deny all;
}
# logging
access_log /var/log/nginx/FQDN.access.log;
error_log /var/log/nginx/FQDN.error.log warn;
# index.html fallback
location / {
#try_files $uri /index.html index.htm index.php;
}
# favicon.ico
location = /favicon.ico {
log_not_found off;
access_log off;
}
# robots.txt
location = /robots.txt {
log_not_found off;
access_log off;
}
# assets, media
location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
expires 7d;
access_log off;
}
# svg, fonts
location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
add_header Access-Control-Allow-Origin "*";
expires 7d;
access_log off;
}
# gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
}
# HTTP redirect
server {
listen 80;
listen [::]:80;
server_name FQDN www.FQDN;
# ACME-challenge
location ^~ /.well-known/acme-challenge/ {
root /var/www/_letsencrypt;
}
location / {
return 301 https://FQDN$request_uri;
}
}
So the SSL request shall be matched for FQDN and www.FQDN while http requests fro FQDN and www.FQDN shall be redirected to the SSL website.
This works fine for my wordpress websites but not for the HTML sites.
Even if I have a default server config nginx redirects the https://www.FQDN to the first config in the config folder.
Does anyone has a hint what's going on here?
I also See different behavior between Chrome and Firefox on one site and Safari on the other side.
Chrome and Firefox will be redirected to the first config in config folder while Safari shoes error that the requested https.www.FQDN website is not secure and readable.
Lets encrypt certificate is created for both domains FQDN and www.FQDN.

Global variable on NGINX

I'm using NGINX to serve static files, reverse proxy to Django and verify client certificates.
I don't want the certificate to be asked at the url root, so I created another server on Nginx.conf to ask for the certificate on port 8443. This server is intended just to ask for the certificate and redirect the client back to port 443, where the reverse proxy to Django occurs.
This is my Nginx.conf:
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
keepalive_timeout 65;
gzip on;
upstream app {
server django:8000;
}
# Redirect from HTTP to HTTPS
server {
listen *:80;
server_name localhost;
return 301 https://localhost$request_uri;
}
server {
listen *:443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/ssl/certificate.pem;
ssl_certificate_key /etc/nginx/ssl/certificate.key;
ssl_password_file /etc/nginx/ssl/certificate.pass;
ssl_verify_client off;
ssl_client_certificate /etc/nginx/ssl/chain.cer;
ssl_verify_depth 3;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
ssl_prefer_server_ciphers on;
server_tokens off;
underscores_in_headers on;
location /static/ {
autoindex off;
alias /static_files/;
}
location / {
try_files $uri $uri/ #app_web;
}
location #app_web {
proxy_pass http://app;
proxy_pass_request_headers on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header CERTINFO $http_certinfo;
proxy_redirect off;
}
}
server {
listen *:8443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/ssl/certificate.pem;
ssl_certificate_key /etc/nginx/ssl/certificate.key;
ssl_password_file /etc/nginx/ssl/certificate.pass;
ssl_verify_client on;
ssl_client_certificate /etc/nginx/ssl/certificate.cer
ssl_verify_depth 3;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
ssl_prefer_server_ciphers on;
add_header CERTINFO $ssl_client_s_dn;
return 301 https://$host$request_uri;
}
}
When the client authenticates on port 8443 and I return him to port 443, I need to forward his certificate information, the $ssl_client_s_dn to be more specific. To do so, I'm trying to use the method add_header on the server of the port 8443 (CERTINFO) and the method proxy_set_header capturing the value with $http_certinfo on the server of the port 443. But this solution is not working. The header is not forwarded from port 8443 to port 443 server.
My question is: is there a way to do that? Can I set some kind of "global" variable on the http block, change its value on port 8443 and than use the updated value on port 443 to forward it to Django?
Thank you so much!

SignalR SSL trust issue with reverse proxy(Nginx) for Android

I am facing issue with SignalR using reverse proxy(Nginx) which has Certificates(Server, client and CA) and these certificates are self signed certificates, generated using OPENSSL.
Nginx Configuration is as below.
http
{
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request"
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
error_log "C:/Error/error1.log" debug;
listen 8080;
server_name localhost;
location /MyService
{
root html;
index index.html index.htm;
proxy_pass http://XX.XX.XX.XX/MyService;
}
location /
{
root html;
index index.html index.htm;
proxy_pass http://XX.XX.XX.XX/MyService;
}
location /MyService/signalr/
{
root html;
index index.html index.htm;
proxy_pass http://XX.XX.XX.XX/MyService/signalr/;
}
}
server {
error_log "C:/Error/error1.log" debug;
listen 443 ssl;
server_name localhost;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate "C:\Certificates\server.crt";
ssl_certificate_key "C:\Certificates\server.key";
ssl_client_certificate "C:\Certificates\ca.crt";
ssl_verify_client on;
location /
{
root html;
index index.html index.htm;
proxy_pass http://XX.XX.XX.XX/MyService;
}
location /MyService
{
root html;
index index.html index.htm;
proxy_pass http://XX.XX.XX.XX/MyService;
}
location /MyService/signalr
{
root html;
index index.html index.htm;
proxy_pass http://XX.XX.XX.XX/MyService/signalr;
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;
}
}
}
I have an Android APP which enforce the user to select the client certificate(P12 certificate, which has CA and Client certificates packaged) for authentication through nginx and route it to server XX.XX.XX.XX. I have a logic which will successfully establishes the connection to the XX.XX.XX.XX server through Nginx. Authentication to server XX.XX.XX.XX through Nginx is successful.
I am facing issues with signalR in this scenario, wherein I am making a hubconnection to the server XX.XX.XX.XX like $"https://{hostname}:{port}/MyService/signalr/". When I try to start the hubconnection
_hubConnection.Start().Wait(); Getting error as One or more errors occurred. (The SSL connection could not be established, see inner exception.) because of which my hub is not receiving any notfication from the server.
I have Referred the following links and tried the suggestions as suggested. Unfortunately I am not getting any breakthrough. Request your help on this.
https://forums.asp.net/t/2029050.aspx?SignalR+Unable+to+Authentication+with+Certificate
https://learn.microsoft.com/en-us/aspnet/signalr/overview/security/hub-authorization
SignalR - Could not establish trust relationship for the SSL/TLS secure channel
https://forums.asp.net/t/2095053.aspx?SignalR+and+reverse+proxy

Nginx is not able to handle a large number of requests

I have an scenario on where a nginx is in front of an Artifactory server.
Recently, while trying to pull a big number of docker images in a for loop, all at the same time (first test was with 200 images, second test with 120 images), access to Artifactory gets blocked, as nginx is busy processing all the requests and users will not be able to reach it.
My nginx server is running with 4 cpu cores and 8192 of ram.
I have tried to improve the handling of files in the server, by adding the bellow:
sendfile on;
sendfile_max_chunk 512k;
tcp_nopush on;
This made it a bit better (but of course, pull's of images with 1gb+ take much more time, due to the chunk size) - still, access to the UI would cause a lot of timeouts.
Is there something else that i can do to improve the nginx performance, whenever a bigger load is pushed thru it?
I think that my last option is to increase the size of the machine (more cpu's) aswell as the number of processes on nginx (8 to 16).
The full nginx.conf file follows bellow:
user www-data;
worker_processes 8;
pid /var/run/nginx.pid;
events {
worker_connections 19000;
}
http {
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
include /etc/nginx/mime.types;
default_type application/octet-stream;
gzip on;
gzip_disable "msie6";
sendfile on;
sendfile_max_chunk 512k;
tcp_nopush on;
set_real_ip_from 138.190.190.168;
real_ip_header X-Forwarded-For;
log_format custome '$remote_addr - $realip_remote_addr - $remote_user [$time_local] $request_time'
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
server {
listen 80 default;
listen [::]:80 default;
server_name _;
return 301 https://$server_name$request_uri;
}
###########################################################
## this configuration was generated by JFrog Artifactory ##
###########################################################
## add ssl entries when https has been set in config
ssl_certificate /etc/ssl/certs/{{ hostname }}.cer;
ssl_certificate_key /etc/ssl/private/{{ hostname }}.key;
ssl_session_cache shared:SSL:1m;
ssl_prefer_server_ciphers on;
## server configuration
server {
listen 443 ssl;
server_name ~(?<repo>.+)\.{{ hostname }} {{ hostname }} _;
if ($http_x_forwarded_proto = '') {
set $http_x_forwarded_proto $scheme;
}
## Application specific logs
access_log /var/log/nginx/{{ hostname }}-access.log custome;
error_log /var/log/nginx/{{ hostname }}-error.log warn;
rewrite ^/$ /webapp/ redirect;
rewrite ^//?(/webapp)?$ /webapp/ redirect;
rewrite ^/(v1|v2)/(.*) /api/docker/$repo/$1/$2;
chunked_transfer_encoding on;
client_max_body_size 0;
location / {
proxy_read_timeout 900;
proxy_max_temp_file_size 10240m;
proxy_pass_header Server;
proxy_cookie_path ~*^/.* /;
proxy_pass http://{{ appserver }}:8081/artifactory/;
proxy_set_header X-Artifactory-Override-Base-Url $http_x_forwarded_proto://$host:$server_port;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
Thanks for the tips.
Cheers,
Ricardo

NGINX: too many redirects

I'm hosting a meteor app behind an nginx proxy. We were using https (and thus 301 redirecting all http connections to 443). However, we've now gone back to http (and thus 301 redirecting all https connections to 80).
When I try to visit my site, I get an error saying, "The page isn’t redirecting properly". However, if I visit in incognito or after clearing my browser cache and cookies, everything works again.
Can I change anything in my nginx conf file (below) to fix this? I really don't want all of my visitors to have to clear their browsing data. Thanks!
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;
server_name [REDACTED];
# redirect to meteor
location / {
proxy_pass http://127.0.0.1:3000;
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
}
}
# HTTPS server
server {
listen 443 ssl spdy; # we enable SPDY here
server_name [REDACTED];
root html; # irrelevant
index index.html; # irrelevant
# redirect to http
return 301 http://$host$request_uri;
ssl_certificate /etc/[REDACTED].pem;
ssl_certificate_key /etc/[REDACTED].pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers '[REDACTED]'
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;
# 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;
}
location ~ /.well-known {
allow all;
}
}

Resources