High Performance NTP Server with Rust rsntp

- Posted in Uncategorized by

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 Serverspecs 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: Score-NTPClient 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:

source $HOME/.cargo/env

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:

vim /etc/chrony/chrony.conf

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.