This program is a Go implementation an NTP server. It listens for incoming NTP requests on configured local addresses and updates its time reference state from multiple specified upstream (downstream from your perspective as a server) NTP servers.
- Serve NTP requests on IPv4 and IPv6 addresses.
- Periodically query multiple upstream NTP servers.
- Only forward time requests to servers that are confirmed to be available.
- Automatically drop privileges to a specified user and optionally chroot to a given directory.
- Debug logging for troubleshooting.
- Make sure you have Go installed (Go 1.13+ recommended).
- Clone this repository or place the source files in a directory.
- Run
go buildto compile the binary.
go build -o gontppool- You will get an executable named
gontppool.
./gontppool [OPTIONS]-
-4 NUM
Set the number of IPv4 server threads. Default is1. -
-6 NUM
Set the number of IPv6 server threads. Default is1. -
-a ADDR:PORT
Set the local listening address for IPv4 sockets. Default is0.0.0.0:123. -
-b ADDR:PORT
Set the local listening address for IPv6 sockets. Default is[::]:123. -
-s ADDR:PORT
Multiple upstream servers: Specify an upstream NTP server address.
This option can be repeated multiple times to provide multiple servers.
Example:./gontppool -s 127.0.0.1:11123 -s ntp.example.org:123 -s 192.168.0.10:9999
The server will periodically check each upstream server for availability and update its reference time state from any that respond correctly.
-
-u USER
Run asUSERafter binding sockets, dropping privileges from root. -
-r DIR
Chroot into the specifiedDIRafter binding sockets and before running. -
-d
Enable debug messages for verbose output. Useful for troubleshooting. -
-h
Print the help message and exit.
sudo ./gontppool -a 0.0.0.0:123 -b [::]:123 -s 127.0.0.1:11123 -s time.google.com:123 -dIn this example, the server listens on all IPv4 and IPv6 addresses on port 123, queries 127.0.0.1:11123 and time.google.com:123 as upstream servers, and prints debug messages to the console.
The project includes a multi-stage Dockerfile for building and running the server in a lightweight container.
- Clone this repository and navigate to the directory.
- Build the Docker image:
docker build -t gontppool .You can run the NTP server in a container as follows:
docker run --rm --name gontppool -p 123:123/udp gontppool -a 0.0.0.0:123 -s 127.0.0.1:11123 -s time.google.com:123This command:
- Maps port
123on the host to port123in the container (UDP traffic). - Starts the server with local binding to
0.0.0.0:123and uses two upstream servers.
If you want to use the pre-built Docker image for multiple architectures (e.g., amd64, arm64), use Docker Buildx:
docker buildx build --platform linux/amd64,linux/arm64 -t your-dockerhub-username/gontppool:latest --push .Replace your-dockerhub-username/gontppool with your Docker Hub repository or private registry path.
If you have pushed the image to a container registry, you can pull and run it as follows:
docker pull skrashevich/gontppool:latest
docker run --rm --name gontppool -p 123:123/udp skrashevich/gontppool:latest -s time.google.com:123- Ensure you run the server with sufficient privileges to bind to port 123 (or run as root and then use
-uand-rto drop privileges). - The server continuously checks upstream servers every few seconds and updates its internal state.
- If no upstream servers are specified, it defaults to
127.0.0.1:11123.
This program is distributed under the terms of the GNU General Public License (GPL) version 2 or later. See LICENSE for details.