nginx rewrite for subsubdomains to subdomains - nginx

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;

Related

How to redirect all https domain from www to non www using nginx config file nginx.conf?

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()
}
}
}

Fourth-Level Subdomain Forwarding

I've recently been trying to set up a reverse proxy that would forward certain 4th-level subdomains to particular locations. So, for example, this is what I'm trying to accomplish (configuration in my nginx file):
server {
listen 80;
server_name *.server.domain.com;
rewrite ^ https://$server_name$request_uri;
}
The goal here being that if someone went to, for example, http://item1.server.domain.com, they would be re-routed to https://item1.server.domain.com. However, with this configuration, the URL gets rewritten to https://%2A.server.domain.com.
Is there a way to fix this so that the full domain (item1) gets added correctly to the rewritten URL? Ideally, I wanted it to eventually be able to rewrite any subdomain on server.domain.com directly to https.
Thanks!
The $server_name variable contains the text from the value of the server_name directive. The %2A is a URL encoded representation of the leading *.
Use $host or $http_host to obtain the hostname actually requested by the client. See this document for more.
For example:
server {
listen 80;
server_name *.server.domain.com;
return 301 https://$host$request_uri;
}
Note: Restart nginx and clear the browser cache between each test. Check the configuration using nginx -T.

Nginx 301 redirection options

I have some 100 or so URLs that need to be permanently redirected from static HTML to dynamic pages served by Wordpress. All examples for Nginx 301 redirection I found suggest that each redirect should be defined as its own server block.
However, I have found out that multiple redirects within one server block work as well such as in this simplified configuration:
server {
listen 80;
server_name www.example.com;
root /var/www/;
location = /subdir/red1.html { return 301 /subdir/?p=1; }
location = /subdir/red2.html { return 301 /subdir/?p=2; }
location = /subdir/red3.html { return 301 /subdir/?p=3; }
}
Curl -I confirms the 301 code. The redirects take place. I prefer this configuration to the one with one server block per redirect because human readability is better. But does this configuration lack something that I'd otherwise have if each redirect was in its own server block?
Well, execrpts you found are probably dealing with http to https redirections where it makes sense not to have anything more in the server block because the vhost is only there to redirect to an other domain. That's completely wrong to pick random examples and take them as a rules of thumb instead of refering to the official documentation.
100 redirects is not a huge count, you could even use permanent rewrites in one unique server block and group them with regexs.
server {
server_name www.example.com;
root /var/www/;
location /subdir/ {
rewrite ^/subdir/red([1-3])\.html /subdir/?p=$1 permanent;
}
}

Nginx subdomains with www

I have Nginx configured in a Amazon EC2 server.
Right now both www.myserver.com, .myserver.com works perfect.
What I need, is configure www..myserver.com. I need to redirect the user to .myserver.com. I mean, I need to rewrite the url or something.
How can I do that?
server {
listen 80;
server_name www.myserver.com;
return 301 http://myserver.com$request_uri;
}
You don't need "rewrites" in nginx. Leave them to apache, and read the docs:
http://nginx.org/en/docs/http/server_names.html
http://nginx.org/en/docs/http/request_processing.html
http://nginx.org/en/docs/http/converting_rewrite_rules.html
Upd:
That is not clear from your question (who knows, what do you mean by double dots). But if you have ever tried to read the docs, you would easily modify the example for your needs:
server {
listen 80;
server_name ~^www\.([^.]+\.myserver\.com)$;
return 301 http://$1$request_uri;
}

NGINX - redirect from https to http without ssl certificate

I'm setting up a new nginx box however I can't figure out why my nginx isn't starting when I use this:
server {
listen 443;
server_name mysite.com; // https://mysite.com
rewrite ^(.*) https://mynewsite.com.com$1 permanent; // new site
}
Anyone help me out?
This is impossible to do. Redirecting from https to http itself is based on a successful https connection, which requires a certificate.
if you have an SSL either purchased one or self signed SSL, you can then redirect the https to http. yes, you can redirect https to http without SSL if someone try adding the s letter in your url so that your url can't serve anything over HTTPS, but only HTTP
server {
listen 443;
server_name yourdomain.com;
return 301 http://www.yourdomain.com;
}
and you need to have another server block to complete the www servingon your url.
server {
listen 443;
server_name www.yourdomain.com;
// the rest of your configs //
}
I hope that helps.

Resources