天天看點

OpenStack Mitaka 版本中 keystone 的概念、概念之間的關系、以及keystone身份認證的基本過程描述

       本文包含以下三個方面的内容。

       1. keystone資料模型的術語解釋

       2. keystone的openstack指令解析

       3. keystone的主要工作過程

       1. keystone資料模型中的一些術語

       在keystone中定義的數學模型,其核心思想是定義了有哪些使用者(user/group)、這些使用者能使用哪些範圍内的資源(domain/project)、這些使用者可以怎樣使用這些資源(role)。

       使用者相關術語:user & group

       user是擁有賬号的獨立個體,group表示一組有着共同點的user,這裡的共同點是指對某個資源具有相同的權限。

       資源相關術語:domain & project

       project也是以前版本中的tenant,它包含了一個資源集合,這裡的資源包括image、server、network等等(注意每一個資源都屬于某個service,例如一個image資源肯定屬于glance service,server資源也就是虛拟機屬于nova service);

       domain是project、user和group的一個大的容器,包含了project集合和使用者集合;domain可以看做一個命名空間,全局唯一。

       權限賦予相關術語:role & role assignment

       role定義了role或者group可獲得的操作權限;當role指派給一個user或group時,必須同時指定這個權限作用于哪個資源;role可以分為project級别和domain級别;role常見值為admin和user,你也可以在各個服務的policy.js中自定義一個新的權限。我會在之後解釋rule的部分解讀部分/etc/keystone/policy.js的内容;

       role assignment 可看做一個三元組<role,resource,identity>,将使用者與特定資源進行映射,并定義了這個映射的權限;舉個例子,一個三元組<admin,project1, user1> 表達的意思是user1對project1内資源的操作權限為admin,這個權限賦予中的role是project級别的;換個例子,一個三元組<user, default domain, group1={u1,u2,u3}>所表達的意思是一組使用者u1,u2,u3對default domain中的所有資源具備user權限。

       使用者-資源-權限之間關系的補充說明

       定義一個user或group時,必須指定其所屬domain,user和group的命名隻需要保證在所屬domain内唯一即可;

       user或group在進行權限賦予時,是可以賦予其他domain内資源的操作權限;

       在定義project時,必須指明其所屬domain,否則預設為default domain,一個project的命名在domain内部唯一;

       我們在建立資源(image, server, network等)時,必須指明其所屬的project與domain;

       role的命名必須全局唯一。

       資料模型中的其他術語-TOKEN

      Token:user在送出請求的同時送出使用者名和密碼用于認證,身份認證通過後keystone就會傳回給使用者一個具有有效期的token(一長串字元串),在使用者本地緩存這個token,在有效期範圍内,使用者可以通過token直接實作對授權資源的單點登陸;token有4種:UUID、PKI、PKIZ 和 fernet token;下面簡單介紹一下這四種token,目前Mitaka官網安裝說明中配置的是fernet token;

        UUID token:每個服務API收到帶有UUID token的請求時,必須拿着這個token到keystone進行驗證token的合法性,驗證通過之後才能響應使用者請求;随着叢集規模的擴大,Keystone 需處理大量驗證UUID token 的請求,在高并發下容易出現性能問題;

       PKI token:攜帶更多使用者資訊并附上了數字簽名,服務API收到PKI token時無需再去keystone驗證;但是 PKI token所攜帶可能随着OpenStack Region增多而變得非常長,很容易超出 HTTP Server 允許的最大 HTTP Header(預設為 8 KB),導緻 HTTP 請求失敗;

       PKIZ token:PKI token 的壓縮版,但壓縮效果有限,無法良好的處理 token 長度過大問題;

      Fernet token:攜帶了少量的使用者資訊,大小約為 255 Byte,采用了對稱加密,無需存于資料庫中;

      前三種 token 都會持久性存于資料庫,與日俱增積累的大量 token 引起資料庫性能下降,是以使用者需經常清理資料庫的 token;Fernet token沒有這樣的需要。

       token 還有scope的概念,表明這個token作用在什麼範圍内的資源,例如某個project範圍或者某個domain範圍,token隻能用于認證使用者對指定範圍内資源的操作;

       資料模型中的其他術語-Rule

       Rule:在/etc/keystone/policy.js中定義了各種操作權限使用規則,指明一個操作必須賦予特定權限才可以執行;例如在policy.js中有兩行代碼是"admin_required": "role:admin or is_admin:1"和"identity:delete_user": "rule:admin_required",表明了這樣一個規則:隻有擁有admin權限的使用者才可以執行删除user的操作;

       資料模型中的其他術語-Region

        Region指明OpenStack部署的地理位置,比如OpenStack部署成混合雲模式,跨多個IDC,例如使用者租用阿裡雲上的虛拟機時,可以指明虛拟機部署在深圳或者北京的IDC;每個region應該擁有一整套獨立資源,region之間可以共享同一個Keystone和Horizon;

       一個形象的例子

       一個連鎖健身館(domain),包含了多個健身服務(service),例如常溫瑜伽、高溫瑜伽、器械健身、健美操、私人健身等;健身館可以随時create service,例如引進拳擊項目;

       健身房提供了多種健身項目(project),例如肌肉增強項目包含了器械健身課程和私人健身課程;減肥項目包含健美操課程、器械健身課程;形體項目包含了常溫瑜伽課程和健美操課程;

       健身房面向不同的閱聽人出售個體(user)卡、情侶(group)卡,或者家庭(group)卡;使用者來健身房購買健身卡時需要填寫申請表格并付費,并獲得了相應的健身卡(token),下次使用者來健身時,隻需要出示健身卡即可;健身卡有時效(類似token有效期),例如半年卡到期後就失效不能再進入健身房健身;

       每一種健身卡都有多個級别(role),如普通級别、黃金級别或者鑽石級别;舉個例子,普通卡每周隻允許來健身2次、銀卡每周允許健身4次、鑽石級别則不限次;

       每一種健身卡包含的健身項目不一樣,例如全能卡可以參加館内所有的健身項目、減肥卡隻可以參加減肥項目,等等;

       根據上述的規定細則,健身中心開始售賣健身卡:一個user購買了個人鑽石級别的全能一年期健身卡,則表示這個user可以在一年有效期内拿着token(健身卡)無限次參與館内所有健身項目;一對情侶購買了黃金級别的減肥半年情侶卡,則這對情侶各自可以在半年内每周最多參與4次減肥項目;健身卡的一次交易,就相當于一次權限賦予(role assignment),情侶購買黃金級别的減肥半年情侶卡就對應一個三元組<黃金級别,減肥項目,這對情侶>,賦予了這對情侶對減肥項目的黃金級别,權限有效期半年;

       上面我們說了,domain是一個連鎖健身館,它在不同城市都有連鎖店,例如上海region、北京region等等;使用者購買卡的時候,也是要指定去哪個region的健身館健身;

       那麼我們在上面有說明一句話“user或group在進行權限賦予時,是可以賦予其他domain内資源的操作權限”,這句話怎麼去了解呢?比如健身房為了促銷,在使用者購買健身卡時,贈送了使用者50元超市卡,使用者可以拿着這超市卡去指定超市(另外一個domain)購物;

       類似的例子還有很多,網上流傳最多的就是旅館的例子,我還可以套用到圖書館、體育館、大學等領域。

       2. keystone的openstack指令解析

       在官網上驗證keystone項目是否安裝成功時,執行了很多openstack指令:

       Create the service entity and API endpoints: http://docs.openstack.org/mitaka/install-guide-ubuntu/keystone-services.html

       Create a domain, projects, users and roles: http://docs.openstack.org/mitaka/install-guide-ubuntu/keystone-users.html

       也可參見我上一篇文章keystone安裝過程。

       根據我們在上面對keystone資料模型的了解,我們在這裡依次回顧一下keytone中的openstack指令。

       openstack service create  --name keystone --description "OpenStack Identity" identity

       這是安裝配置完keystone之後執行的第一個openstack指令,這個指令意思是将identity服務注冊進openstack,我們在安裝其他項目時,都需要在安裝完畢後建立相應的服務。openstack service create指令帶有的參數如下所示。衆多參數中最重要的就是type,type類型決定了這個服務對應了什麼功能,上面這個指令的type是identity,表明這個服務是認證服務。再比如如果type是image,則服務是鏡像服務glance,type是compute則表示服務是計算服務nova,等等等等;下面給出這個指令的使用格式:

