Setting up a hostname and Avahi (mDNS)

We previously made sure our machine can access the internet. In this post, we’ll configure our machine so that we can access it from the local network, without ever knowing its IP address.

Hi. What’s your name?

First of all, we need to set a hostname for our machine. We want to access our machine using an easy to remember name instead of its IP address. It’s so much easier to ping centosvm instead of ping 192.168.1.42 isn’t it? Plus, the IP address might change, but we won’t care since all we need to know is the hostname to access the machine.

Setting a hostname will not actually do anything by itself. Other computers will not be aware of this name, just because we set one. However, CentOS (or any other operating system) might use this name internally or to conveniently “advertise” itself to the network, or we can manually set up services that will do this on our behalf.

Now, according to the RHEL Documentation on host names (make sure you read the whole chapter, it’s very short), there are three different hostnames a system can have, and there are three different ways to set them.

There are three kinds of hostnames (according to the RHEL documentation). Static, pretty, and transient. Static is the one we’re interested in, as it’s the one that the rest of them fallback to. Pretty, is the one that the user sees, just in case you want it to be different. So for example, the static hostname can be “centos7vm” (only latin letters, digits, dots, dashes and underscores are allowed, along with some other restrictions), while the pretty hostname can be “CentOS 7 Virtual Machine Testbed“. Or you know, both can just be “centos7vm“… whatever…

And finally, transient… now, the documentation says the transient hostname is maintained by the kernel. Why? I don’t know, nor could I find any more information by googling it. Why won’t the kernel use the static hostname? Don’t look at me.

Anyway. We can set a hostname using either hostnamectl, nmtui, or nmcli. On both the documentation pages of nmtui and nmcli it mentions that “at time of writing, changing the host name in this way will not be noticed by hostnamectl“. This leads me to believe that hostnamectl is the most appropriate tool to handle this job, although it’s doable with the others as well.

So, according to the documentation, we need to issue hostnamectl status or just hostnamectl (the status is implied) in order to see our current hostname.

Screenshot of hostnamectl with the default hostname localhost.localdomain
Only the “Static hostname” (first line) is of interest right now.

The hostname localhost.localdomain is default to most Linux distributions, or at least the ones I’ve come across. Now, let’s change this bad boy.

I want to be able to ssh from my laptop into the VM by typing ssh devvm as in “Development Virtual Machine“. That’s my static and pretty hostnames right there! Let’s type the following commands (note that the quotes are required if you want spaces in the pretty hostname):

hostnamectl set-hostname "Development Virtual Machine"
hostnamectl status

Screenshot of hostnamectl changing and displaying hostname information.

We see that there is a new line on the status output, that says our pretty hostname is exactly what we typed, while the static hostname is a sanitized version of it, developmentvirtualmachine, with spaces and capitalization removed. I however, don’t want to be typing this humongous hostname, so, let’s change it to devvm:

hostnamectl set-hostname devvm --static
hostnamectl status

Screenshot of hostnamectl setting a static hostname.

We can now see the static hostname changed to devvm, as well as a new line added with the Transient hostname set to developmentvirtualmachine. Why? I don’t know. Moving on.

Connect using the hostname

We’ve set a hostname for our machine. Great. Now, if you try to ping it from you host computer (i.e. the laptop that runs the virtual machine) you’ll get something like this:

Screenshot of ping: cannot resolve devvm: Unknown host
Can’t ping devvm. Do you want to poke one of your friends instead?

Computers don’t magically know each other’s names. They need to somehow translate those names to IP addresses. There are various ways to achieve this, each one having its most appropriate use-case. Just read a few of the answers other users got when asking the same question. Specifically, read this answer as it’s better written than I ever could have written in.

In short, we are interested in Multicast DNS (mDNS for short). It does not require a server such as DNS, it does not require us modifying any files every time an IP address changes (and in the case of our VM, most probably on every restart), and it works with Linux, Mac and Windows. In short, it requires zero configuration! The perfect thing!

The software that implements the mDNS protocol for Linux is called Avahi. Let’s go and install it without delay! Logged in as root (yeah yeah, I know it’s not safe. We’ll stop using the root user when we’ll be done with most base system configuration), type yum install avahi

Yum will determine the fasts mirror, will fetch information on the package we requested, check its dependencies, and ask us whether we want to install avahi and update its dependencies. Just type a y and press enter to confirm. It will then ask us to import a GPG key, just say yes to that to. After a few seconds, avahi should be installed on your system.

Now, avahi makes our hostname discoverable by appending .local at the end, so I should be able to ping devvm.local successfully. This is not the case however, since the avahi daemon does not run yet. Let’s reboot the VM, just in case the service is set to run on each boot.

Just a sidenote here that we can avoid rebooting every now and then, by restarting the various services (or daemons). However, I don’t want to mess around with systemd just now, and want to be sure whenever I start the VM everything works as expected. So, just reboots for a little while longer. They are very fast anyway.

In order to determine if avahi is going to be starting each time the machine starts, we can type systemctl status avahi-daemon.service and we’ll get some information on the specific service. On the end of the Loaded: line we see the word enabled which means avahi is set to run on startup. If it was already running, we would see quite a lot more information.

Screenshot of systemctl status avahi-daemon.service right after installation

Let’s reboot to confirm that it actually runs after a restart. Once the machine reboots, I run nmcli d to make sure it’s connected, and then systemctl status avahi-daemon.service to see if avahi is running. Everything looks perfect!

