I have accounts on a number of systems where the sysadmin doesn't maintain a comprehensive /etc/hosts file. In order to work around this, I wanted to have a per-user ~/.hosts to extend the system file with my own aliases. Then I could use my short nicknames for network activity without spelling out the whole domain name (the domain setting in /etc/resolv.conf is often not close enough for the nicknames to work using DNS).

A common technique for translating host names into IP addresses is to use either getaddrinfo(3) or the obsolete gethostbyname(3). As mentioned in hostname(7), you can set the HOSTALIASES environment variable to point to an alias file, and you've got per-user aliases!

Well, mostly…

HOSTALIASES will work if your program (ping, ssh, etc.) satisfies two conditions:

  1. It has to actually use one of the two functions listed above to resolve the host name. I haven't run across anything that doesn't, but you never know.
  2. It cannot be setuid to another user. If it is, libc sanitizes the environment, so your HOSTALIASES setting is lost. See sysdeps/generic/unsecvars.h for a list of all environment variables that glibc removes for setuid programs.

ping is setuid root (because it needs to listen for ICMP packets), so HOSTALIASES will not work with ping unless you're already root before you call ping.

Here's an example:

$ echo 'g www.google.com' >> ~/.hosts
$ export HOSTALIASES=~/.hosts
$ firefox g

Adjust your ~/.bashrc appropriately, and you can forget about /etc/hosts entirely :).

There's one more caveat: the HOSTALIASES file maps alias names to canonical host names, but the canonical name must be resolvable. You can't specify an IP address as the target.