nginx force ssl http - ssl

I am struggling on how to force SSL on my website (nginx). I would like to force a redirect from both "http://www.example.com" and "http://example.com" to "https://example.com" (without any www).
The code I wrote currently can catch "http://www.example.com" but does not catch "http://example.com", it seems to infinite loop a redirection. I'm pretty sure it has something to do with the "server_name". I tried swapping it up a down inside the "server { ... }" brackets and stuff but it still does not behave the way I would like it.
Here is my nginx conf
server {
server_name www.example.com;
return 301 https://example.com$request_uri;
}
server {
server_name example.com;
root /var/www/example.com;
index index.html index.php index.htm;
location / {
include /etc/nginx/conf/fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
}
location ~ /\.ht {
deny all;
}
}
server {
#listen 443 spdy default deferred;
ssl on;
ssl_certificate_key /etc/myssl/www.example.com.key;
ssl_certificate /etc/myssl/www.example.com.chained.crt;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-[...]';
ssl_prefer_server_ciphers on;
ssl_dhparam /usr/share/myssl/dhparams/dh2048-group14.pem;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:5m;
add_header Strict-Transport-Security max-age=15768000;
}

You'll want to configure each of your server blocks to specifically listen to a certain port, such as the following:
server {
listen 80;
server_name www.example.com example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl spdy;
server_name www.example.com;
ssl_certificate_key /etc/myssl/www.example.com.key;
ssl_certificate /etc/myssl/www.example.com.chained.crt;
[other ssl_* directives, as required]
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl spdy;
server_name example.com;
ssl_certificate_key /etc/myssl/www.example.com.key;
ssl_certificate /etc/myssl/www.example.com.chained.crt;
[other ssl_* directives, as required]
[remaining example.com configuration here]
}
This says listen on HTTP (port 80) for requests to http://www.example.com and http://example.com and redirect them to https://example.com. The second block listens for https://www.example.com and redirects to https://example.com. Then, the final block listens for SSL/SPDY requests to https://example.com.
Add your remaining HTTPS-only configuration to the second block, which looks to be essentially merging the second and third blocks.
The following is now demonstrated in the example: You will need to add another server block if you want your server to respond or redirect users accessing https://www.example.com & thus you may require a second valid SSL certificate (one for www.example.com and one for example.com). Alternatively, a wildcard certificate or a certificate with alternate DNS names would work for both circumstances.
Also ensure that no other conflicting configuration files are present in your configuration directory (eg /etc/nginx/conf.d or /etc/nginx/sites-enabled; depending on your platform).
Edited: expanded based on other information given.

Related

Nginx redirect to endless var/www?

I am having some problems setting up my nginx server with ssl certificate and I have somehow screwed up something. When I go to my website it redirects to an endless loop of /var/wwww. it looks like this:
And this is my cd /etc/nginx/sites-available/default file
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name molle.ws www.molle.ws;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/molle.ws/fullchain.pem; # managed by Cert$
ssl_certificate_key /etc/letsencrypt/live/molle.ws/privkey.pem; # managed by Ce$
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
if ($scheme != "https") {
return 301 https://$host$request_uri;
} # managed by Certbot
Please help :/

www in domain not working - nginx

I'm having problems getting domains to work using nginx when you include www. in the url.
mydomain.com --> Working but www.mydomain.com --> Not
Working
Config file:
server {
listen 80;
listen [::]:80;
#server_name git.mydomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 default_server ssl;
listen [::]:443 default_server ssl;
server_name git.www.mydomain.com;
# certs sent to the client in SERVER HELLO are concatenated in ssl_certific$
ssl_certificate /etc/nginx/ssl/mydomain.com.crt;
ssl_certificate_key /etc/nginx/ssl/mydomain.com.key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 4096 bits
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
# modern configuration. tweak to your needs.
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDH$
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
location / {
try_files $uri $uri/ =404;
}
}
Can you help me? Thank you!
You need to set up the server names you want Nginx to serve from.
server {
listen 80;
listen [::]:80;
server_name mydomain.com www.mydomain.com;
return 301 https://$host$request_uri;
}
So you list the names you want separated by spaces.
I assume that you want to redirect all your www and non-www traffic to https with the server name you have set up in the https configuration, and that your https server name is right.

How to redirect www to non-www and http to https using nginx and cloudflare?

I am using the following to redirect all users to https and to non-www:
server {
listen 80;
listen [::]:80;
server_name www.example.com example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com;
access_log /var/log/nginx/example.com.access.log rt_cache;
error_log /var/log/nginx/example.com.error.log;
root "/usr/share/nginx/app/public";
index index.php index.htm index.html;
charset utf-8;
ssl on;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
client_max_body_size 100m;
include hhvm.conf;
location ~ /\.ht {
deny all;
}
}
Note: I am also using CloudFlare.
When I visit example.com, I am redirected to https://example.com. Great.
But www.example.com redirects to https://www.example.com and the site does not load.
Visiting https://example.com works fine.
Is this a server configuration problem or a CloudFlare problem? How can it be fixed?
The problem was that I needed to add a DNS A record to allow www to point to my server's IP address. Then, nginx could redirect without a problem.