OpenStack Mitaka 版本中 keystone 的概念、概念之間的關系、以及keystone身份認證的基本過程描述

       接下來連續三個建立API endpoint的指令,分别對應3個接口類型:admin、public和internal,注意URL的端口号也有差別;

       openstack endpoint create --region RegionOne  identity public http://controller:5000/v3

       openstack endpoint create --region RegionOne  identity internal http://controller:5000/v3

       openstack endpoint create --region RegionOne  identity admin http://controller:35357/v3

       在RESTful架構中,每個endpoint URL代表一種資源。        在上面三個類型的URL中,admin API的URL與其他兩種端口号都不一樣。它表示隻有admin權限的使用者才可以通過這個URL來通路認證服務,一般這樣的使用者都是系統管理者,系統管理者可以通過這個URL進行對user和group的修改、建立和删除操作。        internal API是提供給OpenStack内部進行通路的網址,在這裡則是表示其他service(nova、glance等)要通路keystone服務,要使用這個URL。        public API則是外部可見的URL,user和group可以通過這個API來對自己有權限的資源進行操作;在這裡, user和group要通路keystone進行認證服務,就是使用這個URL來實作的。        下面給出endpoint建立指令的使用格式:

OpenStack Mitaka 版本中 keystone 的概念、概念之間的關系、以及keystone身份認證的基本過程描述

       可以看到,這個指令最重要的部分就是要表明endpoint類型以及綁定的是什麼服務。

       接下來我們要建立一個default domain。在Liberty版本中不需要有這個操作,default domain預設存在。在Mitaka版本中則需要顯示的進行這個default domain的建立。

       openstack domain create --description "Default Domain" default

       下面給出domain create指令的使用格式:

