分享

学习keystone心得

tallfish 发表于 2015-10-12 10:28:39 [显示全部楼层] 只看大图 回帖奖励 阅读模式 关闭右栏 2 15439
本帖最后由 tallfish 于 2015-10-12 10:29 编辑

产生背景
早期OpenStack版本中,用户、消息、API调用的认证都是放在Nova中。后来由于各种模块加入OpenStack中,安全认证涉及更加广泛,如用户登录、用户消息传递、模块消息通信,服务注册各不相同的认证。就产生了Keystone模块来处理不同的安全认证。

提供的服务
1.身份验证:负责验证从各个组件或者客户端发来的请求,有两种验证方式
2.授权:向通过验证的客户端授予token令牌,设置哪些服务可以访问
3.目录服务:将客户端提供可访问服务的URL
PSOpenStack上所有服务都在Keystone上注册,所以OpenStack的安装要从Keystone入手

Keystone概念
证书(Credentials):数据只被数据的所有者知道,数据所有者可以证明数据是自己的。
认证(Authentication):身份认证服务会确认谁正在发送服务请求。初次的身份请求将通过一系列凭证来确认用户身份,通过后,用户可以获得身份认证服务的访问令牌。
令牌(Token):访问令牌具有时间限制,持续时间,并且可以在任意时间里撤销令牌
服务(Service):一个服务提供一个或者多个访问端点,用户通过访问端点访问资源或执行可能有用的操作
访问端点(Endpoint):一个可通过网络访问的地址,通常由可访问服务的URL来描述
用户(User):个人、系统或服务的一个数字化表现形式,决定谁可以使用OpenStack。当用户发来访问请求时,Keystone将验证输入请求,用户通过Keystone发放的令牌OpenStack服务资源
租户(Tenant):用于分组或者分离的资源和/或便是对象的容器。根据不同的服务运营商,租客可以映射到一个客户、账户、组织或者项目
角色(Role):个性化的用户可执行一组特定的操作,角色包括一组权利和特权。如果用户担当某一个角色,就可以继承角色的权利和特权。
PS:当发送请求到OpenStack的服务时,必须指定一个租户。用户可以在不同的租户承担不同的角色,一个用户也可以在一个租户下承担多种角色。在Keystone服务中,发放的令牌决定了用户的角色。

身份认证
客户端:
         在Keystone的Client类初始化时,就会执行用户认证。
                   1.获取外部传入的用户名、密码、Token和租户等参数
                   2.获取用户缓存在本地的Token,如果Token不存在或过期就向Keystone服务器发送HTTP请求,获取新的Token
                   3.根据获取的Token设置用户的权限
                   4.将用户最新的Token保存在本地keyring中。
1.png


服务端:
用户名密码方式认证:在/usr/share/Keystone/Keystone-dist=paste.ini中的public_service和admin_service应用程序。有定义。主要调用token_controller对象的authenticate()方法来进行用户认证。Keystone共实现了3种认证方式
Token认证:通过已经存在的Token来认证用户的身份,一般保存在内存中。在api-paste.ini配置文件中调用authtoken过滤器中auth_token包的filter_factory方法。此方法会返回一个AuthProtocol的实例。当authtoken过滤器接收到HTTP请求时,会调用AuthProtocol实例的_call_方法:
1. 调用_remove_auth_headers方法,防止用户越权。客户端向服务端发送验证请求时,应该只提供TokenID,为了防止HTTP头部提供租户等字段谋取非法的权限,所以需要删除这些多余字段
2. 调用_validate_user_token方法,从现有的HTTP请求头收集Token,实现Token ID真实性的验证。处理UUID格式的Token使用verify_uuid_token方法:
1) 调用get_admin_token方法,获取用户TokenID。如果Token过期,则使用api-paste.ini指定的用户名和密码向Keystone服务器申请新的Token并保存在本地(内存)中
2) 调用_json_request方法向Keystone服务器发送请求,验证用户的Token。
3. 调用_build_user_headers方法,根据获取的Token信息,重新将用户、服务目录等字段加到HTTP头
本地认证:通过用户名和密码来认证用户的身份,通常用于客户端找不到用户的Token或者保存的Token失效的情况。这类用户的信息是保存在Keystone的数据库中。
外地认证:需要httpd服务
admin_token方式认证:定义在/usr/share/Keystone/Keystone-dist=paste.ini中的admin_token_auth过滤器中。对比客户端传来的Token与配置文件中的admin_token是否一致。在使用用户名密码方式验证时,一般会指定用户所属的租户,因此权限收到严格的约束。而通过admin_token方式认证,用户可以获得完全的权限。在OpenStack其他组件中,由于很多资源都必须属于某一个租户,因此只能通过Token方式认证。

