digital ocean redirect non-www to www - nginx

I'm trying to redirect my domain http://example.com to http://www.example.com on Digital Ocean.
I have A records for both www and #, so the site is accessible at each domain, but the redirect is not working. Here is what I have in my default config file (/etc/nginx/sites-enabled/default):
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /var/www/app/deploy/frontend/;
index index.html index.htm;
# Make site accessible from http://localhost/
server_name example.com;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
}
#Redirect example.com to www.example.com
server {
listen 80;
server_name example.com;
return 301 http://www.example.com.io$request_uri;
}
Any ideas?

The correct way is to define them in separate server blocks. Can be within the same file though like this:
server {
server_name domain.com;
rewrite ^(.*) http://www.domain.com$1 permanent;
}
server {
server_name www.domain.com;
#The rest of your configuration goes here#
}

Create a CNAME record with 'yoursite.com' is an alias of '#'

Related

How to do a redirect from www to non-www for any domain in Nginx?

I have the following server block in Nginx config:
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
server_name _;
if ($scheme = http) {
return 302 https://$host$request_uri;
}
location / {
root /frontend/master;
index index.html;
try_files $uri $uri/ /index.html?$query_string;
}
}
So I already have redirect from http to https. But how to do redirect from www.example.com to example.com for this rule?
UPD: the most important thing here is that domains in our service are dynamic, our users register them by themselves and then chaining them via DNS settings. So I need to make a redirect to non-www without putting some domains in the server_name variable.
Try this
server_name ~^(www\.)?(?<hostname>.+)\.(?<zone>.+)$;
return 301 https://$hostname.$zone$request_uri;
You can change regexp with your hostname for example

How to prevent redirects on nginx when domain in host header does not match domain in request url?

I have nginx running on my home server at keepsecret.ddns.net. When I request e.g. keepsecret.ddns.net/foo/ it returns to me keepsecret.ddns.net/foo/index.html. So far, so good.
Now I am trying to treat my home server as an upstream server. In front of that upstream server is a remote proxy server at www.mydomain.com. When I request e.g. www.mydomain.com/foo/index.html, it is returned to me no problem. However, when I request www.mydomain.com/foo/, nginx first issues a 301 redirect so that I then get sent to keepsecret.ddns.net/foo/, revealing my home IP Address :(
I have no idea why nginx behaves this way. My only guess is that it has something to do with the fact that the domain in the request host header does not match the domain in the request url.
Questions in summary:
Why does nginx do this?
How can I prevent nginx performing this redirect so that I always remain on www.mydomain.com?
Here is the salient part of my config for reference:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}
server {
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name keepsecret.ddns.net www.mydomain.com;
location / {
try_files $uri $uri/ =404;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/keepsecret.ddns.net/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/keepsecret.ddns.net/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 = keepsecret.ddns.net) {
return 301 https://$host$request_uri;
}
if ($host = www.mydomain.com) {
return 301 https://$host$request_uri;
}
listen 80 ;
listen [::]:80 ;
server_name keepsecret.ddns.net www.mydomain.com;
return 404; # managed by Certbot
}
NGINX will be doing an internal redirect to the index.html file in all cases, but it seems to get externalised when the server_name does not match the primary server_name. I suspect that changing the server_name order so that your public (proxied) name is first may get rid of that behaviour.
The alternative would be to focus on the reverse proxy, and take a look at proxy_redirect to make the reverse-proxy rewrite location headers for you.
See: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect

Nginx server name difference

If the server ip is 10.0.0.0, but I'm mapping it to make it to have www.example.com, is the below config the correct way to do it?
server {
listen 80;
server_name 10.0.0.0 example.com;
access_log /var/log/nginx/example.log;
No, if you want to restrict a server to a single interface address, it needs to go with the listen directive:
server {
listen 10.0.0.0:80;
server_name example.com;
access_log /var/log/nginx/example.log;
...
}
above answer, or you can just setup a basic server block
server {
listen 80;
listen [::]:80;
root /var/www/folderName/htdocs; // where you have your project folder and public directory
index index.html index.htm; // add index.php here if using php files
server_name test.com www.test.com; // desired url goes here
location / {
try_files $uri $uri/ =404;
}
}
the tutorials from digital ocean are pretty nice - https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-on-ubuntu-14-04-lts

Too many redirects - changing naked url -> www.example.com

I've changed my conf file so that when a user types in the domain without www it redirects to the domain with www:
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
I also wish for my https for anything under /user
I get the error of too may redirects, where am I going wrong?
So I have:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /var/www/example.com/site;
index index.html index.htm;
# Make site accessible from http://localhost/
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
location /user {
rewrite ^ https://$http_host$request_uri? permanent;
}
}
For port 443:
server {
listen 443;
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
root /var/www/example.com/site;
index index.html index.htm;
ssl on;
ssl_certificate //path here
ssl_certificate_key //path here
location / {
rewrite ^ http://$http_host$request_uri? permanent;
}
location /user {
}
}
With
listen 80 default_server;
you are telling nginx that this server block is the default server for all http requests regardless of the server name.
The directive
return 301 $scheme://www.example.com$request_uri;
sets nginx to redirect all incoming traffic for this server block to www.example.com. That redirected traffic hits the same server block again (default server) and the process repeats itself, hence a redirect loop.
To fix this change your config file and add a second server block:
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name www.example.com;
#rest of your config
[...]
}
server {
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
}
Port 80 can be left out, as it is the default, in case you are wondering.
The same principle applies to traffic for 443 (in the redirect block you however must give the port and ssl specific configuration).

Nginx rewrite HTTP to HTTPS says redirect loop?

I am trying to redirect all HTTP traffic to HTTPS,so when i got to www.domain.com it goes to https://www.domain.com. This is my current .conf file -
server {
listen 80;
#listen [::]:80;
server_name www.domain.net;
rewrite ^(.*) https://www.domain.net$1 permanent;
index index.html index.htm index.php default.html default.htm default.php;
root /home/wwwroot/www.domain.net;
include other.conf;
#error_page 404 /404.html;
location ~ [^/]\.php(/|$)
{
# comment try_files $uri =404; to enable pathinfo
try_files $uri =404;
fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_index index.php;
include fastcgi.conf;
#include pathinfo.conf;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 12h;
}
access_log /home/wwwlogs/www.domain.net.log access; }
It always returns a 'redirect loop' error for my domain, I have tried many different configurations but I always have this same problem. (I appreciate my SSL is not configured as it should be but it still works)
If someone could help me to get it working I would be grateful.
You need put the ssl configuration inside the server:
listen 443 ssl default;
ssl on ssl_certificate << put your .crt >>;
ssl_certificate_key << put your .key >>;
# force https-redirects
if ($scheme = http) {
return 301 https://$server_name$request_uri; }
Do you put on your file the server to listen the port 443?
Because if you don't configurate your nginx to listen the port 443, your server will redirect from 80 to https. And from https to http (80) - this cause your loop.
To build your redirect you need only this:
server {
listen 80 default;
server_name <<your domain>>;
return 301 https://<<your domain>>$request_uri;}
And use the same configuration that you did on your 443 ssl but make those changes:
listen 443 ssl;
ssl_certificate <<your .crt>>;
ssl_certificate_key <<your .key>>;
ssl_client_certificate <<your client certificate .crt>>;

Resources