OpenStack Mitaka 版本中 keystone 的概念、概念之間的關系、以及keystone身份認證的基本過程描述

       可以看出,這個指令唯一必要的參數就是domain命名,務必保證全局唯一。

       建立admin project,指明這個project隸屬于default domain,名稱為admin(不要将這個admin與admin role混淆,這個admin是一個自定義的名稱,在這裡需要吐槽一下,官網安裝執行個體中的命名非常不人性化,各種同名但不同意義的變量)

       openstack project create --domain default  --description "Admin Project" admin

       project建立指令的使用格式如下:

OpenStack Mitaka 版本中 keystone 的概念、概念之間的關系、以及keystone身份認證的基本過程描述

       這個指令的必要參數就是project-name,如果沒有指明domain的話預設配置設定給default domain;命名時注意domain内部唯一;

       建立 admin user,注意這裡admin表示user名稱叫admin,不是role為admin!!!

       openstack user create --domain default \  --password-prompt admin

       user建立指令使用格式如下:

OpenStack Mitaka 版本中 keystone 的概念、概念之間的關系、以及keystone身份認證的基本過程描述

       這個指令唯一必須的參數是user name,如果不指定domain則為default domain,保證user name在domain内唯一;

       建立admin role

       openstack role create admin

       建立角色的指令格式如下:

OpenStack Mitaka 版本中 keystone 的概念、概念之間的關系、以及keystone身份認證的基本過程描述

       注意這個role的名稱必須是在keystone的policy.js下面定義過的,随便亂寫個名字不會産生意義;

       最後也是最重要的,就是role assignment 指令

        openstack role add --project admin --user admin admin

       這個指令但看字面意義超級拗口,将admin project的admin操作權限賦予admin user。

       下面是這個指令的使用格式:

OpenStack Mitaka 版本中 keystone 的概念、概念之間的關系、以及keystone身份認證的基本過程描述

       我們看到這個指令唯一強制的參數是role,這裡我就不能了解了,如果不寫明user/group的話,怎麼會知道将role賦予誰呢?這個問題先放在這裡。我覺得這個指令必須給出的幾個參數是role,project和user/group,組成完整的role assignment三元組,這樣才有意義;

       完成上述指令之後,可能大家覺得建立service和建立domain、user、project之間沒有關系。這是因為目前為止我們的安裝隻進行到keystone的原因。在後續文章中,我們可以看到,我們會為glance鏡像服務建立一個個具體的image,而這些image在建立的時候除了需要指明service是glance服務之外,還需要指明image屬于哪個domain的哪個project;

      在這裡總結一下上述指令。通過上述指令,我們建立了一個keystone服務和它的3個提供給外界通路的URL;建立了一個default domain,這個domain内目前有一個名為admin的project和名為admin的user,我們還建立了一個admin role,進行了一次role assignment操作,将admin project 的admin權限賦予admin user;

      官網上面還有demo project、user role 等建立操作,這些可以基于上述知識自行了解。

       3. keystone的主要工作過程

       keystone的工作内容就是驗證,根據不同的token類型,驗證的過程也不一樣,網上也有人畫出了比較專業的流程圖,在這裡僅簡單描述一些。

       keystone驗證過程-UUID

       - token 生成過程:使用者發送使用者名/密碼、token申請請求至keystone endpoints之一(根據使用者角色);keystone驗證使用者合法性後,生成token和uuid并存儲到資料庫中,将uuid傳回給使用者;使用者在本地緩存uuid

       - 使用者請求過程:使用者請求某個服務進行某項操作,調用相應的API,并附上本地緩存uuid;服務向keystone發送uuid,keystone檢查uuid的合法性,确認有效後傳回至相應服務;如果uuid非法,則删除過期token,拒絕請求;

       keystone驗證過程-PKI/PKIZ

       - token生成過程:使用者發送使用者名/密碼、token申請請求至keystone endpoints之一(根據使用者角色);keystone作為CA,隻管自己的專用私鑰去簽發token,形成CMS格式的token(服務越多越長,多數超過1600位元組,PKIZ類型token的話會壓縮一下),同時維護一份CRL (Certificate Revocation List);keystone将token傳回給使用者,使用者緩存到本地;注意PKI/PKIZ隻是簽名,沒有加密,很容易被抓包抓到,最好做一下HTTPS

       - 使用者請求過程:使用者請求某個服務進行某項操作,調用相應的API,并附上本地緩存CMS格式token;每個服務擁有keystone所有家當的一份拷貝(包括簽發證書、CA憑證和CRL),直接在服務本地利用公鑰去驗證簽名是否正确(不是驗證token本身);驗證正确則響應服務;

       keystone驗證過程-fernet

       - token生成過程:使用者發送使用者名/密碼、token申請請求至keystone endpoints之一(根據使用者角色);keystone采用對稱加密技術傳回加密token,該token不會存儲到資料庫中;使用者緩存token到本地;

       - 使用者請求過程:使用者請求某個服務進行某項操作,調用相應的API,并附上本地緩存的加密token;服務将加密token發送給keystone要求進行驗證;keystone驗證通過并傳回使用者資訊(user、project、role);服務根據這些資訊決定是否響應使用者請求。

繼續閱讀