aboutsummaryrefslogtreecommitdiffstats
path: root/mds/NTP.txt
blob: ebb7997374a1732fab215b7581ee4d33f2523714 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
== After NTP Comes NTS. After NTS comes sdwdate.

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:

* REQ-001: The NTP(NTS) requests shall be anonymous
* REQ-002: It shall be evient when an NTP(NTS) requests has been
tampered with
* REQ-003: It should not be known which time servers are being used
upstream by the client

If you are wondering why any of this even matters you can have a look
https://www.whonix.org/wiki/Time_Attacks[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 https://www.rfc-editor.org/rfc/rfc8915[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 https://gitlab.com/chrony/chrony[chrony] and
https://github.com/pendulum-project/ntpd-rs[ntpd-rs] do not support
SOCKS5 proxies.

* for ntpd-rs look
https://github.com/pendulum-project/ntpd-rs/discussions/1365[here]

Which means our setup is not complete.

=== Implementation

We will be using ntpd-rs as the client. We will also setup one NTS
server using https://gitlab.com/NTPsec/ntpsec[ntpsec].

[source,toml]
----
[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"
----

[source,conf]
----
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/
----

[source,yaml]
----
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:
----

=== What comes after NTS

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`

==== sdwdate

It still has the same flaw as NTP/NTS as in we still have to trust a
server not to lie
https://www.kicksecure.com/wiki/Sdwdate#sdwdate_Source_Pools[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
https://www.kicksecure.com/wiki/Sdwdate#Sdwdate_vs_NTP[here] by
kicksecure themselves.

[cols=",,",options="header",]
|===
|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
|===

* memory-safety: I mean its good and all that sdwdate uses a memory-safe
language(python) but NTP is a protocol. Not sure how NTP is bound to a
single programming language. The one client we mentioned before uses
rust which guarantees memory safety.
* secure connection by default: NTS uses TLS v1.3 . Not sure why sdwdate
is being compared against NTP and not NTS.
* functional over Tor: again, NTS uses TCP which can pass through a
SOCKS5 proxy as is implemented by the current incarnation of Tor. Also,
not sure, but are we comparing against the NTP protocol or a specific
implementation?
* Tor not required: what if I want to use
https://github.com/PurpleI2P/i2pd[i2p] or
https://github.com/yggdrasil-network/yggdrasil-go[yggdrasil] to sync
time over? Why does it have to be Tor?
* apparmor profile: not sure why this is even included. You can write
one for NTP implementations.
* systemd security hardening, seccomp: same as above. You can do it for
NTP/NTS implementations as well.
* drop-in config folder: what’s a folder? Is that supposed to be a
directory? Second, what does that even mean? And third, who is writing
these? The only kind of people who make this sort of mistake are people
who use MS Windows more than Linux. This is official kicksecure
documentation. You have Windows users writing these for the ultra secure
and hardened ``Linux'', I’ll say it again, ``Linux'', distro?
* proxy support: again, NTS uses TCP so it supports SOCKS5 proxies as
well but for whatever reason we are comparing against NTP(though whether
we are comparing against the protocol or an implementation is something
left to be decided by the next generation of humans)
* possible to secure by default on GNU/Linux distribution level: whats
the GNU/Linux distribution level? What does this even mean? You can
secure it on the OS level? I mean it’s software so I would hope that it
would be possible to secure it on the software level.
* secure: what are the criteria? Secure against what? And again, why are
we comparing to NTP and not NTS?
* optional GUI: again not sure why we keep zig-zagging between comparing
implementations and the protocols. In conclusion, why is that table even
there? What purpose does it even serve?

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:

[source,txt]
----
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:

[source,txt]
----
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.

=== DISCLAIMER

Although unrelated, it is worth noting that the kicksecure docs are
pretty good even if you are not planning on using kicksecure.

=== Links

* https://www.rfc-editor.org/rfc/rfc8915[RFC 8915]
* https://github.com/jauderho/nts-servers[Here] you can find a list of
publicly available servers that support NTS
* https://github.com/Kicksecure/sdwdate[sdwdate’s github page]
* https://www.kicksecure.com/wiki/Sdwdate[sdwdate doc]
* https://www.rfc-editor.org/rfc/rfc2616[RFC 2616]

timestamp:1713478033

version:1.1.0

https://blog.terminaldweller.com/rss/feed

https://raw.githubusercontent.com/terminaldweller/blog/main/mds/NTP.md