Well for this one I will be talking a bit about NTP and NTS.
Unlike the DNS post there isn't much going on here.
NTP is plain-text, NTS uses TLS so if our requests are tampered with, we can know.
There is the "oooh, you cant see what I'm sending now" but in this case its NTP so the content being secret is not necessarily more important than making sure the content has not been modified(guarantee of integrity).
So far so good.
But before we go any further, lets talk about what we are trying to achieve here, in other works, what requirements are we trying to satisfy here:
If you are wondering why any of this even matters you can have a look here.
Now talk about the problem. The protocol is fine. We are sending TCP with TLS here. That's brilliant. We get all this:
* Identity: Through the use of a X.509 public key infrastructure, implementations can cryptographically establish the identity of the parties they are communicating with.
* Authentication: Implementations can cryptographically verify that any time synchronization packets are authentic, i.e., that they were produced by an identified party and have not been modified in transit.
* Confidentiality: Although basic time synchronization data is considered nonconfidential and sent in the clear, NTS includes support for encrypting NTP extension fields.
* Replay prevention: Client implementations can detect when a received time synchronization packet is a replay of a previous packet.
* Request-response consistency: Client implementations can verify that a time synchronization packet received from a server was sent in response to a particular request from the client.
* Unlinkability: For mobile clients, NTS will not leak any information additional to NTP which would permit a passive adversary to determine that two packets sent over different networks came from the same client.
* Non-amplification: Implementations (especially server implementations) can avoid acting as distributed denial-of-service (DDoS) amplifiers by never responding to a request with a packet larger than the request packet.
* Scalability: Server implementations can serve large numbers of clients without having to retain any client-specific state.
* Performance: NTS must not significantly degrade the quality of the time transfer. The encryption and authentication used when actually transferring time should be lightweight.
Excerpt from RFC 8915
If we find a client that lets us use a SOCKS5 proxy, then we can send our NTS requests over Tor and then call it a day.
REQ-002 and REQ-003 are being satisfied by using TLS. The missing piece is REQ-001, anonymizing the requests.
This is not something for the protocol to handle so then we have to look for a client that support a SOCKS5 proxy.
Unfortunately chrony and ntpd-rs do not support SOCKS5 proxies.
Which means our setup is not complete.
We will be using ntpd-rs as the client.
We will also setup one NTS server using ntpsec.
[observability]
log-level = "info"
observation-path = "/var/run/ntpd-rs/observe"
[[source]]
mode = "nts"
address = "virginia.time.system76.com"
[[source]]
mode = "nts"
address = "mmo1.nts.netnod.se"
[[source]]
mode = "nts"
address = "ntppool1.time.nl"
[[source]]
mode = "nts"
address = "ntp1.glypnod.com"
[[source]]
mode = "nts"
address = "ntp3.fau.de"
[synchronization]
single-step-panic-threshold = 1800
startup-step-panic-threshold = { forward="inf", backward = 1800 }
minimum-agreeing-sources = 3
accumulated-step-panic-threshold = 1800
[[server]]
listen = "127.0.0.1:123"
[[server]]
listen = "172.17.0.1:123"
[[server]]
listen = "192.168.121.1:123"
[[server]]
listen = "10.167.131.1:123"
[[server]]
listen = "[::1]:123"
nts enable
nts key /etc/letsencrypt/live/nts.dehein.org/privkey.pem
nts cert /etc/letsencrypt/live/nts.dehein.org/fullchain.pem mintls TLS1.3
nts cookie /var/lib/ntp/nts-keys
nts-listen-on 4460
server 0.0.0.0 prefer
server ntpmon.dcs1.biz nts # Singapore
server ntp1.glypnod.com nts # San Francisco
server ntp2.glypnod.com nts # London
tos maxclock 5
restrict default kod limited nomodify noquery
restrict -6 default kod limited nomodify noquery
driftfile /var/lib/ntp/ntp.drift
statsdir /var/log/ntpstats/
version: "3.9"
services:
filebrowser:
image: ntpsec
build:
context: .
deploy:
resources:
limits:
memory: 128M
logging:
driver: "json-file"
options:
max-size: "50m"
networks:
- ntsnet
ports:
- "4460:4460/tcp"
restart: unless-stopped
entrypoint: ["ntpd"]
command: ["-n", "-I", "0.0.0.0", "-d", "5"]
volumes:
- ./ntp.conf:/etc/ntp.conf:ro
- /etc/letsencrypt/live/nts.dehein.org/fullchain.pem:/etc/letsencrypt/live/nts.dehein.org/fullchain.pem:ro
- /etc/letsencrypt/live/nts.dehein.org/privkey.pem:/etc/letsencrypt/live/nts.dehein.org/privkey.pem:ro
- vault:/var/lib/ntp
cap_drop:
- ALL
cap_add:
- SYS_NICE
- SYS_RESOURCE
- SYS_TIME
networks:
ntsnet:
volumes:
vault:
Above we looked at NTP and NTS. We failed to find a client that supports SOCKS5 but that's a trivial matter.
What is not trivial, however, is how NTS and NTP work, and by that I mean you will still have to ask a server to tell you the time.
Doing so over Tor or other anonymizing networks should be fine but we can choose to try out another method of doing things.
Enter sdwdate
It still has the same flaw as NTP/NTS as in we still have to trust a server not to lie please look here.
Personally, It is a bit of a disappointment that the protocol that's supposed to be oh-so-much-shinier and newer than NTP has the same flawed mechanism as NTP.
Now granted having hardware that tells you the time so that you can share that with everyone else is not something trivial or readily-available but this only makes sdwdate desirable in the absence of an NTS client that support SOCKS5 proxy.
Once that is done, the larger user pool of NTS/NTP will offer more protection against the smaller userbase of sdwdate.
sdwdate gives a table of comparison between itself and NTP. Let's take at look at that:
Let's take a look at sdwdate
. It is a roller-coaster. And I do mean that. So don't make up your mind until the very end.
There is a comparison between NTP and sdwdate made here by kicksecure themselves.
category | sdwdate | ntp |
---|---|---|
written in memory-safe language | Yes | No |
distributed trust | Yes | No |
secure connection by default | Yes | No |
gradual clock adjustments | Yes | Yes |
daemon | Yes | Yes |
functional over tor | Yes | No |
tor not required | No | Yes |
client, time fetcher | Yes | Yes |
Server, time provider | No | Yes |
AppArmor profile | Yes | Yes |
systemd security hardening,seccomp | Yes | ? |
drop-in config folder | Yes | No |
proxy support | Yes | No |
possible to secure by default on GNU/Linux distribution level | Yes | No |
secure | Yes | No |
optional GUI | Yes | No |
If we were going to base our judgement on the documentation provided on kicksecure's website, I am sorry to say that sdwdate
does a very poor job but fortunately that's not all there is to it.
Now let's go take a look at the github README for the project:
At randomized intervals, sdwdate connects to a variety of webservers and extracts the time stamps from http headers (RFC 2616))
This is our first spark of brilliance.
The second spark is when we consider the practical meaning of only being able to use Tor v3 addresses. Like a wise man once said:
amateurs practice something until they can get it right. pros practice something until they can't get it wrong.
The result of using only Tor v3 addresses is that you cannot leak your real IP address no matter what happens. You either have a working Tor proxy in which case the IP address will be that of the exit node or none at all.
Now we know we definitely are dealing with a very promising solution. 'sdwdate' extracts the time stamp in the http header so we are not asking a known NTP server about the time, we are just doing a normal http request.
Although unrelated, it is worth noting that the kicksecure docs are pretty good even if you are not planning on using kicksecure.