Cephx源碼淺析

  Ceph X protocol

 

Ceph的Auth認證服務由MON中的AuthMonitor模塊提供,隨MON啓動而啓動。啓動時會檢查認證服務是否爲cephx,如果是將加載admin.keyring(裏面包含客戶端服務器共享的密鑰)。

當服務器接受請求後會開啓一個會話,並初始化一個server_challenge,該值會傳輸給請求授權的客戶端。客戶端接收到server_challenge後,首先判斷該CEPHX client是否爲第一次生成,若是(starting爲true),則進入以下語句


首先解碼數據,獲取其中的server_challenge並打印。

然後驗證是否有對請求中所有操作的服務權限,即validate_ticket,ticket包含對每個服務的操作權限及handler,每個服務的handler都對應一個值,用與或算法來確定客戶端有那些服務的handler,需要那些服務的handler,缺少哪些服務的handler,每個服務 handler對應的16進制值如下表所示

如果已經有AUTH(32)的handler,缺少OSD(4)和MON(1)的handler,則開啓debug_auth後提示的信息將會是

最後返回-EAGAIN,控制權交由MonClient(voidMonClient::handle_auth(MAuthReply *m))

MONClient將根據所需的服務handler創建不同request,創建過程中會隨機生成一個client_challenge加上接收到的server_challenge,加密服務的secret到req.key中,然後通過encode加密到待傳輸給服務器的字節流中。

        判斷是否有need的服務,如果有,就創建authorizer請求Auth服務器獲取到對應服務的tickets。

其中challenge機制就是確保客戶端和服務器保存的keyring完全一致,具體流程如下:


challenge:用來驗證客戶端和服務器之間的服務(entry)的密鑰(key)是否一致,不一致就會返回-EPERM無權限的提示。key值示例:

Ticket:一個記錄,客戶用它來向服務器證明自己的身份,包括客戶標識、會話密鑰、時間戳。

 

首先,客戶端必須與認證器進行身份認證。其中將會用到共享密鑰機制,協商過程如下

 

1.獲取principal/Auth的session key

      (認證請求)

      客戶端->認證器:發送內容principal,principal_addr

       ...認證器在數據庫中查詢信息...

        認證器->客戶端:

A:由principal_secret 加密的{principal/auth session key,validaty}

B:由authsecret加密的{principal ticket, validity, principal/auth session key}

       A,B的數據結構爲:

 

認證器的pricipal_secret在auth/cephx/CephxServiceHandler.cc line 99獲取,存放在eauth.key中


然後在line 146行中加密信息並構建信息:


客戶端的principal_secret由auth/cephx/CephxClientHandler.ccline 120獲取

然後通過函數verify_service_ticket_reply(),若解析成功,則獲取相關服務的handler

 

authsecret由generate_secret(info.session_key)生成


其中服務對應的ticket通過函數build_authorizer()生成

        如果成功,客戶端上將有principal/auth的session key。下一步是請求授權使用其他一些服務

 

2. 獲取principal/service的session key

        客戶端->認證器:B,由principal/authsession key加密的{principal_addr, timestamp}

       認證器->客戶端:

                                          E:由svcsecret加密的{serviceticket}

                                          F:由principal/authsession key加密的{principal/service session key, validity}

 

  principal_addr, timestamp = authenticator

 

  其中service ticket的內容爲principalname, client network address, validity, principal/service session key

 

  注意:步驟1和步驟二有大量相似的內容:連接認證器並向其請求一個key

  做完這步後,客戶端需要有principal/servicesession key,用來後續的創建會話

 

3.在服務器打開一個會話

      客戶端->服務器:E+由principal/servicesession key加密的{principal_addr, timestamp}

服務器->客戶端:由principal/service/sessionkey加密的{timestamp+1}

 

  timestamp+1 = reply authenticator

 

        此時,服務器完全授權與客戶端。從邏輯上來說這裏主要有兩個操作。第一個操作就是從服務器獲取一個session key(步驟一和步驟二),第二個操作爲向服務器發送ticket進行認證

 