认证过程
KeystonePasteDeploy配置定义在/usr/share/Keystone/Keystone-dist=paste.ini中。OpenStack服务中,通常使用composite部件来定义服务的入口。以下两个服务都定义了3url映射,即/v2.0/v3.0/。一般使用的是/v2.0映射
         5000监听端口-公共服务的入口,公共服务用于实现用户名密码方式的认证
         3.png
         2.png

         sizelimit:判断request的大小
url_nomalize:处理request中的url,如删去url最后的’/’
build_auth_context:生成auth context
token_auth:在request.environ字典中,加入token信息
xml_body:将reques格式从xml转化为json
json_body:将json格式的request进行解析
         user_crud_extension[过滤器]:添加用户密码修改的url映射
         public_service[应用程序]:添加用户密码方式认证,查询用户所属租户的url映射

         35357监听端口-管理服务的入口,管理服务实现对Keystone各类资源的增、删、改、查
         5.png
         4.png

sizelimit:判断request的大小
url_nomalize:处理request中的url,如删去url最后的’/’
build_auth_context:生成auth context
token_auth:在request.environ字典中,加入token信息
xml_body:将reques格式从xml转化为json
json_body:将json格式的request进行解析
         crud_extension[过滤器]:添加对用户、租户、角色、服务和端点等资源管理的url映射
         admin_service[应用程序]:添加用户名密码方式认证,用户、租户信息查询的url映射

以上这些类的方法都调用mapper对象的connect方法来添加url映射。调用connect方法时,须指定以下4个参数:
         1.HTTP请求的url格式,例 创建租户请求对应的URL '/tenant'
2.处理请求的Controller对象,例 处理与租户资源有关的HTTP请求的方法为tenant_controller对象的create_tenant方法controller=tenant_controller
         3.处理请求的方法,该方法是指Controller对象中定义的方法action='create_tenant'
         4.请求的条件,通常指定HTTP请求的方法,有GETPOSTPUTDELETEPATCHconditions=dict(method=['POST'])
                   POST(创建):创建一个子资源,POST方法不是冥等的,多次执行,将导致多条相同的相同的用户被创建
                   PUT(更新或者创建):是冥等的,创建一个URL已知的资源,或者对已知资源进行完全替换
                   PATCH:是对PUT方法的补充,用来对已知资源进行局部更新
                   DELETE(删除):是冥等的
                   GET(查看):是冥等的,可以被浏览器缓存,长度有所限制(2048个字符),请求的数据只能包含ASCII字符
         PS:冥等:不管进行多少次操作,结果都是一样的


