Dharma B

posts about

The Naming of Things

26 Jul 2015

“As names have power, words have power. Words can light fires in the minds of men. Words can wring tears from the hardest hearts. There are seven words that will make a person love you. There are ten words that will break a strong man’s will. But a word is nothing but a painting of a fire. A name is the fire itself.”

- Master Elodin, The Name of the Wind by Patrick Rothfuss

A server naming scheme should accomplish several goals:

Human Parseable A Records

Humans should be able to determine a server’s general role from the hostname and DNS A record. A common bad example are “themed” server names such as superman.example.com, batman.example.com and deadpool.example.com. A naming scheme like this makes it impossible to figure out what the hell a server actually does. It forces future admins to perform unnecessary detective work. Cute themed names should not be used. You will also have to generate a long list of names in advance to avoid slowing down the (re)provisioning process. If your environment is not virtualized and servers are constantly repurposed, you might argue that personalized names can be useful for identifying and labeling physical servers. In this case, the hostname could instead encode hardware information, or simply be a short randomly generated string that acts as a serial number for your asset management system.

A better example would be a name such as database-1.example.com or application-3.example.com. This at least encodes the general role in the hostname.

A great example might be database-1.production.aws.example.com and billingapi-3.development.digitalocean.example.com. In addition to encoding the general role in the hostname it also encodes the server’s tier and location/provider in the domain. The general form of the name is <role>-<serial>.<tier>.<datacenter or provider name>.<organization domain>.<tld>. You can adapt it to your needs with some changes:

User-friendly CNAME Records

Use CNAMEs to alias easy-to-remember names to your servers. For example, jira-1.production.aws.example.com might have the following CNAMEs:

Don’t provide the A Record to users. If you want to do a rebuild of your Jira server you can create jira-2.production.aws.example.com, migrate user data from jira-1, change the CNAMES to point to jira-2 during off-peak hours and power off jira-1 when the traffic moves over. With a short TTL on your CNAMEs, you just performed a zero-downtime migration.

Migrate and Be Consistent

Pick a good naming scheme early on and stick with it. Changing a naming scheme can involve a lot of work and should not be a common occurrence. To migrate existing hosts, set the old name as a CNAME and notify effected parties that the old name will be deprecated. On the deprecation date, change the CNAME to point to a redirect to the new friendly CNAME (e.g. HTTP 301). Check the logs on that redirect for a reasonable period of time. If the redirect is still regularly used, contact the responsible parties. For high-availability services, consider leaving the redirect up permanently.

Once the environment is migrated, remain consistent. An inconsistent naming scheme can cause frustration and additional detective work. Document the naming policy and enforce it on your team.

Don’t Trust the Hostname

Hostnames should not be trusted as a source of truth. A server which says it’s ubuntu-wordpress-6.testing.example.com might have an FTP server or some forgotten cron jobs as well. Names are written by people (or scripts written by people) and people lie. Use a tool to check for installed packages, running services and the presence of any interesting or large files. Ansible Facts and Salt Grains are examples of tools that can automate this detective work.

Avoid using hostnames as parseable input for automation tools/scripts. Imagine you have a script that checks the hostname of a server. If it contains application, it installs Tomcat and adds itself to your continuous integration environment. If it contains database, it installs MySQL and adds itself to your database cluster. An attacker gains control of application-8.production.aws.amazon.com via a 0-day vulnerability. The attacker has inside knowledge of your script and changes the hostname to database-4.production.aws.amazon.com. You run your script (which you also use to install updates). The compromised host now gains access to the production database and the attacker now has your customer information.

Instead, use an asset management or configuration management system as the source of truth. In Ansible this would be the Inventory and in Salt this would be the Topfile. If you use a cloud provider, they may offer an inventory system and API you can use.