]> git.proxmox.com Git - ceph.git/blob - ceph/doc/dev/cephx.rst
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / doc / dev / cephx.rst
1 =====
2 Cephx
3 =====
4
5 .. _cephx:
6
7 Intro
8 -----
9
10 The protocol design looks a lot like kerberos. The authorizer "KDC"
11 role is served by the monitor, who has a database of shared secrets
12 for each entity. Clients and non-monitor daemons all start by
13 authenticating with the monitor to obtain tickets, mostly referreed to
14 in the code as authorizers. These tickets provide both
15 *authentication* and *authorization* in that they include a
16 description of the *capabilities* for the entity, a concise structured
17 description of what actions are allowed, that can be interpreted and
18 enforced by the service daemons.
19
20 Other references
21 ----------------
22
23 - A write-up from 2012 on cephx as it existed at that time by Peter
24 Reiher: :ref:`cephx_2012_peter`
25
26 Terms
27 -----
28
29 - *monitor(s)*: central authorization authority
30 - *service*: the set of all daemons of a particular type (e.g., all
31 OSDs, all MDSs)
32 - *client*: an entity or principal that is accessing the service
33 - *entity name*: the string identifier for a principal
34 (e.g. client.admin, osd.123)
35 - *ticket*: a bit of data that cryptographically asserts identify and
36 authorization
37
38 - *principal*: a client or daemon, identified by a unique entity_name,
39 that shares a secret with the monitor.
40 - *principal_secret*: principal secret, a shared secret (16 bytes)
41 known by the principal and the monitor
42 - *mon_secret*: monitor secret, a shared secret known by all monitors
43 - *service_secret*: a rotating secret known by all members of a
44 service class (e.g., all OSDs)
45
46 - *auth ticket*: a ticket proving identity to the monitors
47 - *service ticket*: a ticket proving identify and authorization to a
48 service
49
50
51 Terminology
52 -----------
53
54 ``{foo, bar}^secret`` denotes encryption by secret.
55
56
57 Context
58 -------
59
60 The authentication messages described here are specific to the cephx
61 auth implementation. The messages are transferred by the Messenger
62 protocol or by MAuth messages, depending on the version of the
63 messenger protocol. See also :ref:`msgr2-protocol`.
64
65 An initial (messenger) handshake negotiates an authentication method
66 to be used (cephx vs none or krb or whatever) and an assertion of what
67 entity the client or daemon is attempting to authenticate as.
68
69 Phase I: obtaining auth ticket
70 ------------------------------
71
72 The cephx exchange begins with the monitor knowing who the client
73 claims to be, and an initial cephx message from the monitor to the
74 client/principal.::
75
76 a->p :
77 CephxServerChallenge {
78 u64 server_challenge # random (by server)
79 }
80
81 The client responds by adding its own challenge, and calculating a
82 value derived from both challenges and its shared key
83 principal_secret.::
84
85 p->a :
86 CephxRequestHeader {
87 u16 CEPHX_GET_AUTH_SESSION_KEY
88 }
89 CephXAuthenticate {
90 u8 2 # 2 means nautilus+
91 u64 client_challenge # random (by client)
92 u64 key = {client_challenge ^ server_challenge}^principal_secret # (roughly)
93 blob old_ticket # old ticket, if we are reconnecting or renewing
94 u32 other_keys # bit mask of service keys we want
95 }
96
97 Prior to nautilus,::
98
99 CephXAuthenticate {
100 u8 1 # 2 means nautilus+
101 u64 client_challenge # random (by client)
102 u64 key = {client_challenge + server_challenge}^principal_secret # (roughly)
103 blob old_ticket # old ticket, if we are reconnecting or renewing
104 }
105
106 The monitor looks up principal_secret in database, and verifies the
107 key is correct. If old_ticket is present, verify it is valid, and we
108 can reuse the same global_id. (Otherwise, a new global_id is assigned
109 by the monitor.)::
110
111 a->p :
112 CephxReplyHeader {
113 u16 CEPHX_GET_AUTH_SESSION_KEY
114 s32 result (0)
115 }
116 u8 encoding_version = 1
117 u32 num_tickets ( = 1)
118 ticket_info # (N = 1)
119
120 plus (for Nautilus and later)::
121
122 u32 connection_secret_len # in bytes
123 connection_secret^session_key
124 u32 other_keys_len # bytes of other keys (encoded)
125 other_keys {
126 u8 encoding_version = 1
127 u32 num_tickets
128 service_ticket_info * N # for each service ticket
129 }
130
131 where::
132
133 ticket_info {
134 u32 service_id # CEPH_ENTITY_TYPE_AUTH
135 u8 msg_version (1)
136 {CephXServiceTicket service_ticket}^principal_secret
137 {CephxTicketBlob ticket_blob}^existing session_key # if we are renewing a ticket,
138 CephxTicketBlob ticket_blob # otherwise
139 }
140
141 service_ticket_info {
142 u32 service_id # CEPH_ENTITY_TYPE_{OSD,MDS,MGR}
143 u8 msg_version (1)
144 {CephXServiceTicket service_ticket}^principal_secret
145 CephxTicketBlob ticket_blob
146 }
147
148 CephxServiceTicket {
149 CryptoKey session_key # freshly generated (even if old_ticket is present)
150 utime_t expiration # now + auth_mon_ticket_ttl
151 }
152
153 CephxTicketBlob {
154 u64 secret_id # which service ticket encrypted this; -1 == monsecret, otherwise service's rotating key id
155 {CephXServiceTicketInfo ticket}^mon_secret
156 }
157
158 CephxServiceTicketInfo {
159 CryptoKey session_key # same session_key as above
160 AuthTicket ticket
161 }
162
163 AuthTicket {
164 EntityName name # client's identity, as proven by its possession of principal_secret
165 u64 global_id # newly assigned, or from old_ticket
166 utime_t created, renew_after, expires
167 AuthCapsInfo # what client is allowed to do
168 u32 flags = 0 # unused
169 }
170
171 So: for each ticket, principal gets a part that it decrypts with its
172 secret to get the session_key (CephxServiceTicket). And the
173 CephxTicketBlob is opaque (secured by the mon secret) but can be used
174 later to prove who we are and what we can do (see CephxAuthorizer
175 below).
176
177 For Nautilus+, we also include the service tickets.
178
179 The client can infer that the monitor is authentic because it can
180 decrypt the service_ticket with its secret (i.e., the server has its
181 secret key).
182
183
184 Phase II: Obtaining service tickets (pre-nautilus)
185 --------------------------------------------------
186
187 Now the client needs the keys used to talk to non-monitors (osd, mds,
188 mgr).::
189
190 p->a :
191 CephxRequestHeader {
192 u16 CEPHX_GET_PRINCIPAL_SESSION_KEY
193 }
194 CephxAuthorizer authorizer
195 CephxServiceTicketRequest {
196 u32 keys # bitmask of CEPH_ENTITY_TYPE_NAME (MGR, OSD, MDS, etc)
197 }
198
199 where::
200
201 CephxAuthorizer {
202 u8 AUTH_MODE_AUTHORIZER (1)
203 u64 global_id
204 u32 service_id # CEPH_ENTITY_TYPE_*
205 CephxTicketBlob auth_ticket
206 {CephxAuthorize msg}^session_key
207 }
208
209 CephxAuthorize msg {
210 u8 2
211 u64 nonce # random from client
212 bool have_challenge = false # not used here
213 u64 server_challenge_plus_one = 0 # not used here
214 }
215
216 The monitor validates the authorizer by decrypting the auth_ticket
217 with ``mon_secret`` and confirming that it says this principal is who
218 they say they are in the CephxAuthorizer fields. Note that the nonce
219 random bytes aren't used here (the field exists for Phase III below).
220
221 Assuming all is well, the authorizer can generate service tickets
222 based on the CEPH_ENTITY_TYPE_* bits in the ``keys`` bitmask.
223
224 The response looks like::
225
226 CephxResponseHeader {
227 u16 CEPHX_GET_PRINCIPAL_SESSION_KEY
228 s32 result (= 0)
229 }
230 u8 encoding_version = 1
231 u32 num_tickets
232 ticket_info * N
233
234 Where, as above,::
235
236 ticket_info {
237 u32 service_id # CEPH_ENTITY_TYPE_{OSD,MGR,MDS}
238 u8 msg_version (1)
239 {CephXServiceTicket service_ticket}^principal_secret
240 CephxTicketBlob ticket_blob
241 }
242
243 CephxServiceTicket {
244 CryptoKey session_key
245 utime_t expiration
246 }
247
248 CephxTicketBlob {
249 u64 secret_id # which version of the (rotating) service ticket encrypted this
250 {CephXServiceTicketInfo ticket}^rotating_service_secret
251 }
252
253 CephxServiceTicketInfo {
254 CryptoKey session_key
255 AuthTicket ticket
256 }
257
258 AuthTicket {
259 EntityName name
260 u64 global_id
261 utime_t created, renew_after, expires
262 AuthCapsInfo # what you are allowed to do
263 u32 flags = 0 # unused
264 }
265
266 This concludes the authentication exchange with the monitor. The
267 client or daemon now has tickets to talk to the mon and all other
268 daemons of interest.
269
270
271 Phase III: Opening a connection to a service
272 --------------------------------------------
273
274 When a connection is opened, an "authorizer" payload is sent::
275
276 p->s :
277 CephxAuthorizer {
278 u8 AUTH_MODE_AUTHORIZER (1)
279 u64 global_id
280 u32 service_id # CEPH_ENTITY_TYPE_*
281 CephxTicketBlob auth_ticket
282 {CephxAuthorize msg}^session_key
283 }
284
285 CephxAuthorize msg {
286 u8 2
287 u64 nonce # random from client
288 bool have_challenge = false
289 u64 server_challenge_plus_one = 0
290 }
291
292 Note that prior to the Luminous v12.2.6 or Mimic v13.2.2 releases, the
293 CephxAuthorize msg did not contain a challenge, and consisted only
294 of::
295
296 CephxAuthorize msg {
297 u8 1
298 u64 nonce # random from client
299 }
300
301 The server will inspect the auth_ticket CephxTicketBlob (by decrypting
302 it with its current rotating service key). If it is a pre-v12.2.6 or
303 pre-v13.2.2 client, the server immediately replies with::
304
305 s->p :
306 {CephxAuthorizeReply reply}^session_key
307
308 where::
309
310 CephxAuthorizeReply {
311 u64 nonce_plus_one
312 }
313
314 Otherwise, the server will respond with a challenge (to prevent replay
315 attacks)::
316
317 s->p :
318 {CephxAuthorizeChallenge challenge}^session_key
319
320 where::
321
322 CephxAuthorizeChallenge {
323 u64 server_challenge # random from server
324 }
325
326 The client decrypts and updates its CephxAuthorize msg accordingly,
327 resending most of the same information as before::
328
329 p->s :
330 CephxAuthorizer {
331 u8 AUTH_MODE_AUTHORIZER (1)
332 u64 global_id
333 u32 service_id # CEPH_ENTITY_TYPE_*
334 CephxTicketBlob auth_ticket
335 {CephxAuthorize msg}^session_key
336 }
337
338 where::
339
340 CephxAuthorize msg {
341 u8 2
342 u64 nonce # (new) random from client
343 bool have_challenge = true
344 u64 server_challenge_plus_one # server_challenge + 1
345 }
346
347 The server validates the ticket as before, and then also verifies the
348 msg nonce has it's challenge + 1, confirming this is a live
349 authentication attempt (not a replay).
350
351 Finally, the server responds with a reply that proves its authenticity
352 to the client. It also includes some entropy to use for encryption of
353 the session, if it is needed for the mode.::
354
355 s->p :
356 {CephxAuthorizeReply reply}^session_key
357
358 where::
359
360 CephxAuthorizeReply {
361 u64 nonce_plus_one
362 u32 connection_secret_length
363 connection secret
364 }
365
366 Prior to nautilus, there is no connection secret::
367
368 CephxAuthorizeReply {
369 u64 nonce_plus_one
370 }
371
372 The client decrypts and confirms that the server incremented nonce
373 properly and that this is thus a live authentication request and not a
374 replay.
375
376
377 Rotating service secrets
378 ------------------------
379
380 Daemons make use of a rotating secret for their tickets instead of a
381 fixed secret in order to limit the severity of a compromised daemon.
382 If a daemon's secret key is compromised by an attacker, that daemon
383 and its key can be removed from the monitor's database, but the
384 attacker may also have obtained a copy of the service secret shared by
385 all daemons. To mitigate this, service keys rotate periodically so
386 that after a period of time (auth_service_ticket_ttl) the key the
387 attacker obtained will no longer be valid.::
388
389 p->a :
390 CephxRequestHeader {
391 u16 CEPHX_GET_ROTATING_KEY
392 }
393
394 a->p :
395 CephxReplyHeader {
396 u16 CEPHX_GET_ROTATING_KEY
397 s32 result = 0
398 }
399 {CryptoKey service_key}^principal_secret
400
401 That is, the new rotating key is simply protected by the daemon's
402 rotating secret.
403
404 Note that, as an implementation detail, the services keep the current
405 key and the prior key on hand so that the can continue to validate
406 requests while the key is being rotated.