NGINX Redirect HTTPS to HTTP getting Cert Error - ssl

I have the following NGINX configuration to redirect https to http and then run 301 redirects. The problem is, if people are visiting https://domain.com instead of being redirected they are stuck on a certificate error page.
server {
listen 443;
server_name domain.com www.domain.com;
rewrite ^(.*) http://$host$1 permanent;
}
server {
listen 80;
server_name domain.com www.domain.com;
location ~ /assets/img/images/(.*)$ {
return 301 https://domain.xyz/images/legacy/$1;
}
location ~ /frame/(.*)$ {
return 301 https://domain.xyz/embeded/$1;
}
}

It is a bit of a chicken-and-egg problem such that there is no real way to say that you don't support TLS/SSL without first supporting TLS/SSL.
So, in order to service the redirect, you still must serve a valid certificate.
Once you obtain a certificate (for example a free one from Let's Encrypt), you just add this to your first server block:
listen 443 ssl;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;

Related

SSL issue in domain with www

I have issues in SSL configuration and I have deployed my web applications to AWS EC2.
For the server, I am using Ngnix.
1. http://example.com
2. http://www.example.com
3. https://example.com
4. https://www.example.com
5. example.com
6. www.example.com
In the above URLs, only No.4 (https://www.example.com) is not working.
I've got an error - "Your connection is not private".
I use letsencrypt for an SSL certificate.
I have 4 sub-domains - admin.example.com, api.example.com, dashboard.example.com, and admin-api.example.com.
These work perfectly.
I've created an SSL for each sub-domains but didn't create an SSL certificate for www.example.com
Below is my Ngnix configuration file.
server {
listen 80;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
server {
server_name example.com;
access_log /var/log/nginx/listing-page.access.log;
error_log /var/log/nginx/listing-page.error.log;
...
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
I've tried to solve this issue all day but couldn't still fix it.

Nginx https certbot return 301 -- replace certbot-generated 'if' statements with best practices

I am setting up a nginx web server, and have a question about my server block config. FWIW, it's Ubuntu 16.04, Nginx 1.13.10.
I would like to rewrite Certbot's auto-generated code (which uses IF statements for its redirects), using more efficient syntax, per Nginx Using If and If Is Evil.
Goal: to redirect each of the 3 non-https://# options into one secure #. In other words, http://www.example.com, http://example.com, https://www.example.com should ALL redirect to https://example.com -- but without the IF's.
I have searched keywords like "nginx certbot return 301 redirect" on S.O. and AskUbuntu, but none seem to address the IF issue. Any suggestions, links, and further reading are welcome.
Questions:
The server currently redirects http to https, but does not drop www. Is this because only some of the servers are listening on ipv6? If not, suggestions please.
Will certbot/letsencrypt punish me if I modify its auto-generated code (i.e. will I lose my secure connection)? Or does it only care about good syntax?
Follow-up (I predict the first two will answer the next, but....)
Do my proposed changes (commented in the code) look accurate syntax-wise?
Any further suggestions for improvement?
Code: simplified for clarity of the topic -- but server does https (with an A+ from ssllabs), and passes nginx -t.
aTdHvAaNnKcSe (THANKS in advance)!
##
# 0 - main server https #
##
server {
server_name example.com;
listen 443 ssl;
listen [::]:443 ssl ipv6only=on; # managed by Certbot
#
# insert certbot-generated cert, cert-key, options, and dhparam
# and all the location-related stuff
#
# this is working fine. :)
# But why ipv6only=on ? Pros/cons?
#
}
##
# 1 - redirect https www to #
##
server {
server_name www.example.com;
listen 443 ssl;
return 301 $scheme://example.com$request_uri;
#
# insert certbot-generated cert, cert-key, options, and dhparam
#
# This appears to be secure, but does not actually redirect www to #
# Is it because it's only listening on ipv4?
# Should I add listen [::]:443 ssl; # also ipv6only=on?
}
##
# 2 - redirect http # to https #
##
server {
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name example.com;
listen 80;
listen [::]:80;
return 404; # managed by Certbot
#
# I want to replace entire IF statement with something like:
# return 301 https://example.com$request_uri;
#
# ?? The 404 is the ELSE part of the conditional, right? Safe to delete?
}
##
# 3 - redirect http www to https #
##
server {
if ($host = www.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name www.example.com;
listen 80;
return 404; # managed by Certbot
#
# I'd like to replace with something like:
# return 301 https://example.com$request_uri;
#
# ?? Should I add listen [::]:80;
#
}
Here is a basic setup for an https server, per nginx best practices. This redirects all http traffic to https, and redirects the www subdomain to the domain.
You will of course have to copy your location configs (php, .ht, etc.) into the main block, and your certbot configs into both https blocks. If you are setting this up as a new server, certbot should generate correctly into the right server{} blocks.
I hope this helps someone.
# Basic server config, redirecting all http:// and www to https://#
##
# 0 - main server https #
##
server {
server_name example.com;
listen 443 ssl http2;
listen [::]:443 ssl http2; # managed by Certbot
#
# this is your main config. You don't really need to touch the others
# because they are simple redirects.
#
# include the certbot-generated cert, cert-key, options, and dhparam
# include all the location configs
# include all the php, wordpress, etc.
#
}
##
# 1 - redirect https www to #
##
server {
listen [::]:443 ssl http2;
listen 443 ssl http2;
server_name www.example.com;
return 301 $scheme://example.com$request_uri;
#
# include certbot-generated cert, cert-key, options, and dhparam
#
}
##
# 2 - redirect http # to https #
##
server {
listen 80;
listen [::]:80;
server_name example.com;
return 301 https://example.com$request_uri;
}
##
# 3 - redirect http www to https #
##
server {
listen [::]:80;
listen 80;
server_name www.example.com;
return 301 https://example.com$request_uri;
}

elastic beanstalk/nginx multiple ssl domain redirect to another one

I'm trying to redirect domain.net and domain.fr to www.domain.me with this (https) :
upstream nodejsserver {
server 127.0.0.1:8081;
keepalive 256;
}
server {
listen 443 ssl;
server_name .domain.fr .domain.net;
rewrite ^/(.*) https://domain.me/$1 permanent;
}
It still doesn't work. Nginx is on elastic beanstalk and my ssl certificate is managed by Certificate Manager.

Nginx redirect www http to non-www https causing host name mismatch certificate error in Safari

I am trying to redirect http://www.example.com to https://example.com. Here is my nginx configuration:
server {
listen 80;
server_name www.example.com;
return 301 http://example.com$request_uri;
}
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
root /var/www/example.com;
index index.php;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
[...]
}
I have also tried a similar configuration in which the second server block is listening on port 443 instead of port 80. Both the mentioned configurations yield the expected result in Firefox and Chrome, but Safari throws a scary "This certificate is not valid (host name mismatch)" warning box for the user, which I do not want.
I am not using a wildcard SSL certificate but rather I am trying to get by with just a single domain certificate (valid for example.com). Is what I'm trying to do possible with a single domain SSL certificate?

Force www. and https in nginx.conf (SSL)

After purchasing a SSL certificate I have been trying to force all pages to secured https and to www.
https://www.exampl.com is working and secure but only if type it in exactly. www.example.com or example.com are still pointing to http.
We use nginx as a proxy and need to input the rewrite there. I have SSH / root access via Putty. I have accessed nginx.conf by inputting into putty.
Now what? Do I input the nginx commands on this page? Starting where the cursor is? Any command lines first?
HTTPS:
.htacess – Original code I was given before I found out I had to input into nginx
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]
Nginx code converter – This is how it shows on the converter. Is everything on the correct lines?
# nginx configuration location / {
if ($http_host ~* "^example.com"){
rewrite ^(.*)$ http://example.com/$1 redirect; } }
and then
WWW
.htacess – Original code I was given before I found out I had to input into nginx
#Force www:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301,NC]
Nginx code converter – This is how it shows on the converter. Is everything on the correct line?
# nginx configuration location / {
if ($http_host ~* "^example.com"){
rewrite ^(.*)$ http://www.example.com/$1 redirect; }
}
Do I then save? Restart?
Any help would be greatly appreciated. I have been battling this for weeks. My Hosting company helped as far as they could, now I am learning on the fly…. Or should I just stop and hire a developer? $$$
Thanks
The best way to implement WWW and HTTPS redirection is to create a new server section in Nginx config:
server {
listen 80; #listen for all the HTTP requests
server_name example.com www.example.com;
return 301 https://www.example.com$request_uri;
}
You will also have to perform https://example.com to https://www.example.com redirection. This may be done with code similar to the following:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate ssl.crt; #you have to put here...
ssl_certificate_key ssl.key; # ...paths to your certificate files
return 301 https://www.example.com$request_uri;
}
And of course, you must reload Nginx config after each change. Here are some useful commands:
check for errors in the configuration:
sudo service nginx configtest
reload configuration (this would be enough to make changes "work"):
sudo service nginx reload
restart the whole webserver:
sudo service nginx restart
Important note:
All your server sections must be inside http section (or in a file included in http section):
http {
# some directives ...
server {
# ...
}
server {
# ...
}
# ...
}
The following solution seems to be clear and simple, everything defined in one server block. So with this setup I force everything to https://www.domain.tld, so both handlers are here non-HTTPS and non-WWW on HTTPS.
There are two IF's but if you don't want to duplicate entire SSL block two times to handle it... this is the way to do it.
server {
listen 80;
listen 443 ssl;
server_name domain.tld www.domain.tld;
# global HTTP handler
if ($scheme = http) {
return 301 https://www.domain.tld$request_uri;
}
# global non-WWW HTTPS handler
if ($http_host = domain.tld){
return 303 https://www.domain.tld$request_uri;
}
}
And even better solution to avoid IF's:
# Redirect all traffic from HTTP to HTTPS
server {
listen 80;
server_name example.com www.example.com;
# Destination redirect base URI
set $RURI https://www.example.com;
location / {return 301 $RURI$request_uri;}
}
# Redirect non-WWW HTTPS traffic to WWW HTTPS
server {
listen 443 ssl;
# NOTE: SSL configuration is defined elsewhere
server_name example.com;
return 301 $scheme://www.$host$request_uri;
}
# MAIN SERVER BLOCK
server {
listen 443 ssl;
# NOTE: SSL configuration is defined elsewhere
server_name www.example.com;
}
If you have a sites-enabled directory, do not use the "http" top directive. Just create another file (with any name) in the site-enabled directory that has:
server {
listen 80; #listen for all the HTTP requests
server_name example.com www.example.com;
return 301 https://www.example.com$request_uri;
}
and comment out the line
listen 80;
where the server_name is the same in the other file that serves www.example.com
I searched a lot , finally this is my right answer.
also remember to add a www A record in your domain registar's dns control panel.
# Force all users to https://www.example.com
server {
listen 80;
server_name example.com www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/www.example.com.pem;
ssl_certificate_key /etc/nginx/ssl/www.example.com.key;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
root /var/www/html
error_page 403 /error/404.html;
error_page 404 /error/404.html;
error_page 500 502 503 504 /error/50x.html;
ssl_certificate /etc/nginx/ssl/www.example.com.pem;
ssl_certificate_key /etc/nginx/ssl/www.example.com.key;
}