The other day, I wrote that I was having to make some hacks to my virtual machine in order to get it to run as I wanted in my hypervisor. This was one of them. Having encountered this problem before on a Windows machine, I knew the procedure would be similar for Linux. What I’m talking about specifically, is the problem that network settings, such as DNS server configuration, are erased on reboot by the host’s configuration of the node. Here was my dilemma: I was trying to set up a DNS server on my machine to function as a name server, however, one of the necessities is that the server itself uses its own server as the 1st priority DNS server. I could set this by editing the DNS Settings in Windows or /etc/resolv.conf in Linux, but this was soon erased on reboot.
Now the solution should be very simple in my instance. All my webhost had to do was change the default nameservers in my VM’s configuration file. But they refuse to do that. This is likely because as a large scale host, it is not worthwhile to them to manually configure this, and the fact that they deem their DNS server settings important enough they will not allow changes to them.
I knew what the solution was for Windows. I cooked up a little script a couple of years ago. It basically takes the list of DNS servers currently set, and adds 127.0.0.1 (localhost), to the top of the list. You can grab this script here and all that needs to be done is to set it as a scheduled task to run on System Startup. This will change the DNS settings after the hypervisor changes them at boot, meaning that it is overridden.
When I moved to Linux, I knew I’d have the same issue. It however took a little longer to work out. I knew I wanted to add 127.0.0.1 to resolv.conf, but rc.local did not help me with my problem. I gather this is because it is fired before the hypervisor overwrites the resolv.conf file. My next attempt was to make the resolv.conf file immutable, so it could not be overwritten. I did this with “chattr +i /etc/resolv.conf”, but this caused the container to refuse to start, so I had to gain access to the FS and run “chattr -i /etc/resolv.conf”.
In the end, the solution was obvious. Cron.
This will help you fix it:
Fire up cron’s table in your favourite editor (vi/nano)
But before you do that. Decide your method of maintaining the resolv.conf list. You need to either copy a resolv.conf (our modified one), or directly append the file with a localhost DNS reference, making the server 1st priority.
Make a custom resolv.conf
Do this if you have other settings such as domains “search somedomain.com”. We do this by making a script directory; copying the current resolv.conf; editing it to how we want; copying it as a cron job.
- mkdir /scripts/
- cp /etc/resolv.conf /scripts/resolv.conf
- nano /scripts/resolv.conf #add your settings
- Next add the following to crontab:
- @reboot cp /scripts/resolv.conf /etc/resolv.conf
Append the current file
This requires no extra files. It is the simplest way and is easy if all you want to add is DNS Servers. To add localhost for example, one would add:
- @reboot echo “127.0.0.1″ >>/etc/resolv.conf to append the file.
- Remember this is flexible.
- echo -e “127.0.0.1\n192.168.1.2″ >>/etc/resolv.conf # would add dns servers 127.0.0.1 and 192.168.1.2 in that priority
- echo -e “127.0.0.1″>/etc/resolv.conf # would erase the current configuration first
- However if using such flexibility, it is probably better to define a resolv.conf and then copy it over with
Cron will now execute this command at reboot, appending your DNS settings accordingly.
This solution appears to not be limited to hypervisors, but to many applications, such as NetworkManager. You may need to restart network settings (/etc/init.d/networking restart) – I do not have this problem, but depending on the complexity of modifications, baring in mind these adaptations can be used on /etc/network/interfaces, you may need to restart networking through either a script executed by cron (@reboot /script/foo) or by cron itself (@reboot /etc/init.d/networking restart).