The Last Word On DNS and Host Naming Conventions
1983 was a pretty amazing year. Lotus 1-2-3 was released, the IBM PC XT was released, Pioneer 10 becomes the first man-made object to leave the solar system. We get a woman and a black man in space, there is nuclear panic, the first NES is released, Brinks Mat, the IRA and Maggie Thatcher. Also, DNS was invented. If you want the history, here is a link to the Wikipedia article. With it, DNS brought us the great naming conundrum.
As a Systems Administrator (or a variant thereof, whatever the title), I have strong views on DNS naming conventions in your average corporate network. I’ve seen some obtuse and downright sadistic host and DNS naming convention abuses; I want to avoid more of the same. So, below, is my take on the definitive guide to your average internal namespace. Feel free to comment.
Use full words: don’t omit vowels or use cryptic two letter abreviations
‘dc’, ‘prn01’, ‘ps1-LON’. Wrong, wrong, wrong. Just learn to type and use full words. And what is this obsession with omitting only vowels? I mean: ‘exchngsvr’. Is it really worth it? Does it roll off of the fingers that much more easily? Really? It makes things much more obvious to you and non-technical people alike if you just use full words in logical domains. What would you both as an admin and a user prefer?
app14.svr.internal.corp.com
or
sales.servers.internal.corp.com
A logically configured name that can be read almost as a sentence can’t be a bad thing. To the business it makes the whole thing seem less like a Heath Robinson cranky geek outfit and a modern proper infrastructure.
Properly Configure and Use the Domain Search List
Make sure your domain search list is properly ordered and contains everything sensible for your outfit. Not only does it simplify configuration to single, obvious (full!) words, it comes into it’s own if you ship Virtual Machines between locations, copy configuration information to backup sites, or otherwise sychronize configuration between differently named domains.
Let’s say you ship a VM to a DR and production location. Each is handed out DNS information via DHCP and they have their domain search lists set to dr.corp.com and production.corp.com respectively. All of your scattered, site-specific configuration goes away. Want to talk to an SMTP server? Call it ‘mailhost’ in your configuration and at the DR site the DNS search list will cause a lookup for mailhost.dr.corp.com - likewise for the production location.
Not forgetting the users, having a domain search list that enables them to refer to hosts as ‘sales’, ‘fileserver’, ‘sage’ without full qualification makes everybody’s life easier.
The Cricket Book
Read it. It is getting slightly out-of-date, but the fundamentals still apply. Not optional.
Be Careful of Split Horizon Namespaces
… or revealing a different view of the world to your internal machines. Better that www.corp.com resolves to the same address no matter where you’re coming from and you handle the traffic from one point of ingress only. When the box moves in a year, or something else changes you’ll have an outage. A subdomain of your real (or /a/ real) domain is preferable to an unqualified ‘.corpnet’ internal domain, or a dummy domain in another TLD unresolvable externally. You have a proper chain of DNS delegation making any future delegation and rearrangement of your DNS configuration exponentially more trouble-free.
Get ready for DNSSEC, Test Your Resolver
DNSSEC is coming. When is open to debate, but it pays to keep on top of things. The DNS-ORAC have kindly created a test to determine if your resolver chain can or cannot receive large responses, a problem with additional traffic required for a DNSSEC lookup. Run it and do something about any problems.
Don’t neglect it
DNS is critical to any modern network, be it the Internet as a whole, or your little part of it. A bit of thought and a bit of discipline will make for a better infrastructure for you and your clients.
A Strategy for Domain Name Canonicalization
I recently had to solve a problem for a client at quite short notice. It is a twist on the normal domain canonicalization steps that we might use.
The client had three major requirements:
- The client had 20 publically accessible domains, of which 3 were “canonical” and represented their presence in three different terriorities. The rest were legacy, commerical variants, or “catch-alls”. They had 4 internally-resolvable domain to access various management aspects of the application (all ACL protected too, of course!).
- The client required that if a user visit the site with a plain domain name, it should be canonicalized to the www. version with a 301 redirect
- The site must be SSL protected.
SSL certificates only existed for the three main domains.
Usually, within this particular part of infrastructure we would move the SSL burden to the load balancer, and have that issue a 302 redirect to the https protected site automatically, preserving any of the path portion of the URL that had been supplied too.
As SSL certificates existed only for the three canonical domains this wasn’t an option: we can’t issue a redirect to https until we canonicalized the domain (the certificates were not wildcards, even for the three that existed). Canonicalization would take place after the connection would hit the load balancer. It just would not work.
I took the decision to use the Apache instance fronting-up the application server to handle all of these tasks, as it was the natural place for them to sit. The load balancers were relegated to fail-over, session persistence and NATing only.
A new Apache was recompiled that included:
- mod_alias (part of the default build)
- mod_rewrite
- mod_proxy
Now, to tackle domain name canonicalization.
When using name-based virtual hosts Apache serves content from the first default vhost where the requested domain does not match the ServerName or ServerAlias of any of the other named vhosts.
I took advantage of this and had the default vhost configured with an internally resolvable hostname, thereby creating a catch-all for any requests not to canonical domains.
The following configuration directives were used:
RewriteEngine On
# Alternative hostname, with or without a www. prefix
# Repeat for all non-canonical domains
RewriteCond %{HTTP_HOST} ^.*notcanonical\.test$ [NC,OR]
RewriteCond %{HTTP_HOST} ^.*alsonotcanonical\.test$ [NC,OR]
# Canonical hostname without www. prefix
# Repeat for all canonical domains
RewriteCond %{HTTP_HOST} ^canonical\.test$ [NC,OR]
RewriteRule ^/(.*) https://www.canonical.test/$1 [L,R=301]
RewriteCond %{HTTP_HOST} ^anothercanonical\.test$ [NC,OR]
RewriteRule ^/(.*) https://www.anothercanonical.test/$1 [L,R=301]
There are some important details in here.
- By redirecting straight to the desired canonical domain with https:// prefix the request cycle is shortened to only one possible 301 redirect. It would be possible to simply let the URL iterate over the conditions multiple times, perhaps for ease of maintenance and DRYness, but you risk increasing the response cycle length.
- The ‘NC’ flag ensures that case is ignored, and we add ‘OR’ to override the explicit AND for RewriteConds.
- When we issue the Rewrite we the ‘L’ flag is included to stop multiple iterations through the request cycle, and we override the default 302 issued (temporary) with a 301.
- The brackets within the RewriteRule regex capture any matches into a named variable ($1). We use this in the 301 target URL to preserve any of the path portion of the URL. The hostname and port are not parsed with this type of rule.
The final part of the puzzle is configuring two named virtual hosts for each canonical domain. The first listens on port 80 for plain http and is there to handle the situation whereby the user visits the canonical domain, but does so via plain http. Within the vhost container I used the RedirectMatch directive of mod_alias to issue a 301 redirect to the https:// version of the URL.
RedirectMatch 301 (.*)$ https://www.canonical.test$1
The second named host listens on port 443 and is configured to handle SSL in the usual manner. Within the vhost container we proxy the back-end application with something like:
ProxyRequests Off < Proxy * > Order deny,allow Allow from all </Proxy> ProxyPass / http://appserver.internal/ ProxyPassReverse / http://appserver.internal/