Nginx redirect http to https not working

I'm setting up an nginx server with an SSL.
The domain with the ssl is dev.cooknconnect.com
I want to redirect all requests from: http://domain.com to https://domain.com
I have the following server blocks setup currently:
server {
listen 1.2.3.4:80 default;
server_name domain.com;
server_tokens off;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443 ssl;
server_name domain.com www.domain.com;
keepalive_timeout 70;
server_tokens off;
ssl on;
ssl_certificate /etc/ssl/certs/certificate.crt;
ssl_certificate_key /etc/ssl/private/certificate.key;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://domain.com;
}
}
This currently does not work, but I don't understand why not.Can anyone find any mistake in my config.If not please suggest some way to track or debugging the same.
You could use this and it should work normally
server {
listen 80;
server_name domain.com;
server_tokens off;
return 301 https://$http_host$request_uri;
}
keep in mind that https://dev.yourdomain.com won't work, because your certificate was issued only for the root domain, the https for the dev subdomain will show the yellow certificate warning.
This works fine for me:
server{
listen 80;
server_name *.example.com;
rewrite ^ https://$host$request_uri? permanent;
}
This will permanently rewrite http to https for the domain itself and sub-domains to https mode.

Nginx redirect http://www and naked http/https to https://www

I would like to redirect all traffic from the following domains:
http://domain.com
http://www.domain.com
https://domain.com
to
https://www.domain.com
I have a SSL certificate for the above domain. It hosts a Rails app, served by Passenger.
To accomplish the naked domain redirect, I've set up an URL redirect in my DNSimple account:
URL domain.com 3600 https://www.domain.com
My server blocks are as follows (Inspired by Nginx no-www to www and www to no-www amongst others):
server {
listen 80;
listen 443;
server_name domain.com;
ssl on;
ssl_certificate /etc/ssl/domain-ssl.crt;
ssl_certificate_key /etc/ssl/domain.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
server_tokens off;
access_log /dev/null;
error_log /dev/null;
return 301 https://www.domain.com$request_uri;
}
server {
listen 443 ssl;
server_name www.domain.com;
root /home/deploy/app/current/public;
passenger_enabled on;
passenger_app_env production;
passenger_set_cgi_param HTTP_X_FORWARDED_PROTO https;
ssl on;
ssl_certificate /etc/ssl/domain-ssl.crt;
ssl_certificate_key /etc/ssl/domain.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
}
passenger_pre_start https://www.domain.com;
What works:
naked domain gets redirected to secure https://www
http://www domain gets redirected to secure https://www
https:// www works
What does't:
Naked https:// doesn't work, browsers throws a server not found
Basically I want to redirect all traffic to the secure https://www.domain.com. What am I missing here?
If you don't have a certificate for domain.com redirecting from https://domain.com to https://www.domain.com will not work, because before the browser gets the redirect it has to successfully establish the SSL connection (https is http inside SSL) and this fails because the certificate does not match.
I had similar kind of scenario and this is how I solved the redirection from
https://domain.com -----> https://www.domain.com
server {
listen 443;
server_name domain.com;
if ($host = domain.com) {
rewrite ^(.*) https://www.domain.com:443$request_uri? permanent;
}
Hope this helps!
Using if condition in nginx
Directive if has problems when used in location context, in some cases it doesn't do what you expect but something completely different instead. In some cases it even segfaults. It's generally a good idea to avoid it if possible. The only 100% safe things which may be done inside if in location context are: return ...; rewrite ... last;
Following will help.
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.example.com;
====>>> Your site configuratioin Goes here <<======
}
Provide a specific server block for the naked domain along with a general default. The more-specific ones will be used first.
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
return 301 https://www.$host$request_uri;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.example.com;
# omitting the rest for https://www.example.com
}
I use Let's Encrypt for my certificates so something like the following for default_server prevents redirecting the ACME challenges (note the second wildcard server_name for handling all https://*.example.com which don't have their own server block).
# omit server_name example.com block, same as above
server {
listen 80 default_server;
listen [::]:80 default_server;
location ~ ^/\.well-known/acme-challenge {
# LetsEncrypt
add_header Content-Type text/plain;
expires 0;
alias /var/www/html/acme/$host;
break;
}
location ~ ^/(?!\.well-known/acme-challenge) {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name *.example.com;
# omitting the rest for https://*.example.com
}
Setup certificates for the naked example.com, www.example.com and any others:
sudo certbot certonly --manual -d example.com -d www.example.com -d abc.example.com