Screenshot of nmcli d and systemctl status avahi-daemon.service running smoothly
Looks good!

Let’s try and ping our VM from our host (i.e. my laptop): ping devvm.local

Screenshot of ping devvm.local saying unknown host
Does NOT look good!

Argh! What’s wrong?

Let’s (virtually) disconnect the network cable and then reconnect it to see what happens. On your running virtual machine window, you’ll find a series of icons on the lower left border. Find the one that looks like two computer monitors. If you hover over it, it will read something similar to “Indicates the activity of the network interfaces:“. Click on it and then select “Connect Network Adapter” so as to uncheck it. Run nmcli d continuously until the state reads unavailable (so we know linux got notified of the disconnect) and then go back and re-select “Connect Network Adapter” so it’s checked. Again, run nmcli d to make sure we’re reconnected. Run systemctl status avahi-daemon.service -l (that’s a lower-case L, it shows the full messages instead of truncating them) and we’ll see something similar to the screenshot below.

Screenshot of avahi status showing it responded to a disconnect and a reconnect

Four consecutive lines inform us that avahi understood the disconnect: “Withdrawing address record…“, “Leavind mDNS multicast group…“, “Interface enp0s3.IPv4 no longer relevant for mDNS“. Then, four lines showing that avahi got notified of the reconnect: “Joining mDNS multicast group…”, “New relevant interface…“, “Registering new address record…

Let’s try and ping our VM again. Nope. No luck.

Let’s restart only the avahi daemon. Type systemctl restart avahi-daemon.service and press enter. There’s no feedback, therefore no errors. That’s good! Let’s try pinging the VM again. Oh wow! It works!

So, we’re now in a good path, i.e. we know avahi works alas, not exactly as it should after boot. Rebooting my virtual machine confirms it again doesn’t work, and the whole process before can bring it to a working state.

I scoured the internet with search terms such as “centos 7 avahi doesn’t work“, “centos 7 virtualbox avahi problems“, and all the other ways I could phrase my problem, but to no avail. Pretty much, I can’t really explain why avahi won’t work after boot,

Furthermore, I noticed that after 5 minutes or so, avahi would stop working again, i.e. I couldn’t ping the machine using its hostname. I was about to dump CentOS for Debian, when searching for the term centos 7 avahi stops working I stumbled on this thread which mentions the firewall. It actually makes sense. If the firewall is configured to block incoming connections to avahi, this explains why it won’t work in general. When restarting the avahi daemon, it probably initiates some connections so the firewall temporarily whitelists it, and then it appears as working. After a specific time frame, it’s again blacklisted. Perhaps, when the machine boots, avahi starts before the firewall, so the firewall never has the chance to listen to the internally-initiated connection by avahi, therefore it never temporarily whitelists it. It’s a plausible explanation for my issues.

This hypothesis seems to be supported by this article (found while searching for centos 7 avahi firewall), where the author immediately configures the firewall after installing avahi. Let’s do what he does to configure the firewall:

firewall-cmd --zone=public --permanent --add-service=mdns

Let’s reboot the machine and ping. It works! Let’s wait 5-10 minutes as well and ping again. It works again!

I thought this nightmare would never end! Woohoooooooooo!

You might be interested in …

Screenshot of a terminal with tmux running Midnight Commander, vim and htop

New Year’s Resolution v0.16

Speaking terminal

Shame on me. It’s been almost four years without writing a single word in this blog. You can’t – of course – force creativity, but it’s not like I’d write long essays anyway. I do however like the technical side of things and I enjoy challenges in unhealthy amounts, if the enjoyment could be measured, […]

Read More

Setting up networking (I can has internetz)

Speaking terminal

In my previously misleadingly titled “Setting up an environment” post, we created a brand new minimal CentOS 7 installation. The title is misleading in the sense that in order to set up an environment, I’ll need far more than a few posts to explore and configure an ideal environment. In this post, we’ll configure networking […]

Read More

Setting up an environment

Speaking terminal

So, in order to have a vanilla environment where I’ll get to play around and have to configure most of the stuff myself (in order to force myself to learn), I decided to install CentOS 7 in a virtual machine. This will give the added benefit of keeping snapshots so that in case I get […]

Read More

6 Comments

  1. Very nice article, especially the detail you brought to it, the many links and also what you searched for on Google.

  2. This article is missing info on nss-mdns. If you don’t have that along with avahi, it won’t work out of the box because your system only knows to use dns servers in your /etc/resolv.conf file (which is populated by NetworkManager)…

    On some fresh installs of CentOS 7 Avahi is enabled by default (for instance the GNOME Live edition) but nss-mdns isn’t and isn’t available in the default repos…

    Easiest way to add the required repo to your system is:
    sudo yum -y install epel-release

    Then just do:
    sudo yum -y install nss-mdns

    Your default firewall zone Public, should already allow the mdns service by default. You can check this using firewall-config from the command line.

    Finally, a transient hostname is when your system was automatically assigned a hostname through DHCP (common in large enterprises)…

  3. Thanks, firewall command fixed problem for me! It was very baffling – would reboot Redhat vm (under VMware Fusion), my first ssh using the name.local would work but subsequent ones didn’t until I’d rebooted. I’d figured the first one was somehow changing things for subsequent ones, didn’t realise it was time related (although I do now recall sometimes doing another successful ssh).

Leave a Reply

Your email address will not be published. Required fields are marked *