認證一次的客戶端LOG:

2017-06-07 02:13:01.623684 7fcebee53700 10 In get_auth_session_handler for protocol 0

2017-06-07 02:13:01.624411 7fcebcf03700 10 cephx server client.admin: start_session server_challenge 74bce2b1ff1d53cf

2017-06-07 02:13:01.625707 7fcebcf03700 10 cephx server client.admin: handle_request get_auth_session_key for client.admin

2017-06-07 02:13:01.625755 7fcebcf03700 20 cephx server client.admin:  checking key: req.key=9f181d3f0a65f5d6 expected_key=9f181d3f0a65f5d6

2017-06-07 02:13:01.625826 7fcebcf03700 30 cephx keyserverdata: get_service_secret service auth id 10 AQAaQjZZu5S9MhAABm5KJtxKnRixsZ59P/VyLw== expires 2017-06-07 05:48:10.851268

2017-06-07 02:13:01.625845 7fcebcf03700 10 cephx: build_service_ticket_reply encoding 1 tickets with secret AQAK/DBZI7nTCBAAR9jeJ21LPvMjpd8NsP036Q==

2017-06-07 02:13:01.625878 7fcebcf03700 10 cephx: build_service_ticket service auth secret_id 10 ticket_info.ticket.name=client.admin

2017-06-07 02:13:01.625916 7fcebcf03700 30 cephx: service_ticket_blob is 0000 : 01 0a 00 00 00 00 00 00 00 60 00 00 00 aa ed fb : .........`......

0010 : 31 c2 6a 23 5f 05 13 d8 c5 a5 d7 c2 9e bb 36 b3 : 1.j#_.........6.

0020 : b1 55 5a c3 01 7a bf 4c d7 44 75 4f 13 08 6a b8 : .UZ..z.L.DuO..j.

0030 : fb 78 28 cc c4 51 d7 32 b9 12 99 f2 56 37 f2 f8 : .x(..Q.2....V7..

0040 : 0f 3c 40 09 39 f8 3a 39 13 e0 b9 7f 6c 86 67 93 : .<@.9.:9....l.g.

0050 : 72 21 e2 25 99 52 a2 7b 76 32 3d 82 cf 5a c1 8f : r!.%.R.{v2=..Z..

0060 : 65 aa db d8 c2 82 76 20 83 0b b6 a6 37          : e.....v ....7

 

2017-06-07 02:13:01.625968 7fcebcf03700 10 cephx keyserverdata: get_caps: name=client.admin

2017-06-07 02:13:01.625970 7fcebcf03700 10 cephx keyserverdata: get_secret: num of caps=3

2017-06-07 02:13:01.629389 7fcebcf03700 10 cephx server client.admin: handle_request get_principal_session_key

2017-06-07 02:13:01.629392 7fcebcf03700 10 cephx: verify_authorizer decrypted service auth secret_id=10

2017-06-07 02:13:01.629435 7fcebcf03700 10 cephx: verify_authorizer global_id=59021

2017-06-07 02:13:01.629490 7fcebcf03700 10 cephx: verify_authorizer ok nonce 6b8b4567327b23c6 reply_bl.length()=36

2017-06-07 02:13:01.629493 7fcebcf03700 10 cephx server client.admin:  ticket_req.keys = 5

2017-06-07 02:13:01.629495 7fcebcf03700 10 cephx server client.admin:  adding key for service mon

2017-06-07 02:13:01.629498 7fcebcf03700 30 cephx keyserverdata: get_service_secret service mon id 117 AQBbTTdZKaCOJBAAQawa1qk9/bRbuxA+CgT37A== expires 2017-06-07 02:48:27.613288

2017-06-07 02:13:01.629529 7fcebcf03700 10 cephx server client.admin:  adding key for service osd

2017-06-07 02:13:01.629532 7fcebcf03700 30 cephx keyserverdata: get_service_secret service osd id 117 AQBbTTdZNg+PJBAAQgoJiMojU35X2JU2YcN6+A== expires 2017-06-07 02:48:27.613344

2017-06-07 02:13:01.629550 7fcebcf03700 10 cephx keyserverdata: get_caps: name=client.admin

2017-06-07 02:13:01.629553 7fcebcf03700 10 cephx keyserverdata: get_secret: num of caps=3

2017-06-07 02:13:01.629557 7fcebcf03700 10 cephx: build_service_ticket_reply encoding 2 tickets with secret AQAtYTdZfVFNJRAAbeqZQmRjR0vc889iri1VEA==

2017-06-07 02:13:01.629586 7fcebcf03700 10 cephx: build_service_ticket service mon secret_id 117 ticket_info.ticket.name=client.admin

2017-06-07 02:13:01.629608 7fcebcf03700 30 cephx: service_ticket_blob is 0000 : 01 75 00 00 00 00 00 00 00 60 00 00 00 f0 03 c9 : .u.......`......

