参考资料:官方配置文档(http://docs.openstack.org/mitaka/install-guide-rdo/common/get_started_identity.html)
openstack的组件都是通过HTTP暴露自己的API,你可以通过任意的client去访问这些API,这导致存在很大的安全隐患,所以每当有client向openstack API发送请求的时候,我们都有必要对此做一个认证。因此我们需要在用户每次请求时都需要通过一个服务来给它颁发一张通行证。这个服务就是keystone,而这个通行证就是token。因为token是通过keystone提供的一个数据块来充当有效的账户密码组合,有效期通常是几个小时或者几分钟。所以token要比传统的用户密码认证和修改环境变量更加安全有效。
简版:
详细版:
K版以后使用的都是Fernet Tokens,区别于UUID tokens只能持久化存入数据库,Fernet tokens完全不需要持久化。部署人员可以通过设置keystone.conf中的[token] provider = keystone.token.providers.fernet.Provider来启用Fernet token,这也是我们一会需要配置的参数项。Fernet tokens需要symmetric encryption keys(对称加密密钥),这些keys可以使用keystone-manage fernet_setup建立, 并且使用keystone-manage fernet_rotate周期性地轮换。这些keys必须被在一个multi-node(或者multi-region)部署中的所有Keystone nodes共享,这样就能使一个node生成的tokens可以立即被其他节点验证。
创建一个keystone数据库和一个用于初始化keystone期间的临时管理token,用于存放Keystone组件(User、Tenant、Roles等)的相关信息。
command:
mysql -u root -p123456
CREATE DATABASE keystone;
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY '123456';
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY '123456';
exit
outPut:
[root@controller my.cnf.d]# mysql -u root -p123456
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 14
Server version: 10.1.12-MariaDB MariaDB Server
Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> CREATE DATABASE keystone;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> exit
Bye
[root@controller my.cnf.d]#
生成一个用于初始化keystone期间的临时管理token:
[root@controller my.cnf.d]# openssl rand -hex 10
e84dd5a8efe2a3b84ea9
[root@controller my.cnf.d]#
1.安装openstack-keystone,httpd和mod_wsgi:
yum install openstack-keystone httpd mod_wsgi -y
2.编辑/etc/keystone/keystone.conf文件
[DEFAULT]
...
admin_token = e84dd5a8efe2a3b84ea9
[database]
...
connection = mysql+pymysql://keystone:123456@controller.example.com/keystone
[token]
...
provider = fernet
总览:
[root@controller my.cnf.d]# cat /etc/keystone/keystone.conf | grep -v ^# | grep -v ^$
[DEFAULT]
admin_token = e84dd5a8efe2a3b84ea9 #刚刚使用openssl指令生成的随机数
[assignment]
[auth]
[cache]
[catalog]
[cors]
[cors.subdomain]
[credential]
[database]
connection = mysql+pymysql://keystone:123456@controller.example.com/keystone #使用keystone账户连接到controller节点的数据库上
[domain_config]
[endpoint_filter]
[endpoint_policy]
[eventlet_server]
[eventlet_server_ssl]
[federation]
[fernet_tokens]
[identity]
[identity_mapping]
[kvs]
[ldap]
[matchmaker_redis]
[memcache]
[oauth1]
[os_inherit]
[oslo_messaging_amqp]
[oslo_messaging_notifications]
[oslo_messaging_rabbit]
[oslo_middleware]
[oslo_policy]
[paste_deploy]
[policy]
[resource]
[revoke]
[role]
[saml]
[shadow_users]
[signing]
[ssl]
[token]
provider = fernet
[tokenless_auth]
[trust]
[root@controller my.cnf.d]#
3.同步keystone数据库:
su -s /bin/sh -c "keystone-manage db_sync" keystone
我执行这条命令的时候是没有任何输出的,所以我还特意用keystone账号登陆了keystone数据库。如果没有在keystone数据库中看到任何tables的同学,可以核对一下你的connection语句有没有写对。
4.安装 Fernet keys:
Fernet tokens需要由keystone-manage fernet_setup来创建的symmetric encryption keys
keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
5.配置Apache服务
vim /etc/httpd/conf/httpd.conf
ServerName controller.example.com #指定Apache HTTP Server的hostname
创建/etc/httpd/conf.d/wsgi-keystone.conf,监听5000和35357端口,并建立两个Virtualhost-Port虚拟主机。
vim /etc/httpd/conf.d/wsgi-keystone.conf
Listen 5000
Listen 35357
<VirtualHost *:5000>
WSGIDaemonProcess keystone-public processes=5 threads=1 user=keystone group=keystone display-name=%{GROUP}
WSGIProcessGroup keystone-public
WSGIScriptAlias / /usr/bin/keystone-wsgi-public
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
ErrorLogFormat "%{cu}t %M"
ErrorLog /var/log/httpd/keystone-error.log
CustomLog /var/log/httpd/keystone-access.log combined
<Directory /usr/bin>
Require all granted
</Directory>
</VirtualHost>
<VirtualHost *:35357>
WSGIDaemonProcess keystone-admin processes=5 threads=1 user=keystone group=keystone display-name=%{GROUP}
WSGIProcessGroup keystone-admin
WSGIScriptAlias / /usr/bin/keystone-wsgi-admin
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
ErrorLogFormat "%{cu}t %M"
ErrorLog /var/log/httpd/keystone-error.log
CustomLog /var/log/httpd/keystone-access.log combined
<Directory /usr/bin>
Require all granted
</Directory>
</VirtualHost>
上面就是keystone的安装部分,下面需要介绍的是serviceProject了
keystone有个服务目录,是记录着各个服务的信息,方便以后对各个服务的定位和通信。在创建服务目录之前,因为新建的认证服务数据库并没有包含任何支持authentication 和catalog services的信息。所以我们必须使用在上文中创建的临时的authentication 。
vim ~/auth_token
export OS_TOKEN=e84dd5a8efe2a3b84ea9 #也是刚刚使用openssl指令生成的随机数
export OS_URL=http://controller.example.com:35357/v3
export OS_IDENTITY_API_VERSION=3
加载auth_token文件的环境变量:
source ~/auth_token
创建keystone服务:
[root@controller my.cnf.d]# openstack service create --name keystone --description "OpenStack Identity" identity
+-------------+----------------------------------+
| Field | Value |
+-------------+----------------------------------+
| description | OpenStack Identity |
| enabled | True |
| id | 92bca7cfb3dc473386fec8d354054089 |
| name | keystone |
| type | identity |
+-------------+----------------------------------+
keystone还管理着一个服务相关的API endpoints目录,Services使用endpoints目录确定怎么通过哪个API与其他Services通信。每一个Openstack service提供了三种形式的API endpoint:admin管理, internal内部, and public外部:
[root@controller my.cnf.d]# openstack endpoint create --region RegionOne identity public http://controller.example.com:5000/v3
+--------------+---------------------------------------+
| Field | Value |
+--------------+---------------------------------------+
| enabled | True |
| id | 00d93c78c13c407b857321a8b87d200a |
| interface | public |
| region | RegionOne |
| region_id | RegionOne |
| service_id | 92bca7cfb3dc473386fec8d354054089 |
| service_name | keystone |
| service_type | identity |
| url | http://controller.example.com:5000/v3 |
+--------------+---------------------------------------+
[root@controller my.cnf.d]# openstack endpoint create --region RegionOne identity internal http://controller.example.com:5000/v3
+--------------+---------------------------------------+
| Field | Value |
+--------------+---------------------------------------+
| enabled | True |
| id | 7df1cfd1ad984659ac8fcd6c6b5037e0 |
| interface | internal |
| region | RegionOne |
| region_id | RegionOne |
| service_id | 92bca7cfb3dc473386fec8d354054089 |
| service_name | keystone |
| service_type | identity |
| url | http://controller.example.com:5000/v3 |
+--------------+---------------------------------------+
[root@controller my.cnf.d]# openstack endpoint create --region RegionOne identity admin http://controller.example.com:35357/v3
+--------------+----------------------------------------+
| Field | Value |
+--------------+----------------------------------------+
| enabled | True |
| id | b2cb0d1963464b958eec1e97e98181c8 |
| interface | admin |
| region | RegionOne |
| region_id | RegionOne |
| service_id | 92bca7cfb3dc473386fec8d354054089 |
| service_name | keystone |
| service_type | identity |
| url | http://controller.example.com:35357/v3 |
+--------------+----------------------------------------+
[root@controller my.cnf.d]#
在此之前先举例了解一下domain,tenant(project),user和role的概念。
假如你就是一个user,你在公司A上班,你们的公司在大厦B中租了一层,假如B是一个domain,那么A就是一个tenant,你的工牌就是你的token,而你的职称就是你在公司A,也就是tenant中所扮演的role。
之前我们说过,用户如果要访问openstack API,它需要从Keystone获取token令牌。当User访问服务时,亮出自己的令牌后,相关的服务就会向Keystone求证令牌的合法性。所以,要判断一个用户归属于哪个tenant,并且在哪个tenant中充当一个什么样的role,这都是需要我们提前创建tenant,创建User,创建Role,并将User和tenant、Role关联起来的。
1.创建domain:
[root@controller my.cnf.d]# openstack domain create --description "Default Domain" default
+-------------+----------------------------------+
| Field | Value |
+-------------+----------------------------------+
| description | Default Domain |
| enabled | True |
| id | 098b1a4d36d241ed87e979ec86d32722 |
| name | default |
+-------------+----------------------------------+
[root@controller my.cnf.d]#
2.创建创建一个名为admin的project:
[root@controller my.cnf.d]# openstack project create --domain default --description "Admin Project" admin
+-------------+----------------------------------+
| Field | Value |
+-------------+----------------------------------+
| description | Admin Project |
| domain_id | 098b1a4d36d241ed87e979ec86d32722 |
| enabled | True |
| id | a406cf3ba524428bbcb853c1d6d4f2f3 |
| is_domain | False |
| name | admin |
| parent_id | 098b1a4d36d241ed87e979ec86d32722 |
+-------------+----------------------------------+
3.创建一个名为admin的user,会提示输出入密码,我的密码统一使用123456
[root@controller my.cnf.d]# openstack user create --domain default --password-prompt admin
User Password:
Repeat User Password:
+-----------+----------------------------------+
| Field | Value |
+-----------+----------------------------------+
| domain_id | 098b1a4d36d241ed87e979ec86d32722 |
| enabled | True |
| id | 1b7b714e9f3e4b68b0e6596a399b2b14 |
| name | admin |
+-----------+----------------------------------+
4.创建一个名为admin的role:
[root@controller my.cnf.d]# openstack role create admin
+-----------+----------------------------------+
| Field | Value |
+-----------+----------------------------------+
| domain_id | None |
| id | 71c19da7430a4946b369430ef9be06cb |
| name | admin |
+-----------+----------------------------------+
5.关联admin tenant、admin user到admin role中:
[root@controller my.cnf.d]# openstack role add --project admin --user admin admin
[root@controller my.cnf.d]#
所有创建的roles都必须要映射到每一个Openstack service特定的policy.json配置文件中,默认的policy会将大多数的services的管理权限授予admin角色。所以上面我们创建了default domain、admin tenant、admin user、admin role,并且将tenant和user绑定到了roles中,这样的话tenant和user就拥有了admin role的权限。
跟上述过程一样,不做重复说明
[root@controller my.cnf.d]# openstack project create --domain default --description "Service Project" service
+-------------+----------------------------------+
| Field | Value |
+-------------+----------------------------------+
| description | Service Project |
| domain_id | 098b1a4d36d241ed87e979ec86d32722 |
| enabled | True |
| id | c6fcbab4aaa8407ba02d8b5ead2063a7 |
| is_domain | False |
| name | service |
| parent_id | 098b1a4d36d241ed87e979ec86d32722 |
+-------------+----------------------------------+
[root@controller my.cnf.d]# openstack project create --domain default --description "Demo Project" demo
+-------------+----------------------------------+
| Field | Value |
+-------------+----------------------------------+
| description | Demo Project |
| domain_id | 098b1a4d36d241ed87e979ec86d32722 |
| enabled | True |
| id | ba7e2bf2e2314dcfb77782015700259c |
| is_domain | False |
| name | demo |
| parent_id | 098b1a4d36d241ed87e979ec86d32722 |
+-------------+----------------------------------+
[root@controller my.cnf.d]# openstack user create --domain default --password-prompt demo
User Password:
Repeat User Password:
+-----------+----------------------------------+
| Field | Value |
+-----------+----------------------------------+
| domain_id | 098b1a4d36d241ed87e979ec86d32722 |
| enabled | True |
| id | 1f9cc015d1b547a5bb80e14c4b9fe19f |
| name | demo |
+-----------+----------------------------------+
[root@controller my.cnf.d]# openstack role create user
+-----------+----------------------------------+
| Field | Value |
+-----------+----------------------------------+
| domain_id | None |
| id | 7cf16bd1d894487fa3cb7c07d6959760 |
| name | user |
+-----------+----------------------------------+
[root@controller my.cnf.d]# openstack role add --project demo --user demo user
[root@controller my.cnf.d]#
1.出于安全考虑,我们现在可以禁用掉临时的认证token机制。
编辑/etc/keystone/keystone-paste.ini文件,删除掉[pipeline:public_api], [pipeline:admin_api], and [pipeline:api_v3]中的admin_token_auth
删除完效果如下
[pipeline:public_api]
# The last item in this pipeline must be public_service or an equivalent
# application. It cannot be a filter.
pipeline = cors sizelimit url_normalize request_id build_auth_context token_auth json_body ec2_extension public_service
[pipeline:admin_api]
# The last item in this pipeline must be admin_service or an equivalent
# application. It cannot be a filter.
pipeline = cors sizelimit url_normalize request_id build_auth_context token_auth json_body ec2_extension s3_extension admin_service
[pipeline:api_v3]
# The last item in this pipeline must be service_v3 or an equivalent
# application. It cannot be a filter.
pipeline = cors sizelimit url_normalize request_id build_auth_context token_auth json_body ec2_extension_v3 s3_extension service_v3
unset之前设置的环境变量:
[root@controller my.cnf.d]# unset OS_TOKEN OS_URL
2.使用admin user来请求获取authentication token
[root@controller my.cnf.d]# openstack --os-auth-url http://controller.example.com:35357/v3 \
> --os-project-domain-name default --os-user-domain-name default \
> --os-project-name admin --os-username admin token issue
Password:
+------------+-------------------------------------------------------------------------+
| Field | Value |
+------------+-------------------------------------------------------------------------+
| expires | 2016-08-03T11:56:11.583616Z |
| id | gAAAAABXoc3LXAhwCZ5GOLaf0NvME7Dz- |
| | 2LwBvcM1xu28ibjOPb1Z0dyEwWqT2NPyZRABCaGTsLThMqZjAn-pXjR2tf-QZKjx1D4DsD1 |
| | aqnml0h8kFcfYCK5xKnZ2GNpbjefSmiW2QUIa6ePfl2popFtb9lsC_xjdxY_yAPoz9KtaCi |
| | -Mb0mLY0 |
| project_id | a406cf3ba524428bbcb853c1d6d4f2f3 |
| user_id | 1b7b714e9f3e4b68b0e6596a399b2b14 |
+------------+-------------------------------------------------------------------------+
因为在之前创建了admin tenant、admin user、admin role,就是说现在数据库中已经存在了admin user的相关信息,所以keystone可以在不需要使用临时token的情况下直接申请admin user的token。 —— 也就是说如果一个User希望从Keystone上申请到一个Token并以此来登陆Openstack进行操作的话,首先需要创建这个User和对应的tenant并将其加入role中。
3.使用demo user来请求获取authentication token
[root@controller my.cnf.d]# openstack --os-auth-url http://controller.example.com:5000/v3 \
> --os-project-domain-name default --os-user-domain-name default \
> --os-project-name demo --os-username demo token issue
Password:
+------------+-------------------------------------------------------------------------+
| Field | Value |
+------------+-------------------------------------------------------------------------+
| expires | 2016-08-03T11:57:14.342689Z |
| id | gAAAAABXoc4Kf9hXO3yDhvtPpczdUpe9aiRjks4mlzBz-6s5X2JzfVd4qGUL-XkHFgY0m_f |
| | 1_IKsxre5xq83D0QZ2tg2tbT7m36ak3b45gN2Gfaf1kQdXcSN4fot8yh9obnW8B6Bg_DDnK |
| | IngMIBhzrjgX75sE1im7wH3-KMq8RwJXmVJlIOY7k |
| project_id | ba7e2bf2e2314dcfb77782015700259c |
| user_id | 1f9cc015d1b547a5bb80e14c4b9fe19f |
+------------+-------------------------------------------------------------------------+
非管理员账户使用Port:5000来定位Keystone service
从上面的操作可以看出openstack认证机制是挺麻烦了,为了增加openstack client的操作效率,我们可以使用其提供的简易的环境脚本,也就是OpenRC。
1.为admin user创建OpenRC文件 :
vim ~/admin-openrc
export OS_PROJECT_DOMAIN_NAME=default
export OS_USER_DOMAIN_NAME=default
export OS_PROJECT_NAME=admin
export OS_USERNAME=admin #用户名
export OS_PASSWORD=123456 #密码
export OS_AUTH_URL=http://controller.example.com:35357/v3 #端口
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2
2.为demo user创建OpenRC文件 :
vim ~/demo-openrc
export OS_PROJECT_DOMAIN_NAME=default
export OS_USER_DOMAIN_NAME=default
export OS_PROJECT_NAME=demo
export OS_USERNAME=demo
export OS_PASSWORD=123456
export OS_AUTH_URL=http://controller.example:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2
3.使用办法:
[root@controller ~]# . admin-openrc
[root@controller ~]# openstack token issue
+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| expires | 2016-08-03T12:19:08.197634Z |
| id | gAAAAABXodMsJFu0kt8TSr6SKi-cgj0e3jIg6Z5Lva3zsTeMsT9iYCPwxR1dyIA4SIK-Q-8KtBRp4R75r7gzq5rNFLpT9vL5RfpldXEx_t_5M-TMqjuj6w1SOPVP- |
| | PVM4pYTcd9Vl2PderogQQtKzNXIwRfqXg7lRZyjDySb4HZy3fyspZVOidg |
| project_id | a406cf3ba524428bbcb853c1d6d4f2f3 |
| user_id | 1b7b714e9f3e4b68b0e6596a399b2b14 |
+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
以上就是本篇全部内容,谢谢!如果你能看到这段话的话!