Make it so nginx always has site using https - nginx

NOTE: example.com is just that. Per the rules of stackoverflow, I'm not using an actual domain.
I've been trying to get it so my nginx server for a single site always uses https.
I have the certificate installed and if I view the site with:
https://www.example.com it works fine.
But by default it goes to http and shows the site as insecure.
Here is the config:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /var/www/nodeapp;
index index.html index.htm;
server_name www.example.com example.com;
location / {
proxy_pass https://[IP address here]: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;
}
}
I esentially want everything to point to https://www.example.com

Because your site has both of http and https. (80 port and 443 port).
To activate the only https you have to remove the config for http.
Please remove listen 80 and use listen 443 instead.
If you want to redirect all traffics to https,
you could add redirection config as following.
server{
if ($host = your_domain) {
return 301 https://$host$request_uri;
}
server_name your_domain;
listen 80;
return 404;
}
I've assumed that your config has ssl part in your main config.
For example,
listen 443 ssl;
ssl_certificate /etc/***/fullchain.pem;
ssl_certificate_key /etc/**/privkey.pem; # managed by Certbot
ssl_dhparam /etc/**/ssl-dhparams.pem; # managed by Certbot

Related

How do I configure an ssl certificate with Nginx on Ubuntu 18.04?

I am trying to install an SSL certificate on an Ubuntu server with Nginx (my project is on a Flask server). When I try to reach my domain with my current configuration, the site can't be reached and ERR_CONNECTION_TIMED_OUT appears. I'm also trying to redirect all http requests to https. This is my current .conf file:
server {
server_name backlogtracker.live www.backlogtracker.live;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
}
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/letsencrypt/live/backlogtracker.live/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/backlogtracker.live/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 = www.backlogtracker.live) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = backlogtracker.live) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server;
server_name backlogtracker.live www.backlogtracker.live;
return 301 https://$server_name$request_uri;
}
Even with https, I can't reach the domain. Is there something that I'm missing?
Redirect http->https
This is a simple pattern for redirecting everything to https:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
It does not fit to all use-cases, but for most it is the simplest way without strange directives.
Order
Order does in some cases make a difference in config-files. Nginx is working top-down, so to prevent strange behaviour I'd suggest to always write your config as a story. E.g. return immediately stops execution, so stuff behind that is not processed. I would suggest the order:
connection settings (listen, server_name)
general config (ssl, headers, log, etc)
logic (if, map, ..)
locations
Headers for reverse proxy
I would suggest to always add headers (can be put in server-block to work for all locations):
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 Referer $http_referer;
proxy_set_header X-Forwarded-Proto $scheme;
SSL Protocol
Disable old TLS protocols
ssl_protocols TLSv1.2 TLSv1.3;
Further inspection
If not working then:
What is included in /etc/letsencrypt/options-ssl-nginx.conf
What are the logs of Flask and Nginx telling?
Are both running on host machine (no containers)?

NGINX config causing ERR_TOO_MANY_REDIRECTS error

