Using Keystone as OAuth 2.0 Authorization Server for Tacker APIs¶
Note
The content of this document has been confirmed to work using Tacker and Keystone 2024.1 Caracal.
Overview¶
The third-party clients can access the NFV orchestration APIs that is provided by Tacker via the Client Credentials Grant flow of RFC6749 OAuth 2.0 Authorization Framework. OAuth 2.0 Client Credentials Grant flow is prescribed in the API specification of ETSI NFV-SOL013 v3.4.1. And Tacker implements OAuth 2.0 Mutual-TLS Client Authentication based on RFC8705. Tacker uses the Keystonemiddleware to support OAuth 2.0 Client Credentials Grant and OAuth 2.0 Mutual-TLS Client Authentication through the Keystone identity server.
Preparations¶
According to RFC6749, HTTPS must be enabled in the authorization server since requests include sensitive information in plain text, so it should enable Tacker to support HTTPS protocols. You can reference this guide to enable HTTPS for Tacker APIs Configuring HTTPS/mTLS for Tacker APIs. For keystone server, reference the Configure HTTPS in Identity Service.
Note
Based on the server environment, this command may have to be run to enable SSL module in apache2 service when setting up HTTPS protocol for keystone server.
$ sudo a2enmod ssl
Note
If the Keystone identity server supports the HTTPS protocol, set the CA file and HTTPS auth url for Keystone Server in tacker.conf.
[keystone_authtoken]
#cafile = /opt/stack/data/ca-bundle.pem
cafile = /opt/stack/certs/multi_ca.pem
#auth_url = http://$keystone_host_name/identity
auth_url = https://$keystone_host_name/identity
And if CA files that signed certificates used by the Keystone identity server
and the Tacker server are not the same, it is necessary to add CA file for
Keystone server into multi_ca.pem
.
$ cat keystone.host.crt >> multi_ca.pem
Guide for OAuth 2.0 Client Credentials Grant¶
To use OAuth 2.0 Client Credentials Grant for Tacker APIs, it is necessary to
confirm that OAuth 2.0 client credentials is enabled in the Keystone
identity server. In this example, $keystone_host_name
is the domain name
used by the Keystone identity server, and the domain name used by the Tacker
server is $tacker_host_name
.
To use OAuth 2.0 Client Credentials Grant in Tacker, you should configure the Tacker server and the Keystonemiddleware in the following steps.
Enable Client Credentials Grant¶
To handle API requests using OAuth 2.0 Client Credentials Grant, you have to configure the Keystonemiddleware which intercepts API calls from clients and verifies a client’s identity, see Middleware Architecture.
Add
keystonemiddleware.oauth2_token:filter_factory
to the configuration fileapi-paste.ini
to enable OAuth 2.0 Client Credentials Grant.$ vi /etc/tacker/api-paste.ini [composite:tackerapi_v1_0] #keystone = request_id catch_errors authtoken keystonecontext extensions tackerapiapp_v1_0 keystone = request_id catch_errors oauth2token keystonecontext extensions tackerapiapp_v1_0 [composite:vnfpkgmapi_v1] #keystone = request_id catch_errors authtoken keystonecontext vnfpkgmapp_v1 keystone = request_id catch_errors oauth2token keystonecontext vnfpkgmapp_v1 [composite:vnflcm_v1] #keystone = request_id catch_errors authtoken keystonecontext vnflcmaapp_v1 keystone = request_id catch_errors oauth2token keystonecontext vnflcmaapp_v1 [composite:vnflcm_v2] #keystone = request_id catch_errors authtoken keystonecontext vnflcmaapp_v2 keystone = request_id catch_errors oauth2token keystonecontext vnflcmaapp_v2 [composite:vnfpm_v2] #keystone = request_id catch_errors authtoken keystonecontext vnfpmaapp_v2 keystone = request_id catch_errors oauth2token keystonecontext vnfpmaapp_v2 [composite:vnflcm_versions] #keystone = request_id catch_errors authtoken keystonecontext vnflcm_api_versions keystone = request_id catch_errors oauth2token keystonecontext vnflcm_api_versions [composite:vnffm_v1] #keystone = request_id catch_errors authtoken keystonecontext vnffmaapp_v1 keystone = request_id catch_errors oauth2token keystonecontext vnffmaapp_v1 [filter:oauth2token] paste.filter_factory = keystonemiddleware.oauth2_token:filter_factory
Restart tacker service so that the modified configuration information takes effect.
$ sudo systemctl restart devstack@tacker
Verify Access to Tacker APIs¶
Access to the Tacker APIs with the OAuth 2.0 access token to verify that OAuth 2.0 Client Credentials Grant flow works correctly.
Obtain client credentials with application credentials API
See the OAuth 2.0 usage guide and Application Credentials API for information about obtaining client credentials ($oauth2_client_id and $oauth2_client_secret).
Obtain an access token from the OAuth 2.0 Access Token API
$ curl -i -u "$oauth2_client_id:$oauth2_client_secret" \ -X POST https://$keystone_host_name/identity/v3/OS-OAUTH2/token \ -H "application/x-www-form-urlencoded" \ -d "grant_type=client_credentials" \ --cacert multi_ca.pem HTTP/1.1 200 OK Date: Wed, 22 May 2024 05:55:21 GMT Server: Apache/2.4.52 (Ubuntu) Content-Type: application/json Content-Length: 264 Vary: X-Auth-Token x-openstack-request-id: req-269c250e-5fc8-439b-9d40-8ba6c139a245 Connection: close {"access_token":"$oauth2_access_token","expires_in":3600,"token_type":"Bearer"}
Access the OpenStack Tacker APIs with the OAuth 2.0 access token to confirm that OAuth 2.0 Client Credentials Grant flow works correctly
$ curl -i -X GET "https://$tacker_host_name:9890/v1.0/vims" \ -H "Authorization: Bearer $oauth2_access_token" \ --cacert multi_ca.pem HTTP/1.1 200 OK Content-Type: application/json Content-Length: 736 X-Openstack-Request-Id: req-75594c93-dc19-49cd-9da5-6f8e9b7a7a03 Date: Wed, 22 May 2024 05:59:43 GMT {"vims": [{"id": "84517803-0e84-401e-ad75-8f6b8ab0a3b6", "type": "openstack", "tenant_id": "d53a4605d776472d846aed35735d3494", "name": "openstack-admin-vim", "description": "", "placement_attr": {"regions": ["RegionOne"]}, "is_default": true, "created_at": "2024-06-03 14:29:08", "updated_at": null, "extra": {}, "auth_url": "https://$keystone_host_name/identity/v3", "vim_project": {"name": "nfv", "project_domain_name": "Default"}, "auth_cred": {"username": "nfv_user", "user_domain_name": "Default", "cert_verify": "False", "project_id": null, "project_name": "nfv", "project_domain_name": "Default", "auth_url": "https://$keystone_host_name/identity/v3", "key_type": "barbican_key", "secret_uuid": "***", "password": "***"}, "status": "ACTIVE"}]} $ curl -i -X GET "https://$tacker_host_name:9890/vnfpkgm/v1/vnf_packages" \ -H "Authorization: Bearer $oauth2_access_token" \ --cacert multi_ca.pem HTTP/1.1 200 OK Content-Type: application/json Content-Length: 498 X-Openstack-Request-Id: req-3f5ebaad-6f66-43b7-bd0f-917a54558918 Date: Wed, 22 May 2024 06:06:24 GMT [{"id": "6b02a067-848f-418b-add1-e9c020239b31", "onboardingState": "ONBOARDED", "operationalState": "ENABLED", "usageState": "IN_USE", "vnfProductName": "Sample VNF", "vnfSoftwareVersion": "1.0", "vnfdId": "b1bb0ce7-ebca-4fa7-95ed-4840d70a1177", "vnfdVersion": "1.0", "vnfProvider": "Company", "_links": {"self": {"href": "/vnfpkgm/v1/vnf_packages/6b02a067-848f-418b-add1-e9c020239b31"}, "packageContent": {"href": "/vnfpkgm/v1/vnf_packages/6b02a067-848f-418b-add1-e9c020239b31/package_content"}}}] $ curl -i -X GET "https://$tacker_host_name:9890/vnflcm/v1/vnf_instances" \ -H "Authorization: Bearer $oauth2_access_token" \ --cacert multi_ca.pem HTTP/1.1 200 OK Content-Type: application/json Content-Length: 603 X-Openstack-Request-Id: req-ceeb935f-e4af-4f46-bfa9-4fb3e83a4664 Date: Wed, 22 May 2024 06:24:33 GMT [{"id": "fd25f4ca-27ac-423b-afcf-640a64544e61", "vnfInstanceName": "vnf-fd25f4ca-27ac-423b-afcf-640a64544e61", "instantiationState": "NOT_INSTANTIATED", "vnfdId": "b1bb0ce7-ebca-4fa7-95ed-4840d70a1177", "vnfProvider": "Company", "vnfProductName": "Sample VNF", "vnfSoftwareVersion": "1.0", "vnfdVersion": "1.0", "vnfPkgId": "6b02a067-848f-418b-add1-e9c020239b31", "_links": {"self": {"href": "https://$tacker_host_name:9890/vnflcm/v1/vnf_instances/fd25f4ca-27ac-423b-afcf-640a64544e61"}, "instantiate": {"href": "https://$tacker_host_name:9890/vnflcm/v1/vnf_instances/fd25f4ca-27ac-423b-afcf-640a64544e61/instantiate"}}}]
Confirm that a client can not access the Tacker APIs with an X-Auth-Token.
$ curl -i -X POST https://$keystone_host_name/identity/v3/auth/tokens?nocatalog \ -d '{"auth":{"identity":{"methods":["password"],"password": {"user":{"domain":{"name":"$userDomainName"},"name":"$userName","password":"$password"}}},"scope":{"project":{"domain":{"name":"$projectDomainName"},"name":"$projectName"}}}}' \ -H 'Content-type:application/json' \ --cacert multi_ca.pem HTTP/1.1 201 CREATED Date: Wed, 05 Jun 2024 06:48:33 GMT Server: Apache/2.4.52 (Ubuntu) Content-Type: application/json Content-Length: 712 X-Subject-Token: $x_auth_token Vary: X-Auth-Token x-openstack-request-id: req-bc85eb93-eb34-41d6-970e-1cbd776c1878 Connection: close {"token": {"methods": ["password"], "user": {"domain": {"id": "$userDomainId" , "name": "$userDomainName"}, "id": "$userId", "name": "$userName", "password_expires_at": null}, "audit_ids": ["nHh38yyHSnWfPItIUnesEQ"], "expires_at": "2024-06-05T07:48:33.000000Z", "issued_at": "2024-06-05T06:48:33.000000Z", "project": {"domain": {"id": "$projectDomainId", "name": "$projectDomainName"}, "id": "$projectId", "name": "$projectName"}, "is_domain": false, "roles": [{"id": "4f50d53ed79a42bd89105954f21d9f1d", "name": "member"}, {"id": "9c9f278da6e74c2dbdb80fc0a5ed9010", "name": "manager"}, {"id": "fcdedca5ce604c90b241bab70f85d8cc", "name": "admin"}, {"id": "42ff1a2ac70d4496a90dd6aa8985feb1", "name": "reader"}]}} $ curl -i -X GET "https://$tacker_host_name:9890/v1.0/vims" \ -H "X-Auth-Token:$x_auth_token" \ --cacert multi_ca.pem HTTP/1.1 401 Unauthorized Content-Type: application/json Content-Length: 114 Www-Authenticate: Keystone uri="https://$keystone_host_name/identity" X-Openstack-Request-Id: req-5ee22493-4961-4272-82c6-c44978d3ed8b Date: Wed, 05 Jun 2024 07:02:02 GMT {"error": {"code": 401, "title": "Unauthorized", "message": "The request you have made requires authentication."}}
Enable OpenStack Command through Client Credentials Grant¶
To use OAuth 2.0 Client Credentials Grant from OpenStack CLI, you have to use
v3oauth2clientcredential
as auth_type
.
Before executing the command, you should remove the variables that affect the OpenStack command from the OS environment, then set the variables that required by OAuth 2.0 Client Credentials Grant to the OS environment.
$ unset OS_USERNAME $ unset OS_USER_ID $ unset OS_USER_DOMAIN_ID $ unset OS_USER_DOMAIN_NAME $ unset OS_TOKEN $ unset OS_PASSCODE $ unset OS_REAUTHENTICATE $ unset OS_TENANT_ID $ unset OS_TENANT_NAME $ unset OS_PROJECT_ID $ unset OS_PROJECT_NAME $ unset OS_PROJECT_DOMAIN_ID $ unset OS_PROJECT_DOMAIN_NAME $ unset OS_DOMAIN_ID $ unset OS_DOMAIN_NAME $ unset OS_SYSTEM_SCOPE $ unset OS_TRUST_ID $ unset OS_DEFAULT_DOMAIN_ID $ unset OS_DEFAULT_DOMAIN_NAME
$ export OS_AUTH_URL=https://$keystone_host_name/identity $ export OS_IDENTITY_API_VERSION=3 $ export OS_REGION_NAME="RegionOne" $ export OS_INTERFACE=public $ export OS_OAUTH2_ENDPOINT=https://$keystone_host_name/identity/v3/OS-OAUTH2/token $ export OS_OAUTH2_CLIENT_ID=$oauth2_client_id $ export OS_OAUTH2_CLIENT_SECRET=$oauth2_client_secret $ export OS_AUTH_TYPE=v3oauth2clientcredential $ export OS_CACERT=/opt/stack/certs/multi_ca.pem
Execute a tacker command to confirm that OpenStack command can access the Tacker APIs successfully.
$ openstack vim list +--------------------------------------+---------------------+----------------------------------+-----------+------------+--------+ | ID | Name | Tenant_id | Type | Is Default | Status | +--------------------------------------+---------------------+----------------------------------+-----------+------------+--------+ | 84517803-0e84-401e-ad75-8f6b8ab0a3b6 | openstack-admin-vim | d53a4605d776472d846aed35735d3494 | openstack | True | ACTIVE | +--------------------------------------+---------------------+----------------------------------+-----------+------------+--------+ $ openstack vnf package list +--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+ | Id | Vnf Product Name | Onboarding State | Usage State | Operational State | Links | +--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+ | 6b02a067-848f-418b-add1-e9c020239b31 | Sample VNF | ONBOARDED | IN_USE | ENABLED | { | | | | | | | "self": { | | | | | | | "href": "/vnfpkgm/v1/vnf_packages/6b02a067-848f-418b-add1-e9c020239b31" | | | | | | | }, | | | | | | | "packageContent": { | | | | | | | "href": "/vnfpkgm/v1/vnf_packages/6b02a067-848f-418b-add1-e9c020239b31/package_content" | | | | | | | } | | | | | | | } | +--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+ $ openstack vnflcm list +--------------------------------------+------------------------------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+ | ID | VNF Instance Name | Instantiation State | VNF Provider | VNF Software Version | VNF Product Name | VNFD ID | +--------------------------------------+------------------------------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+ | fd25f4ca-27ac-423b-afcf-640a64544e61 | vnf-fd25f4ca-27ac-423b-afcf-640a64544e61 | NOT_INSTANTIATED | Company | 1.0 | Sample VNF | b1bb0ce7-ebca-4fa7-95ed-4840d70a1177 | +--------------------------------------+------------------------------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+
Guide for OAuth 2.0 Mutual-TLS Client Authentication¶
To use OAuth 2.0 Mutual-TLS Client Authentication in Tacker, you should configure the Tacker server, the Keystone identity server and the Keystone middleware in the following steps.
Enable Keystone to Support Mutual-TLS Client Authentication¶
Modify the apache configuration file and add options to implement mutual TLS support for the Keystone service. You can reference Configuring HTTPS/mTLS for Tacker APIs to create Private root CA, private key and certificate that will be required in this guide. And the certificate and key files should be stored where the apache service can access.
Note
If HTTPS protocol has been enabled for keystone server in previous section by referencing Configure HTTPS in Identity Service, that configuration must be disabled by unlinking or removing the symlinked configuration file before enabling mTLS.
$ sudo unlink /etc/apache2/sites-enabled/000-default.conf
$ sudo vi /etc/apache2/sites-enabled/keystone-wsgi-public.conf ProxyPass "/identity" "unix:/var/run/uwsgi/keystone-wsgi-public.socket|uwsgi://uwsgi-uds-keystone-wsgi-public" retry=0 <IfModule mod_ssl.c> <VirtualHost _default_:443> ServerAdmin webmaster@localhost ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLEngine on SSLCertificateFile /etc/ssl/certs/keystone.pem SSLCertificateKeyFile /etc/ssl/private/keystone.key SSLCACertificateFile /etc/ssl/certs/multi_ca.pem <Location /identity/v3/OS-OAUTH2/token> SSLVerifyClient require SSLOptions +ExportCertData SSLOptions +StdEnvVars SSLRequireSSL </Location> </VirtualHost> </IfModule>
Restart apache service so that the modified configuration information takes effect.
$ sudo systemctl restart apache2.service
Modify the
keystone.conf
to enable the os-oauth2-api to use TLS certificates for user authentication.$ vi /etc/keystone/keystone.conf [oauth2] oauth2_authn_method=certificate oauth2_cert_dn_mapping_id=oauth2_mapping
Restart Keystone service so that the modified configuration information takes effect.
$ sudo systemctl restart devstack@keystone
Enable Mutual-TLS Client Authentication¶
Enable mTLS (aka., two-way TLS) for Tacker APIs to use Oauth 2.0 Mutual-TLS client authentication.
See Configuring HTTPS/mTLS for Tacker APIs for detailed steps, to enable mTLS for Tacker APIs.
Add
keystonemiddleware.oauth2_mtls_token:filter_factory
to the configuration fileapi-paste.ini
to enable OAuth 2.0 Mutual-TLS client authentication.$ vi /etc/tacker/api-paste.ini [composite:tackerapi_v1_0] #keystone = request_id catch_errors authtoken keystonecontext extensions tackerapiapp_v1_0 keystone = request_id catch_errors oauth2_mtls_token keystonecontext extensions tackerapiapp_v1_0 [composite:vnfpkgmapi_v1] #keystone = request_id catch_errors authtoken keystonecontext vnfpkgmapp_v1 keystone = request_id catch_errors oauth2_mtls_token keystonecontext vnfpkgmapp_v1 [composite:vnflcm_v1] #keystone = request_id catch_errors authtoken keystonecontext vnflcmaapp_v1 keystone = request_id catch_errors oauth2_mtls_token keystonecontext vnflcmaapp_v1 [composite:vnflcm_v2] #keystone = request_id catch_errors authtoken keystonecontext vnflcmaapp_v2 keystone = request_id catch_errors oauth2_mtls_token keystonecontext vnflcmaapp_v2 [composite:vnfpm_v2] #keystone = request_id catch_errors authtoken keystonecontext vnfpmaapp_v2 keystone = request_id catch_errors oauth2_mtls_token keystonecontext vnfpmaapp_v2 [composite:vnflcm_versions] #keystone = request_id catch_errors authtoken keystonecontext vnflcm_api_versions keystone = request_id catch_errors oauth2_mtls_token keystonecontext vnflcm_api_versions [composite:vnffm_v1] #keystone = request_id catch_errors authtoken keystonecontext vnffmaapp_v1 keystone = request_id catch_errors oauth2_mtls_token keystonecontext vnffmaapp_v1 [filter:oauth2_mtls_token] paste.filter_factory = keystonemiddleware.oauth2_mtls_token:filter_factory
Create Mapping Rules for Validating TLS Certificates¶
Because different root certificates have different ways of authenticating TLS certificates provided by client, the relevant mapping rules need to be set in the system.
Create a mapping rule file. When using Subject Distinguished Names, the “SSL_CLIENT_SUBJECT_DN_*” format must be used. When using Issuer Distinguished Names, the “SSL_CLIENT_ISSUER_DN_*” format must be used. The “*” part is the key of the attribute for Distinguished Names converted to uppercase. For more information about the attribute types for Distinguished Names, see the relevant RFC documentation such as: RFC1779, RFC2985, RFC4519, etc. In this example, 4 Subject Distinguished Names is mapped for user identity. You can map other Distinguished Names like email. For detail, reference Mapping Combinations.
$ vi oauth2_mapping.json [ { "local": [ { "user": { "name": "{0}", "id": "{1}", "domain": { "name": "{2}", "id": "{3}" } } } ], "remote": [ { "type": "SSL_CLIENT_SUBJECT_DN_CN" }, { "type": "SSL_CLIENT_SUBJECT_DN_UID" }, { "type": "SSL_CLIENT_SUBJECT_DN_O" }, { "type": "SSL_CLIENT_SUBJECT_DN_DC" }, { "type": "SSL_CLIENT_ISSUER_DN_CN", "any_one_of": [ "root_b.openstack.host" ] } ] } ]
Use the mapping file to create the oauth2_mapping rule in keystone.
$ openstack mapping create --rules oauth2_mapping.json oauth2_mapping +----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+ | Field | Value | +----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+ | id | oauth2_mapping | | rules | [{'local': [{'user': {'name': '{0}', 'id': '{1}', 'domain': {'name': '{2}', 'id': '{3}'}}}], 'remote': [{'type': 'SSL_CLIENT_SUBJECT_DN_CN'}, | | | {'type': 'SSL_CLIENT_SUBJECT_DN_UID'}, {'type': 'SSL_CLIENT_SUBJECT_DN_O'}, {'type': 'SSL_CLIENT_SUBJECT_DN_DC'}, {'type': 'SSL_CLIENT_ISSUER_DN_CN', | | | 'any_one_of': ['root_b.openstack.host']}]}] | | schema_version | 1.0 | +----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
If it already exists, use the file to update the mapping rule in keystone.
$ openstack mapping set --rules oauth2_mapping.json oauth2_mapping
To use
oauth2_mtls_token
Keystonemiddleware, default project of the user must be set. In this example, the default project ofnfv_user
user is set tonfv
project that is in thedefault
project domain.$ openstack user show nfv_user +---------------------+----------------------------------+ | Field | Value | +---------------------+----------------------------------+ | default_project_id | None | | domain_id | default | | email | None | | enabled | True | | id | 173c59254d3040969e359e5df0a3b475 | | name | nfv_user | | description | None | | password_expires_at | None | +---------------------+----------------------------------+ $ openstack project show nfv +-------------+----------------------------------+ | Field | Value | +-------------+----------------------------------+ | description | | | domain_id | default | | enabled | True | | id | 2e189ea6c1df4e4ba6d89de254b3a534 | | is_domain | False | | name | nfv | | options | {} | | parent_id | default | | tags | [] | +-------------+----------------------------------+
$ openstack user set 173c59254d3040969e359e5df0a3b475 \ --project 2e189ea6c1df4e4ba6d89de254b3a534 \ --project-domain default
Verify Access to Tacker APIs¶
Access to the Tacker APIs with client certificate to verify that OAuth 2.0 Mutual-TLS Client Authenticating works correctly.
To use OAuth 2.0 Mutual-TLS Client Authentication, the client private key and certificate is necessary. Create a certificate signing request based on the mapping rule created in previous section. For this guide, 4 Subject Distinguished Names mapped in oauth2 mapping rule have to be included.
$ openssl genrsa -out nfv_user.key 4096 $ openssl req -new -key nfv_user.key -out nfv_user.csr \ -subj "/UID=173c59254d3040969e359e5df0a3b475/O=Default/DC=default/CN=nfv_user"
Use the root certificate to generate a self-signed certificate for the user. Because the Issuer Common Names is mapped to be
root_b.openstack.host
in previous section, the client certificate has to be signed with root_b which CN isroot_b.openstack.host
. Root certificate can be created by referencing Configuring HTTPS/mTLS for Tacker APIs.$ openssl x509 -req -in nfv_user.csr \ -CA root_b.pem -CAkey root_b.key -CAcreateserial -out \ nfv_user.pem -days 180 -sha256 Certificate request self-signature ok subject=UID = 173c59254d3040969e359e5df0a3b475, O = Default, DC = default, CN = nfv_user
Obtain OAuth 2.0 Certificate-Bound access tokens through OAuth 2.0 Mutual-TLS Client Authentication.
$ curl -i -X POST https://$keystone_host_name/identity/v3/OS-OAUTH2/token \ -H "application/x-www-form-urlencoded" \ -d "grant_type=client_credentials&client_id=173c59254d3040969e359e5df0a3b475" \ --cacert multi_ca.pem \ --key nfv_user.key \ --cert nfv_user.pem HTTP/1.1 200 OK Date: Mon, 30 Sep 2024 05:31:07 GMT Server: Apache/2.4.52 (Ubuntu) Content-Type: application/json Content-Length: 307 Vary: X-Auth-Token x-openstack-request-id: req-11c95e0e-4b3f-4150-8ce9-b82f047c6906 Connection: close {"access_token":"$oauth2_mtls_access_token","expires_in":3600,"token_type":"Bearer"}
Access Tacker APIs using obtained OAuth 2.0 Certificate-Bound access tokens.
$ curl -i "https://$tacker_host_name:9890/v1.0/vims" \ -H "Authorization: Bearer $oauth2_mtls_access_token" \ -H "application/json" \ --cert nfv_user.pem \ --key nfv_user.key \ --cacert multi_ca.pem HTTP/1.1 200 OK Content-Type: application/json Content-Length: 2182 X-Openstack-Request-Id: req-9c39a83a-c123-4857-ac8c-ac0ada066ab1 Date: Wed, 02 Oct 2024 00:23:17 GMT {"vims": [{"id": "ce04bbe5-3ffe-449f-ba2a-69c0a747b9ad", "type": "kubernetes", "tenant_id": "2e189ea6c1df4e4ba6d89de254b3a534", "name": "test-vim-k8s", "description": "", "placement_attr": {"regions": ["default", "kube-node-lease", "kube-public", "kube-system"]}, "is_default": true, "created_at": "2024-07-04 09:07:56", "updated_at": null, "extra": {}, "auth_url": "https://10.0.2.15:6443", "vim_project": {"name": "nfv"}, "auth_cred": {"bearer_token": "***", "ssl_ca_cert": "$ssl_ca_cert", "auth_url": "https://10.0.2.15:6443", "username": "None", "key_type": "barbican_key", "secret_uuid": "***"}, "status": "ACTIVE"}]} $ curl -i "https://$tacker_host_name:9890/vnfpkgm/v1/vnf_packages" \ -H "Authorization: Bearer $oauth2_mtls_access_token" \ -H "application/json" \ --cert nfv_user.pem \ --key nfv_user.key \ --cacert multi_ca.pem HTTP/1.1 200 OK Content-Type: application/json Content-Length: 498 X-Openstack-Request-Id: req-32628f18-a8e6-49cc-8ac6-b2e49d961a42 Date: Wed, 02 Oct 2024 00:24:25 GMT [{"usageState": "IN_USE", "operationalState": "ENABLED", "id": "718e94a6-dfbf-48a4-8c6f-eaa541063a1b", "onboardingState": "ONBOARDED", "vnfProductName": "Sample VNF", "vnfProvider": "Company", "vnfSoftwareVersion": "1.0", "vnfdId": "eb37da52-9d03-4544-a1b5-ff5664c7687d", "vnfdVersion": "1.0", "_links": {"self": {"href": "/vnfpkgm/v1/vnf_packages/718e94a6-dfbf-48a4-8c6f-eaa541063a1b"}, "packageContent": {"href": "/vnfpkgm/v1/vnf_packages/718e94a6-dfbf-48a4-8c6f-eaa541063a1b/package_content"}}} $ curl -i "https://$tacker_host_name:9890/vnflcm/v2/vnf_instances" \ -H "Authorization: Bearer $oauth2_mtls_access_token" \ -H "application/json" \ -H "Version:2.0.0" --cert nfv_user.pem \ --key nfv_user.key \ --cacert multi_ca.pem HTTP/1.1 200 OK Content-Length: 829 Version: 2.0.0 Accept-Ranges: none Content-Type: application/json X-Openstack-Request-Id: req-adcc7680-8491-413d-806e-47906d2601fa Date: Wed, 02 Oct 2024 00:36:24 GMT [{"id": "703148ca-addc-4226-bee8-ef73d81dbbbf", "vnfdId": "eb37da52-9d03-4544-a1b5-ff5664c7687d", "vnfProvider": "Company", "vnfProductName": "Sample VNF", "vnfSoftwareVersion": "1.0", "vnfdVersion": "1.0", "instantiationState": "INSTANTIATED", "_links": {"self": {"href": "http://$tacker_host_name:9890/vnflcm/v2/vnf_instances/703148ca-addc-4226-bee8-ef73d81dbbbf"}, "terminate": {"href": "http://$tacker_host_name:9890/vnflcm/v2/vnf_instances/703148ca-addc-4226-bee8-ef73d81dbbbf/terminate"}, "scale": {"href": "http://$tacker_host_name:9890/vnflcm/v2/vnf_instances/703148ca-addc-4226-bee8-ef73d81dbbbf/scale"}, "heal": {"href": "http://$tacker_host_name:9890/vnflcm/v2/vnf_instances/703148ca-addc-4226-bee8-ef73d81dbbbf/heal"}, "changeExtConn": {"href": "http://$tacker_host_name:9890/vnflcm/v2/vnf_instances/703148ca-addc-4226-bee8-ef73d81dbbbf/change_ext_conn"}}}]
Enable OpenStack Command through Mutual-TLS Client Authentication¶
To use OAuth 2.0 Mutual-TLS Client Authentication from OpenStack CLI, you have
to use v3oauth2mtlsclientcredential
as auth_type
.
Before executing the command, you should remove the variables that affect the OpenStack command from the OS environment, then set the variables that required by OAuth 2.0 Mutual-TLS Client Authentication to the OS environment.
$ unset OS_USERNAME $ unset OS_USER_ID $ unset OS_USER_DOMAIN_ID $ unset OS_USER_DOMAIN_NAME $ unset OS_TOKEN $ unset OS_PASSCODE $ unset OS_REAUTHENTICATE $ unset OS_TENANT_ID $ unset OS_TENANT_NAME $ unset OS_PROJECT_ID $ unset OS_PROJECT_NAME $ unset OS_PROJECT_DOMAIN_ID $ unset OS_PROJECT_DOMAIN_NAME $ unset OS_DOMAIN_ID $ unset OS_DOMAIN_NAME $ unset OS_SYSTEM_SCOPE $ unset OS_TRUST_ID $ unset OS_DEFAULT_DOMAIN_ID $ unset OS_DEFAULT_DOMAIN_NAME
$ export OS_AUTH_TYPE=v3oauth2mtlsclientcredential $ export OS_KEY=/opt/stack/certs/nfv_user.key $ export OS_CERT=/opt/stack/certs/nfv_user.pem $ export OS_CACERT=/opt/stack/certs/multi_ca.pem $ export OS_OAUTH2_CLIENT_ID=173c59254d3040969e359e5df0a3b475 $ export OS_OAUTH2_ENDPOINT=https://$keystone_host_name/identity/v3/OS-OAUTH2/token $ export OS_INTERFACE=public $ export OS_REGION_NAME="RegionOne" $ export OS_IDENTITY_API_VERSION=3 $ export OS_AUTH_URL=https://$keystone_host_name/identity
Execute Tacker commands to confirm that OpenStack command can access the Tacker APIs successfully.
$ openstack vim list +--------------------------------------+--------------+----------------------------------+------------+------------+--------+ | ID | Name | Tenant_id | Type | Is Default | Status | +--------------------------------------+--------------+----------------------------------+------------+------------+--------+ | ce04bbe5-3ffe-449f-ba2a-69c0a747b9ad | test-vim-k8s | 2e189ea6c1df4e4ba6d89de254b3a534 | kubernetes | True | ACTIVE | +--------------------------------------+--------------+----------------------------------+------------+------------+--------+ $ openstack vnf package list +--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+ | Id | Vnf Product Name | Onboarding State | Usage State | Operational State | Links | +--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+ | 718e94a6-dfbf-48a4-8c6f-eaa541063a1b | Sample VNF | ONBOARDED | IN_USE | ENABLED | { | | | | | | | "self": { | | | | | | | "href": "/vnfpkgm/v1/vnf_packages/718e94a6-dfbf-48a4-8c6f-eaa541063a1b" | | | | | | | }, | | | | | | | "packageContent": { | | | | | | | "href": "/vnfpkgm/v1/vnf_packages/718e94a6-dfbf-48a4-8c6f-eaa541063a1b/package_content" | | | | | | | } | | | | | | | } | +--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+ $ openstack vnflcm list --os-tacker-api-version 2 +--------------------------------------+-------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+ | ID | VNF Instance Name | Instantiation State | VNF Provider | VNF Software Version | VNF Product Name | VNFD ID | +--------------------------------------+-------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+ | 703148ca-addc-4226-bee8-ef73d81dbbbf | | INSTANTIATED | Company | 1.0 | Sample VNF | eb37da52-9d03-4544-a1b5-ff5664c7687d | +--------------------------------------+-------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+