NGinx webserver installation, configuration and managment can be time consuming. You have to adapt configuration when adding new subdomain, new script language support and so on... Lets discover how you can make it easier: new subdomain ? create directory; make SSL mandatory ? create a symlink; make authentication mandatory ? another symlink.
Virtual hosts basis
NGinx webserver, like any modern webserver, is able to handle many virtual hosts, means that you can host many domainname on same IP adress. Choice will be done by webserver, based on informations found into HTTP request (Host field).
This is quite easy, except when you want to use SSL. In SSL, cypher negotiation occurs before HTTP request is sent. Therefore, the webserver has no way to guess which domainname you want to connect to. Starting, it does not know which SSL key he has to choose. One solution could be to create an SSL certificate with all hosted domains in it. That's not a suitable solution, since you'll have to modify your certificate each time you want to add or remove a domainname. Another solution is to use wildcard certificate (as an example for *.domain.tld). But what if you want to add *.domain.anothertld ? Simple: you can't.
Finally, you can create and maintain your own certificate but people connecting to your website will have an alert until they validate your own certificate.
For now, we assume that 1 IP address = 1 domainname.
Environment preparation
Automating vhosts managment require some organisation. Here is basically what I choose as directory tree:
As you can guess, Directory usage is as follow:
config
Will host all "magic" configuration:
auth
Symlinks with subdomains make authentication mandatory.
ssl
Symlinks with subdomains make SSL mandatory.
logs
You'll find here both access and error logs files for the domainname
www
Document root for web hosting. Subdomains will be created as subdirectories.
Now that we have the structure, let's have a look on how the system should behave.
NGinx installation and configuration
Following NGinx configuration should only be used for tests. It certainly won't scale well, as well as won't fit your needs. But it's pretty simple which is always a good thing to understand what happen.
Notice log_format option: I just added $host field so that I can see in log file which vhost has been called. This is important since there will be only one log file per domain and every associated subdomains.
domain.tld configuration
Lets continue with domain.tld configuration. Add following lines into file /etc/nginx/sites-available/mondomaine.com:
Here again, I modified access_log option so that it will use globally defined format vhosts.
I won't detail SSL certificate creation here.
Default vhost
A default vhost is like other vhosts, except that It should deal with all requests for which webserver does not find specific vhost. Just for that, it must be defined before others vhosts.
Create /etc/nginx/site-available/0000-default file and add following configuration:
With this example, I assume you've your own dedicated server. You can safely redirect all traffic against you website. As an example, all request to http://server_ip_addr will be redirect to http://www.domain.tld/
Then you have to enable vhost:
Behaviour rules
Now that we have a basic working configuration, we can have a look on rewrites rules:
We need to host domain domain.tld.
domain.tld must be redirected to www.domain.tld.
We want to easily deal with subdomains. As an example:
blog.domain.tld shal be reachable with SSL. Authentication is integrated into application.
webmail.domain.tld must be reachable with SSL only. Authentication is integrated into application.
protected.domain.tld requires authentication, can be reached without SSL.
masteroftheworld.domain.tld require authentication and SSL.
As we alos registered domain.anothertld, we want to have both domains using same hosting space.
For last point, you'll use ServerAlias option. If you forget that, then requests to domain.anothertld will be managed by default vhost.
Rewrite Rules
Now that we have our behaviour rules, we can now work on the implementation.
Each request to http://domain.tld will be redirected to http://www.domain.tld
This avoid duplicate content.
Every request to http://sslsubdir.domain.tld will be redirected to https://sslsubdir.domain.tld
You just have to make sure that directory /var/www/mondomaine.com/www/sslsubdir exists and that symlink sslsubdir exists in /var/www/mondomaine.com/config/ssl/.
Every request to http://www.domain.tld/subdir will be redirected to http://subdir.domain.tld/
Here again, you have to avoid duplicate content. Just have to make sure that directory /var/www/domain.tld/www/subdir exists.
Every request to http://subdir.domain.tld will be rewritten in /var/www/domain.tld/www/subdir.
You just need /var/www/domain.tld/www/subdir to exist.
You certainly noticed there is no fourth rewrite rules. That's normal because this rule will handle authentication and we're just about to talk about that.
Authentication configuration
It's now time to protect some directories access. We have to create users first:
For next users:
Please not deletion of -c option. If you maintain it, you will override authentication file.
Finall, we just have to setup authentication and define rewrite rule #4:
Rewrite rules order
Rules order is very important: you have to redirect SSL subdomains, then perform optionnal authentication before you determine and serve correct ressource. Bad order can result in protected.domain.tld exposed.
Subdomains definition
As a summary:
blog.domain.tld neither require SSL nor authentication.
webmail.domain.tld requires SSL, not authentication.
protected.domain.tld requires authentication, not SSL.
masteroftheworld.domain.tld requires SSL and authentication.
Once more, to keep things as simple as it can, I won't talk about filesystem access grants.
Final configuration for domain.tld
Here is the result:
Of course, in SSL vhost, we don't need third rule: as we already are in SSL, we don't need to redirect request to HTTPS.
Conclusion
It does not pretend to be exhaustive. Of course, you'll still need to add new domains to NGinx configuration. You will also have to integrate and adapt rewrite rules at 2 places, though you can concentrate it in one file only and use include configuration option.
But, that opens some interesting way of exploration. As an example: can we use this configuration as proxy in front of an Apache to be able to separate static content from dynamic ?.
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.
e-mail : jean point baptiste point favre arobase gmail.com