High Performance NTP Server with Rust rsntp
The NTP Pool is a collection of voluntary Server operators, donating bandwith and server ressources to the public, syncing the time of more than 100 Mio Devices on the Internet. To read more about the pool, click here.
But some regions are currently strongly underserved, making proper timekeeping difficult and increasing the load of a few servers. The most notable example of this is the China-Zone. As of writing, there are currently 5 Servers serving the entire country. For comparrison, Finnland, a much smaller Country has 35 active servers.
So to be able to provide a server to the China region, the server has to be able to answer a LOT of queries. This Post describes some expirences on the experiments.
Serverhardware: The Server was a virtual Server from Hetzner Cloud The Server was choosen due to it beeing a small experiment with the capability to scale up and down, depending on the workload.
Normal NTP Client: The first drop started, when the server got added to the China-Zone, immediately the server got overloaded and started dropping Packages. Config:
driftfile /var/lib/ntp/ntp.drift pool ip1 iburst pool ip2 iburst pool ip3 iburst pool ip4 iburst pool ip5 iburst server ntp1.hetzner.de iburst restrict -4 default kod notrap nomodify nopeer noquery limited restrict -6 default kod notrap nomodify nopeer noquery limited restrict 127.0.0.1 restrict ::1 restrict source notrap nomodify noquery
Just a standard NTP Config, with the recommended Settings for the NTP Pool.
Since this was not acceptable(The server started dropping within the first 30 Minutes of beeing readded to the pool), I decided to evaluate other NTP Server Software.
I decided to try out this Rust Implementation due to its ability of multitasking. Since this is not a full ntp server, its needs a Backend Server running, providing the full features. Since ntpd is not able to run on nonstandard ports, I decided to go with chrony, which I will evaluate in a later test.
Setup Requirements: Git, make Installation for Debian and Debian-based Systems(like Ubuntu)
apt install git build-essential
The setup is pretty straight forward, you need to clone the Git Repository with
git clone https://github.com/mlichvar/rsntp cd rsntp
To compile, you need to have Rust installed, which can be installed by running:
curl https://sh.rustup.rs -sSf | sh
and then choosing 1 to install. After the installation is finished, you need to run this command in Order to add rust to your current session:
Now you can start the compiler with
make -e release
The -e Switch sets the Environment we want to compile to, in this case the release Version with the optimized executable.
Cargo now starts downloading depencies and compiling. Once it has finished, go to the output directory of the compiler and copy the created executable to the directory where you want to execute it from and mark it as executable
cp ./target/release/rsntp /usr/local/bin/rsntp chmod +x /usr/local/bin/rsntp
Before we can start the Server, we need to set up Chrony. This is quiet easy as it can be directly installed from the repository:
apt install chrony screen -y
Now we need to edit the Config and adjust a few settings:
Add 4-6 Source Timeserver to the config, in Order to have a proper source of time, then add a few Values, that I will explain below the config:
pool ip1 iburst pool ip2 iburst pool ip3 iburst pool ip4 iburst pool ip5 iburst server server1 iburst makestep 1 3 rtcsync allow cmdport 0 leapsectz right/UTC driftfile /var/lib/chrony/chrony.drift noclientlog port 11123
Explanation of the most important values(Full list here):
pool/server: Source Server where to pull time from.
allow - This is necessary for chrony to allow external queries, like the rust server needs to. You can limit the source of the queries, check the full list link above for more details)
cmdport 0 - Since I only monitor and control the server from itself, I disallowed all remote commands
noclientlog - Disabled due to no rate limiting used(since this isn´t the main NTP Server.
port 11123 - Port to listen to. Required for rsntp
Now you only have to restart chrony.
service chrony restart
And can now start rsntp and begin serving clients. I decided to use screen for this, since I want to monitor it, but you can also create a service for it and have it running in the background. And since I have a 2 Core VM, I want to use 2 Threats for IPv4, which is the majority of the traffic.
screen rsntp --ipv4-threads 2
And thats it, the new Server is now up and running. Verify it with a online test like this one and then add it to the pool.
I am not sure, if this is running better, but I will report back on the results.