We have an nginx 1.20.1 webserver on Ubuntu 16.04 hosting many sites. One site is oldsite.example.com and while we're building a newsite.example.com we wish for users to start using the new URL (newsite.example.com). We already made a DNS change but wanted clarity on the nginx part. New URL has to work with both HTTP/HTTPS and we have separate SSL cert it as well.
Thank you for reading.
oldsite nginx conf:
server {
server_name oldsite.example.com
;
listen 80;
if ($host = oldsite.example.com) {
return 301 https://$host$request_uri;
}
return 404;
}
server {
listen 443 ssl;
add_header Content-Security-Policy upgrade-insecure-requests;
For your question about redirection, a simple 302 will do the trick. It is similar to the 301 redirection you are already using:
return 301 https://$host$request_uri;
And you can return sth. like this, but in your ssl server section:
server {
listen 443 ssl;
server_name newsite.example.com;
return 302 https://oldsite.example.com$request_uri;
...
But I would recommend a proxy_pass, or just copy & paste your old configs into the new one. It will save you a redirection.
And for all of your misunderstandings about the protocol,
There is a server name indicator, or SNI, in plain text, in a TLS request (at least for now). If you know about the Host: header, that is it. You can have multiple HTTPS sites on the same host distinguished by server_name, which is exactly what you do for HTTP sites.
Even for HTTP sites, the Host: header is required (for HTTP/1.1 or higher, but no higher), and the server will look at it. You cannot simply CNAME (or sth. similar) a domain into another without modifying server configuration.
wouldn't the user's browser, when they type newsite.example.com and end up at oldsite.example.com
As I said, there is a server name indicator and the server will look at it, as it will look at Host: header. You can distinguish different sites on the same host by different server names.
Related
I want to redirect all domain from www to non-www using Nginx config file nginx.conf.
I have tried using the below configuration but it only work for URL start with HTTP but does not work for HTTPS
I have added below server block
server {
server_name "~^(?!www\.).*" ;
return 301 $scheme://$1$request_uri ;
}
Since you didn't specify listening port in the server block you've shown in your question, it will listen on a plain HTTP TCP port 80 by default. You need to specify
listen 443 ssl;
to listen on an HTTPS TCP port 443. However to make the server block workable via the HTTPS protocol, you'd need to specify an SSL certificate/key (at least), and to made a user browser following a redirect returned by nginx, that certificate should be a valid one, issued for the domain name you want to be redirected, or the browser will complain about invalid certificate and won't follow the redirect location.
So if you want to use some kind of universal server block for redirecting every HTTPS request from www to non-www domain, it will be impossible unless you have a certificate that include every domain name you want do redirect (which seems to be impossible to have for a custom non-predefined list of domain names).
Update
Although this isn't a thing I'd do for myself in a production environment, actually there is a way to achieve workable solution using the lua-resty-auto-ssl (see the documentation examples), OpenResty/lua-nginx-module and the following sever block (remember that server names specified by domain prefix have the lowest priority comparing to exact matched server names, e.g. www.example.com, or server names specified by domain suffix, e.g. *.example.com):
init_by_lua_block {
auto_ssl = (require "resty.auto-ssl").new()
auto_ssl:set("allow_domain", function(domain)
return true
end)
auto_ssl:init()
}
map $host $basename {
~^www\.(.+) $1;
default $host;
}
server {
listen 443 ssl;
server_name www.*;
ssl_certificate_by_lua_block {
auto_ssl:ssl_certificate()
}
ssl_certificate /path/to/dummy.crt;
ssl_certificate_key /path/to/dummy.key;
return 301 https://$basename$request_uri;
}
In order for this to work you'd also need the corresponding plain HTTP block to allow ACME challenge(s) to be successfully completed:
server {
listen 80;
server_name www.*;
location / {
return 301 https://$basename$request_uri;
}
location /.well-known/acme-challenge/ {
content_by_lua_block {
auto_ssl:challenge_server()
}
}
}
I'm trying to let all traffic for my nginx be redirected to HTTPS, independent of server name. So, any other vhost should be redirected to its HTTPS counterpart.
example.com -> https://example.com
test.com -> https://test.com
...
Yet, instead of using the incoming $server_name or $host (tried both), it keeps redirecting to a plain https://_. Is my config incorrect?
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://$server_name$request_uri;
}
Okay, rather silly. If you have previously setup any non-working configuration (e.g. one which will result in the faulty redirect), the browser will remember this redirect without asking the server again (as according to HTTP 301 - permanently moved). So, either clear the browser's data or try with a different one.
I am configuring an nginx server at the moment and I have two domain types:
www.example.com
example.com
On the server I added a new server block with the following code to redirect every incoming requests to the domain without www.
server {
server_name www.example.com;
return 301 $scheme://example.com$request_uri;
}
The problem is that I only got HTTP 200 instead of 301.
The changed file is: /etc/nginx/sites-enabled/default
What am I missing? I did exactly how the documentation says in Digital Ocean.
On a website which currently is serving on HTTPS, I want to redirect some pages to HTTP and not use SSL on them. In nginx I configured it like this:
server{
listen 80;
server_name example.com;
location / {
root /var/some/where;
}
location /secure {
return 301 https://example.com$request_uri;
}
}
server{
listen 443 ssl;
server_name example.com;
include ssl_params;
location /secure {
root /var/some/where/secure;
}
location / {
return 301 http://example.com$request_uri;
}
}
Using curl I can see everything is fine as follow:
$ curl -sIL https://example.com/ | grep HTTP
HTTP/1.1 301 Moved Permanently
HTTP/1.1 200 OK
$ curl -sIL http://example.com/ | grep HTTP
HTTP/1.1 200 OK
But when I try to open HTTPS url in Firefox, I'll get this error:
The page isn't redirecting properly.
Firefox has detected that the server is redirecting the request for this address in a way that will never complete.
This problem can sometimes be caused by disabling or refusing to accept cookies
Using a private window, when I try to open url in HTTP for the first time, is OK. But as soon as I refresh the page, It'll be redirected to HTTPS scheme and the error will appear again.
Do you have a certificate set up? None showing in your config.
The way it works is to open the secure connection (using the certificate) then return the content (including any redirect). It is not possible to redirect before creating the secure connection (as that would be a huge security risk to https if it was possible).
Considering Strict-Transport-Security: max-age=15768000 as result of curl -i -L on target domain, which means hsts header exists and by definition:
tells your browser to always connect to a particular domain over HTTPS. Attackers aren’t able to downgrade connections, and users can’t ignore TLS warnings.
We have an application where we use subdomains for each of our customer's installations. so we have customer1.ourapp.com, customer2.ourapp.com, customer3.ourapp.com and so on.
Because of security we want to redirect all http to https, since we have a wildcard SSL certificate.
Also, some customers are not that tech savvy and add www to their domain name, so then you get things like: http://www.customer1.ourapp.com or https://www.customer1.ourapp.com. In those cases the SSL certificate isn't valid because of the subsubdomain.
I'm trying to write the vhost config for nginx to make the correct redirect in these two cases. I got the http to https redirect to work with:
server {
listen 80;
server_name *.ourapp.com;
#Rewrite all nonssl requests to ssl.
return 301 https://$host$request_uri$is_args$args;
}
correct url's use:
server {
listen 443;
server_name *.ourapp.com;
#Rest of config
}
Made an attempt for the subsub domains, but it's not matching:
server {
server_name "~^(.*)\.(.*)\.ourapp\.com$";
return 301 https://$2.ourapp.com$request_uri;
}
Any idea how to get this working?
Wildcarded server takes precedence over regexp'ed one and matches 'www...' too.
You can use one definition for both cases:
server_name ~ ^(?:.*\.)?(.*)\.ourapp\.com$;
return 301 https://$1.ourapp.com$request_uri;