This post proposes a solution to restore hostname settings on virtual servers during reboot. It’s probably a common V-Server phenomenon that the virtualization software overwrites some network configuration files on startup. I have this problem with Strato, my reliable and competitively priced German provider. The overwrite happens because the V-Server management system needs to assign the right IP addresses and good name servers to V-Server instances. However, whilst network settings are reset for a good reason, I feel that the hostname is a user setting that server providers might respect.
Why Custom Hostnames Matter
First off, when opening an SSH connection to one of my servers, I like to see a name I can remember at the command prompt, and not some generated number. More importantly, daemon processes that require networking read system settings and may start using a different hostname if it changes after reboot. In most cases this will not make a functional difference. But for a mail server I like to have matching reverse DNS record and hostname, if only because the hostname may become part of mail headers.
Setting Hostname by System Service
On Ubuntu 20.04 a custom system service fixes the hostname overwrite issue for Strato, and probably many other V-Server providers. The service needs to run after network initialization, but before starting up daemons that require networking.
For the proposed solution, as root user, create a folder /root/startup and the following service definition file:
/root/startup:$ cat hostname-setup.service [Unit] Description=Setup Hostname Before=network.target [Service] ExecStart=/root/startup/setup.sh Type=oneshot [Install] WantedBy=network-online.target
Then create the shell script that fixes the hostname:
/root/startup:$ cat setup.sh #!/bin/bash SDIR=`dirname $0`; touch $SDIR/setup-ran HOSTNAME=howler.frizz.net echo $HOSTNAME > /etc/hostname hostname $HOSTNAME exit 0
For testing, the setup script creates a file ‘setup-ran’ having the time the hostname was restored as a modification timestamp.
Afterwards, activate the service in systemctl:
/root/startup:$ cd /etc/systemd/system /etc/systemd/system:$ ln -s /root/startup/hostname-setup.service /etc/systemd/system:$ systemctl enable hostname-setup.service
Now reboot the server. Upon logging in, the system should have restored your custom hostname. Also, daemons like Postfix should have used your hostname in system log files during their startup. If that’s not the case, compare logging timestamps to the ‘setup-ran’ file. To check the timestamp, do:
/root/startup:$ ls --full-time setup-ran
How Does the Fix Work?
The boot process for Debian based systems, such as Ubuntu, is described in the Debian System Initialization Reference. It specifies that from boot stage 4 the Systemd takes charge of spawning up the process tree. To work out which processes to start, Systemd reads unit configuration files with “Wants=”, “Requires=”, “WantedBy=”, and “RequiredBy=” dependency directives. By evaluating which other units a configuration unit wants or requires to run, Systemd learns about restrictions in the process startup sequence. In addition, “Before=” and “After=” directives give startup preferences where hard dependencies are missing.
*.service describes the process controlled and supervised by systemd.Debian System Initialization Reference
*.target groups other unit configuration files to create the synchronization point during start-up.
Debian furthermore bundles *.service configuration units into *.target synchronization points. On my Ubuntu 20.04 system, I have services of interest like apache, postfix and mariadb under the “multi-user” target. For custom name server settings to take effect, the restore needs to happen before any of those processes start. Looking at “After=” directives for “multi-user”, I find “network”, “network-pre”, and “nss-lookup” as targets to complete before “multi-user”. So requiring the “hostname-setup” service to run before “network” target enforces the right sequence.
In the service definition, the service should be “Type=oneshot” so Systemd waits until the setup script completes, before continues on to “multi-user” target.
Finally, the Debian reference specifies /etc/systemd/system as standard directory for configuration files overriding defaults. So that’s where we create the symlink to the service file under /root/startup.