验证Keystone API
-i/--include 输出时包括protocol头信息
-H/--header <line>自定义头信息传递给服务器
-X/--request <command>指定什么命令
-d/--data <data>   HTTP POST方式传送数据
List:
List/Show/Update/Deleteservices:
curl-s -H "X-Auth-Token:$OS_TOKEN" http://controller:5000/v3/services | python -mjson.tool
curl-s -H "X-Auth-Token:$OS_TOKEN" http://controller:5000/v3/services/{service_id} | python -mjson.tool
curl -s -X PATCH -H"X-Auth-Token:$OS_TOKEN" -H "Content-Type:application/json" -d '{"type":"volume"}' http://controller:5000/v3/services/{service_id} | python -mjson.tool
curl-s -X DELETE -H "X-Auth-Token:$OS_TOKEN" http://controller:5000/v3/services/{service_id} | python -mjson.tool
List endpoints:
curl-s -H "X-Auth-Token:$OS_TOKEN" http://controller:5000/v3/endpoints |python -mjson.tool
curl-s -H "X-Auth-Token:$user_token"http://controller:35357/v2.0/tokens/$user_token/endpoints | python -mjson.tool
Listprojects(tenants):
curl-s -H "X-Auth-Token:$OS_TOKEN" http://controller:5000/v3/projects |python -mjson.tool
curl-s -H "X-Auth-Token:$user_token" http://controller:5000/v2.0/tenants| python -mjson.tool
List users:
curl-s -H "X-Auth-Token:$OS_TOKEN" http://controller:5000/v3/users | python -mjson.tool
List the role a userhas been granted on a tenant:
curl-s -H "X-Auth-Token:$user_token"http://controller:35357/v2.0/tenants/$tenant_id/users/$user_id/roles
List version:
curl-s http://0.0.0.0:5000 | python -mjson.tool
curl-s http://0.0.0.0:5000/v2.0/ | python -mjson.tool
curl-s http://0.0.0.0:35357 | python -mjson.tool
curl-s http://0.0.0.0:35357/v2.0/ | python -mjson.tool
List api-extensions:
curl-s http://0.0.0.0:5000/v2.0/extensions | python -mjson.tool
curl-s http://controller:5000/v2.0/extensions | python -mjson.tool
Token
Get X-Auth-Token foran access token:
curl-s -H "Content-type: application/json" -d'{"auth":{"tenantName": "admin", "passwordCredentials":{"username": "admin", "password":"redhat"}}}' http://controller:35357/v2.0/tokens | python -mjson.tool
Get X- Subject -Tokenfor an access token:
curl-i -H "Content-Type:application/json" -d '{ "auth":{"identity":{"methods":["token"],"token":{"id":"$user_token "}}}}' http://controller:5000/v3/auth/tokens ; echo
Validate a token:
curl-s -H "X-Auth-Token:$user_token" -H "X-Subject-Token:$sbj_token"http://controller:35357/v2.0/tokens/$user_token | python -mjson.tool
project
Disable a project:
curl-s -X PATCH -H "X-Auth-Token:$OS_TOKEN"" -H "Content-Type:application/json" -d '{"project": {"enabled": false}}'http://controller:5000/v3/projects/$PROJECT_ID | python -mjson.tool
Enable a project:
curl-s -X PATCH -H "X-Auth-Token:$OS_TOKEN"" -H "Content-Type:application/json" -d '{"project": {"enabled": ture}}'http://controller:5000/v3/projects/$PROJECT_ID | python -mjson.tool
Create group roleassignment on project:
Curl –s –X PUT –H "X-Auth-Token:$OS_TOKEN"http://controller:5000/v3/projects/$PROJECT_ID/groups/$GROUP_ID/roles/$ROLE_ID| python -mjson.tool
User
Create a user:
curl–s -H "X-Auth-Token:$OS_TOKEN" -H "Content-Type:application/json" -d '{"user": {"name":"newuser", "password": "redhat"}}' http://controller:5000/v3/users| python -mjson.tool
Show details for auser:
curl-s -H "X-Auth-Token:$OS_TOKEN"http://controller:5000/v3/users/$USER_ID | python -mjson.tool
Change password(thiscan be done as the user):
curl-s -H "X-Auth-Token: $OS_TOKEN" -H "Content-Type: application/json"-d '{ "user": {"password": "'$NEW_PASS'","original_password": "'$ORIG_PASS'"} }'http://controller:5000/v3/users/$USER_ID/password
Reset password(thisrequires admin):
curl-s -X PATCH -H "X-Auth-Token: $OS_TOKEN" -H "Content-Type: application/json"-d '{ "user": {"password": "'$NEW_PASS'"} }'http://controller:5000/v3/users/$USER_ID | python -mjson.tool


客户端发送HTTP请求流程
1.创建Keystone Client对象。在KeystoneClient对象初始化时,会调用HTTPClient对象的authenticate方法进行用户认证
2.调用Keystone Client对象的tenant_manager成员变量的get方法
Keystone Client对象的tenant_manager成员变量是一个TenantManager对象,TenantManager类继承自ManagerWithFind类,ManagerWithFind类继承自Manager类。Manager类的get方法调用了HTTPClient对象的get方法。
3. HTTPClient对象的get方法实现了发送HTTPGET请求的底层功能
6.png


Keystone访问其他服务流程
1.创建Keystone clien对象。通过Keystone Client对象向Keystone服务器发送认证请求,申请用户Token。在用户Token中,可以提取Token ID和服务目录
2.创建需要访问的OpenStack组件的相应Client对象。根据Token中的服务目录,设置Client对象的endpoint等信息
3.当Client对象向OpenStack服务发送HTTP请求时,OpenStack服务会通过auth_token过滤器向Keystone服务器发送认证请求。如果认证成功,OpenStack再调用相应的方法处理用户请求

例:创建虚拟机的流程(含有Neutron
7.png



已有(2)人评论

跳转到指定楼层
a2901153 发表于 2015-10-13 10:23:07
正在学习,攒分中
回复

使用道具 举报

Hemona 发表于 2016-7-6 18:09:51
keystone真的是前一发动全身
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条