NGinx automatic vhosts configuration with subdomains, SSL and authentication support - second version

Jean Baptiste FAVRE

september 2010

This document superseeds this one: Nginx: Configuration d'hôtes virtuels avec support automatique des sous-domaines, du SSL et de l'authentification sous GNU/Debian Linux. I won't get into details here and will use previous results as start.

Previous version gaps

Previous version was fully functionnal. One of the problems concerns optimisations:

As a consequence, NGinx shall behave poorly under eavy load. More, when adding a new vhost, you had to copy the whole rewrite rules set and adapt it.

Try to fix this design issues.

Previous configuration summary

Here is what we got:

tree /var/www/
domain.tld/
|-- config
|   |-- auth
|   `-- ssl
|-- logs
|   |-- access.log
|   |-- error.log
`-- www
    |-- subdir1
    |-- subdir2
    |-- subdir3
    `-- subdir4
Rewrite rules for vhosts domain.tld
########## Rewrite rules for domain.tld => www.domain.tld ##########
if ($host ~* ^domain\.tld$) {
    rewrite ^(.*) $scheme://www.domain.tld$1 permanent;
    break;
}
########## Rewrite rules for automatic SSL support ##########
set $redirect_ssl 'no';
if ($host ~* ^(.*)\.domain\.tld$) { set $ssl_subdomain $1; }
if (-e /var/www/domains/domain.tld/config/ssl/$ssl_subdomain) { set $redirect_ssl 'yes'; }
if ($scheme ~* '^https$') { set $redirect_ssl 'no'; }
if ($redirect_ssl ~* '^yes$') {
	rewrite ^(.*) https://$ssl_subdomain.domain.tld$1 permanent;
	break;
}
########## Rewrite rules to redirect www.domain.tld/directory/... into directory.domain.tld/... ###
if ($host ~* ^www\.domain\.tld$) {}
if ($uri ~* ^/$) {
	set $dir_subdomain "www";
	set $dir_filename "";
}
if ($uri ~* ^/([^/]+)(.*)$) {
	set $dir_subdomain $1;
	set $dir_filename $2;
}
if (-d /var/www/domains/domain.tld/docroot/$dir_subdomain) {
	rewrite ^(.*)$ $scheme://$dir_subdomain.domain.tld$dir_filename permanent;
	break;
}
########## Rewrite rules for automatic authentication support ##########
if ($host ~* ^([^.]+)\.domain\.tld$) {
	set $auth_subdomain $1;
}
if (-e /var/www/domains/domain.tld/config/auth/$auth_subdomain) {
	rewrite ^(.*)$ /auth$1;
	break;
}
if ($host ~* ^([^.]+)\.domain\.tld$) {
	set $auth_subdomain $1;
}
if (-d /var/www/domains/domain.tld/docroot/$auth_subdomain) {}
if (-e /var/www/domains/domain.tld/config/auth/$auth_subdomain) {
	rewrite ^(.*)$ /auth/$auth_subdomain$1;
	break;
}
########## Rewrite rules for automatic subdomains ##########
if ($host !~* ^www\.domain\.tld$) {}
if ($host ~* ^([^.]+)\.domain\.tld$) {
	set $auto_subdomain $1;
}
if (-d /var/www/domains/domain.tld/docroot/$auto_subdomain) {}
if (-e /var/www/domains/domain.tld/docroot/$auto_subdomain/$uri) {
	rewrite ^(.*)$ /$auto_subdomain$uri;
	break;
}
if (-f /var/www/domains/domain.tld/docroot/$auto_subdomain$uri.xhtml) {
	rewrite ^(.*)$ /$auto_subdomain$uri.xhtml;
	break;
}
if (-f /var/www/domains/domain.tld/docroot/$auto_subdomain$uri.php) {
	rewrite ^(.*)$ /$auto_subdomain$uri.php;
	break;
}
if ($host ~* ^www\.domain\.tld$) {}
if (-f /var/www/domains/domain.tld/docroot/$uri.xhtml) {
	rewrite ^(.*)$ /$uri.xhtml;
	break;
}

Fixes to apply

Generic Regex
We have to delete domainname usage into regex so that we don't need to adapt rules for each vhosts.

As an example: if ($host ~* ^domain\.tld$) { will be if ($host ~* ^[.*]+\.[.*]+$) {.

Files and directories checks
Most of the tests are in fact not relevant.
Files and directories checks
The only 2 tests we have to keep are related to SSL and authentication support. All the other ones can and should be deleted.
Rewrite from www.domain.tld/subdir into subdir.domain.tld
Here again, we got a perfs killer. Rules are optimized, but you just have to take care about your link policy to make them optional. They were here just to avoid duplicate content.

Final configuration from domain.tld

/etc/nginx/sites-available/domain.tld
#######################  Magic  RewriteRules  #######################
uninitialized_variable_warn off;
##### Rewrite rules for domain.tld => www.domain.tld #####
if ($host ~* ^([^.]+\.[^.]+)$) {
    set $host_without_www $1;
    rewrite ^(.*) $scheme://www.$host_without_www$1 permanent;
}
##### Rewrite rules for subdomains with automatic SSL support #####
set $redirect_ssl 'no';
if ($host ~* ^(.*)\.([^.]+\.[^.]+)$) {
    set $ssl_subdomain $1;
    set $host_without_www $1.$2;
}
if (-e $document_root/config/ssl/$ssl_subdomain) {
    set $redirect_ssl 'yes';
}
if ($scheme = 'https') {
    set $redirect_ssl 'no';
}
if ($redirect_ssl = 'yes') {
    rewrite ^(.*) https://$ssl_subdomain.$host_without_www$1 permanent;
}
##### Rewrite rules for automatic authentication #####
if ($host ~* ^([^.]+)\.[^.]+\.[^.]+$) {
    set $auth_subdomain $1;
}
if (-e $document_root/config/auth/$auth_subdomain) {
    rewrite ^(.*)$ /auth$1;
    break;
}
##### Rewrite rules for automatic subdirectory rewriting #####
set $redirect_subdir 'yes';
if ($redirect_subdir_done = 'yes') {
    set $redirect_subdir 'no';
}
if ($host ~* 'www\.[^.]+\.[^.]+$') {
    set $redirect_subdir 'no';
}
if ($host ~* ^([^.]+)\.[^.]+\.[^.]+$) {
    set $subdir_domain '$1';
}
if ($redirect_subdir = 'yes') {
    set $redirect_subdir_done 'yes';
    rewrite ^(.*)$  /$subdir_domain$1 break;
}
####################  End Of Magic RewriteRule  ####################

Conclusion

Once more, this way of doing things is not perfect.

But it allows to prepare next step: adding PHP-FPM support. More to come !

About Jean Baptiste FAVRE

I spend most of my free time on the Internet working on GNU/Linux with Debian or CentOS, virtualization with Xen and KVM technology, as well as cluster stacks with corosync and OpenAIS. Particularly interested in Linux, Netfilter, virtualization, monitoring and clusters, most of my personal works are published on this website and others should not delay. By way professional, I manage servers running RedHat or CentOS and VMware ESXi farm.
From time to time, I manage to drop my keyboard and read a book while listening to music, but it never lasts long.

License

Creative Commons License This document is published under Creative Common by-nc-sa license.

Valid XHTML 1.0 Strict |  Valid CSS |  license Creative Common by-nc-sa

Index

  1. Previous version gaps
  2. Previous configuration summary
  3. Fixes to apply
  4. Final configuration from domain.tld
  5. Conclusion
  6. About ...
  7. License