Below is my current nginx config.
server {
listen 80 default_server;
server_name _;
return 307 https://$host$request_uri;
}
server {
listen [::]:443 ssl;
listen 443 ssl;
server_name localhost;
# Protect against the BEAST attack by not using SSLv3 at all. If you need to support older browsers (IE6) you may need to add
# SSLv3 to the list of protocols below.
ssl_protocols TLSv1.2;
ssl_certificate /etc/nginx/ssl.crt;
ssl_certificate_key /etc/nginx/ssl.key;
location / {
proxy_pass http://localhost:80; # TODO: replace port if app listens on port other than 80
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
All has been working well, but I recently added the first 'server' block hoping to redirect my url to https:// whenever a http:// version of the URL is visited, but I am getting an 'ERR_TOO_MANY_REDIRECTS' message when visiting the URL in the browser.
My application's port is on 80 within an Azure Container.
Any help would be appreciated!

Nginx ignores return directive

The problem:
I have an application running with Nginx serving as a reverse proxy. I have a ssl certificate to a certain example.com, but I also want my application to respond to example.organization.com (even without a certificate for the domain).
My idea was to set a return directive to return the desired URL and 301 as the status code... The problem is, my directive is not being used by Nginx. The nginx does force a HTTPS connection, but with any URL used and returning 302, so with the example.organization.com the browser does not accept it because of the lack of a ssl certificate. Even when the listen 80 block is disabled the redirect still goes on. Nginx is running inside a Docker container and it's hitting another Docker container (I don't think it is influencing the behavior, but I'm not sure)
What I've tried:
I tried to use the rewrite ^ https://example.com$request_uri permanent instead of the return 301 https://example.com$request_uri.
I also tried this:
server {
listen 443 ssl;
server_name example.com;
if ($host != "example.com") {
return 301 https://example.com;
}
}
But it didn't work.
server configuration:
server {
listen 80;
server_name example.com example.organization.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/conf/cert.crt;
ssl_certificate_key /etc/nginx/conf/cert.key;
location / {
proxy_pass http://container:80/
}
proxy_set_header HOST $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}

Enable cloudflare on multiple subdomains when using VPS with nginx?

There is a VPS machine with nginx’om configured on which 10 sites are spinning structure
tester.example.com
api-one.tester.example.com
api-two.tester.example.com
api-3.tester.example.com
api-4.tester.example.com
api-5.tester.example.com
api-6.tester.example.com
central site spinning on a separate hosting
in nginx, I configured the default site tester.example.com to use ssl from the cloudflare service
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name tester.example.com www.tester.example.com;
return 302 https://$server_name$request_uri;
}
server {
# SSL configuration
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
ssl on;
ssl_certificate /etc/ssl/certs/cert.pem;
ssl_certificate_key /etc/ssl/private/private.pem;
ssl_client_certificate /etc/ssl/certs/cloudflare.crt;
ssl_verify_client on;
server_name tester.example.com www.tester.example.com;
root /var/server/site/;
index index.html index.htm index.nginx-debian.html;
location / {
# try_files $uri $uri/ =404;
proxy_pass http://localhost:8880;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
without https - using regular ip: Port, opening passes through all services
how can I make api-one.tester.example.com config, etc. so that they also open via ssl?
I tried to change the port in the subdomain config (8443 which supports cloudflare), but does not give the desired result
.....
listen 8443 ssl http2;
listen [::]:8443 ssl http2;
ssl on;
.....
You normally have to setup subdomains separately in Cloudflare DNS settings, unless you use *.wildcard, but I don't think they support that any more.
If you want Cloudflare to route all subdomains on https/ssl, there is an option on Cloudflare dashboard > Crypto > Always use HTTPS. In this case, your domains will redirect to https if they were accessed by plain http. This of course requires that your server is setup to support SSL for the domain (regardless of Cloudflare) OR that you are using "Flexible" under Crypto > SSL settings, which allows Cloudflare to serve your website to the client on https, although the data from your server to Cloudflare is served without SSL.

Nginx redirect only root domain but not subdomain to www

Currently I'm using setting below to redirect non-www domain to www domain and it's working fine:
server {
listen 80;
server_name example.com;
return 301 http://www.example.com$request_uri;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://www.example.com:8888;
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;
}
}
However, now I would like to allow wildcard subdomain but it seems like all the subdomains were being redirect to www.domain.com. So my question is how can I make it only redirect the root domain to www only and excluding all other subdomain? Thanks.
The first server block is also the implicit default server, which means that any domain name that does not match www.example.com will be handled by it.
If you would like that second server block to handle all domains except example.com, you can make it the default server explicitly, by adding the default_server option to the listen directive. See this document for details.
For example:
server {
listen 80;
server_name example.com;
return 301 http://www.example.com$request_uri;
}
server {
listen 80 default_server;
...
}

Resources