0010 : e4 d4 93 c3 9d cb 14 bf 22 87 36 ea 66 f6 d4 7a : ........".6.f..z

0020 : 97 b6 06 28 8a 9e 7a 14 02 28 b7 e9 18 0d 8c 4e : ...(..z..(.....N

0030 : 13 6a ff 42 90 1b fa 94 2b 45 a2 b4 88 cd 0a 22 : .j.B....+E....."

0040 : 2a db bd 57 4f 19 89 d7 7c 97 88 f4 2d a3 80 69 : *..WO...|...-..i

0050 : b4 12 03 12 63 e6 39 c7 aa 28 e9 af ce 64 7b d9 : ....c.9..(...d{.

0060 : 1f 87 63 e9 3c 11 d8 85 d8 13 33 6b 81          : ..c.<.....3k.

 

2017-06-07 02:13:01.629705 7fcebcf03700 10 cephx: build_service_ticket service osd secret_id 117 ticket_info.ticket.name=client.admin

2017-06-07 02:13:01.629733 7fcebcf03700 30 cephx: service_ticket_blob is 0000 : 01 75 00 00 00 00 00 00 00 70 00 00 00 a9 5a f8 : .u.......p....Z.

0010 : c5 6b c2 d1 f0 03 fc 6e f6 c2 35 69 b2 8b 18 a4 : .k.....n..5i....

0020 : 17 5a dc 51 0d 22 d7 f5 bd 13 0f 72 b4 85 d3 1c : .Z.Q.".....r....

0030 : 60 e4 45 0b 4a 46 fe f3 56 5a 3a 4c db d1 98 15 : `.E.JF..VZ:L....

0040 : 87 7e 44 02 87 8b da 8c 0d e6 ca 6c 62 e2 28 b1 : .~D........lb.(.

0050 : 4a 56 11 01 bb 7d 41 6a ad 48 71 d7 b2 14 1f 3d : JV...}Aj.Hq....=

0060 : 70 bd 89 ad d0 34 e7 a4 d5 07 30 61 f9 d7 f6 5e : p....4....0a...^

0070 : 38 47 7e c0 6c 55 96 cc 3a 56 04 1d 3e          : 8G~.lU..:V..>

 

2017-06-07 02:13:02.890379 7fcebd704700 10 cephx keyserver: _check_rotating_secrets

認證一次的客戶端LOG:

2017-06-07 02:13:01.621865 7fcaa56e77c0  5 adding auth protocol: cephx

2017-06-07 02:13:01.622152 7fcaa56e77c0  2 auth: KeyRing::load: loaded key file /etc/ceph/ceph.client.admin.keyring

2017-06-07 02:13:01.625041 7fca9e5de700 10 cephx: set_have_need_key no handler for service mon

2017-06-07 02:13:01.625046 7fca9e5de700 10 cephx: set_have_need_key no handler for service osd

2017-06-07 02:13:01.625048 7fca9e5de700 10 cephx: set_have_need_key no handler for service auth

2017-06-07 02:13:01.625050 7fca9e5de700 10 cephx: validate_tickets want 37 have 0 need 37

2017-06-07 02:13:01.625063 7fca9e5de700 10 cephx client: handle_response ret = 0

2017-06-07 02:13:01.625067 7fca9e5de700 10 cephx client:  got initial server challenge 8411847458138444751

2017-06-07 02:13:01.625073 7fca9e5de700 10 cephx client: validate_tickets: want=37 need=37 have=0

2017-06-07 02:13:01.625077 7fca9e5de700 10 cephx: set_have_need_key no handler for service mon

2017-06-07 02:13:01.625079 7fca9e5de700 10 cephx: set_have_need_key no handler for service osd

2017-06-07 02:13:01.625081 7fca9e5de700 10 cephx: set_have_need_key no handler for service auth

2017-06-07 02:13:01.625082 7fca9e5de700 10 cephx: validate_tickets want 37 have 0 need 37

2017-06-07 02:13:01.625085 7fca9e5de700 10 cephx client: want=37 need=37 have=0

2017-06-07 02:13:01.625090 7fca9e5de700 10 cephx client: build_request

2017-06-07 02:13:01.625318 7fca9e5de700 10 cephx client: get auth session key: client_challenge 17269135696729659005

error reading input file openrc: (2) No such file or directory

2017-06-07 02:13:01.626499 7fca9e5de700 10 cephx client: handle_response ret = 0

2017-06-07 02:13:01.626504 7fca9e5de700 10 cephx client:  get_auth_session_key

2017-06-07 02:13:01.626512 7fca9e5de700 10 cephx: verify_service_ticket_reply got 1 keys

2017-06-07 02:13:01.626515 7fca9e5de700 10 cephx: got key for service_id auth

2017-06-07 02:13:01.626587 7fca9e5de700 10 cephx:  ticket.secret_id=10

2017-06-07 02:13:01.626593 7fca9e5de700 10 cephx: verify_service_ticket_reply service auth secret_id 10 session_key AQAtYTdZfVFNJRAAbeqZQmRjR0vc889iri1VEA== validity=43200.000000

2017-06-07 02:13:01.626615 7fca9e5de700 10 cephx: ticket expires=2017-06-07 14:13:01.626615 renew_after=2017-06-07 11:13:01.626615

2017-06-07 02:13:01.626630 7fca9e5de700 10 cephx client:  want=37 need=37 have=0

2017-06-07 02:13:01.626634 7fca9e5de700 10 cephx: set_have_need_key no handler for service mon

2017-06-07 02:13:01.626637 7fca9e5de700 10 cephx: set_have_need_key no handler for service osd

2017-06-07 02:13:01.626639 7fca9e5de700 10 cephx: validate_tickets want 37 have 32 need 5

2017-06-07 02:13:01.626644 7fca9e5de700 10 cephx client: validate_tickets: want=37 need=5 have=32

2017-06-07 02:13:01.626647 7fca9e5de700 10 cephx: set_have_need_key no handler for service mon

2017-06-07 02:13:01.626649 7fca9e5de700 10 cephx: set_have_need_key no handler for service osd

2017-06-07 02:13:01.626651 7fca9e5de700 10 cephx: validate_tickets want 37 have 32 need 5

2017-06-07 02:13:01.626653 7fca9e5de700 10 cephx client: want=37 need=5 have=32

2017-06-07 02:13:01.626656 7fca9e5de700 10 cephx client: build_request

2017-06-07 02:13:01.626658 7fca9e5de700 10 cephx client: get service keys: want=37 need=5 have=32

2017-06-07 02:13:01.631371 7fca9e5de700 10 cephx client: handle_response ret = 0

2017-06-07 02:13:01.631375 7fca9e5de700 10 cephx client:  get_principal_session_key session_key AQAtYTdZfVFNJRAAbeqZQmRjR0vc889iri1VEA==

2017-06-07 02:13:01.631394 7fca9e5de700 10 cephx: verify_service_ticket_reply got 2 keys

2017-06-07 02:13:01.631397 7fca9e5de700 10 cephx: got key for service_id mon

2017-06-07 02:13:01.631448 7fca9e5de700 10 cephx:  ticket.secret_id=117

2017-06-07 02:13:01.631453 7fca9e5de700 10 cephx: verify_service_ticket_reply service mon secret_id 117 session_key AQAtYTdZetWFJRAAwQx9u2IWLyo4vd57FK3W1g== validity=3600.000000

2017-06-07 02:13:01.631470 7fca9e5de700 10 cephx: ticket expires=2017-06-07 03:13:01.631469 renew_after=2017-06-07 02:58:01.631469

2017-06-07 02:13:01.631480 7fca9e5de700 10 cephx: got key for service_id osd

2017-06-07 02:13:01.631518 7fca9e5de700 10 cephx:  ticket.secret_id=117

2017-06-07 02:13:01.631522 7fca9e5de700 10 cephx: verify_service_ticket_reply service osd secret_id 117 session_key AQAtYTdZPS2GJRAAXf3AxV8eApYSf5FwQC/ArQ== validity=3600.000000

2017-06-07 02:13:01.631536 7fca9e5de700 10 cephx: ticket expires=2017-06-07 03:13:01.631536 renew_after=2017-06-07 02:58:01.631536

2017-06-07 02:13:01.631545 7fca9e5de700 10 cephx: validate_tickets want 37 have 37 need 0

2017-06-07 02:13:01.631604 7fca9e5de700 10 cephx: validate_tickets want 37 have 37 need 0

2017-06-07 02:13:01.631609 7fca9e5de700 20 cephx client: need_tickets: want=37 need=0 have=37

 

官方原文:

  Ceph X protocol

 

  First, the principal has to authenticate withthe authenticator. A

  shared-secret mechanism is being used, andthe negotitaion goes like this:

 

  A = Authenticator

  P = Principle

  S = Service

 

  1. Obtaining principal/auth session key

 

  (Authenticate Request)

  p->a : principal, principal_addr.  authenticate me!

 

 ...authenticator does lookup in database...

 

  a->p : A= {principal/auth session key,validity}^principal_secret (*)

         B= {principal ticket, validity,principal/auth session key}^authsecret

 

 

  [principal/auth session key, validity] =service ticket

  [principal ticket, validity, principal/authsession key] = service ticket info

 

  (*) annotation: ^ signifies 'encrypted by'

 

  At this point, if is genuine, the principalshould have the principal/auth

  session key at hand. The next step would beto request an authorization to

  use some other service:

 

  2. Obtaining principal/service session key

 

  p->a : B, {principal_addr,timestamp}^principal/auth session key. authorize

         me!

  a->p : E= {service ticket}^svcsecret

         F= {principal/service session key,validity}^principal/auth session key

 

  principal_addr, timestamp = authenticator

 

  service ticket = principal name, clientnetwork address, validity, principal/service session key

 

  Note that steps 1 and 2 are pretty much thesame thing; contacting the

  authenticator and requesting for a key.

 

  Following this the principal should have aprincipal/service session key that

  could be used later on for creating asession:

 

  3. Opening a session to a service

 

  p->s : E + {principal_addr,timestamp}^principal/service session key

  s->p :{timestamp+1}^principal/service/session key

 

  timestamp+1 = reply authenticator

 

  Now, the principal is fully authenticatedwith the service. So, logically we

  have 2 main actions here. The first one wouldbe to obtain a session key to

  the service (steps 1 and 2), and the secondone would be to authenticate with

  the service, using that ticket.

 

該內容在源碼中的/src/auth/cephx/CephxProtocol.h的註釋中

發佈了79 篇原創文章 · 獲贊 75 · 訪問量 44萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章