配置 Tacker API 的 HTTPS/mTLS

本文档介绍了如何在 Tacker API 上设置 HTTPS 和双向 TLS,也称为相互 TLS (mTLS)。在本指南中,$tacker_host_name 将用作 Tacker API 的主机名。

注意

本文档的内容已确认在使用 Tacker 2024.1 Caracal 时有效。

准备工作

为了启用 TLS,需要使用私有/公共证书颁发机构 (CA) 作为根证书来签署证书。虽然通常使用公共 CA 颁发的证书,但本指南介绍了如何创建私有 CA 来测试 HTTPS/mTLS 功能。

创建私有证书颁发机构 (CA)

如果用于 mTLS 的证书由公共 CA 颁发,请跳过步骤 1 和 2。

  1. 生成 RSA 私钥。

    $ openssl genrsa -out root_a.key 4096
    
  2. 生成自签名证书。

    $ openssl req -new -x509 -key root_a.key -out root_a.pem -days 365
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [AU]:JP
    State or Province Name (full name) [Some-State]:Tokyo
    Locality Name (eg, city) []:Musashino
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:OpenstackORG
    Organizational Unit Name (eg, section) []:DevDept
    Common Name (e.g. server FQDN or YOUR name) []:root_a.openstack.host
    Email Address []:
    
  3. 如果需要支持多个根证书,则应将这些根证书合并并配置在服务器上。例如,本指南使用先前创建的 root_a.pem,以及以相同方式创建的 root_b.pem。在创建 root_b.pem 时,将 CN 指定为 root_b.openstack.host

    在此步骤中,通过连接两个根证书来创建一个新的 multi_ca.pem。

    $ cat root_a.pem >> multi_ca.pem
    $ cat root_b.pem >> multi_ca.pem
    $ cat multi_ca.pem
    -----BEGIN CERTIFICATE-----
    MIIF1TCCA72gAwIBAgIUBAofPmi3cxX3/xvz6n3Pi9KjPW4wDQYJKoZIhvcNAQEL
    BQAwejELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRva3lvMRIwEAYDVQQHDAlNdXNh
    ...
    HC1PfWQYli7d+98zz1KXwUkLv9MmBOOnP83wS4upfspTpU1wBK9ZcKFAS5MkpuS6
    0x5atdhal1RlulNblqs6TR5W+uiffCJblQRzDMSLLZVzkAULhWqRRkS7PxtKnc2z
    cidL67MTrzni
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    MIIF1TCCA72gAwIBAgIUICVkJl1df1REQOKdF9VelC3+lEAwDQYJKoZIhvcNAQEL
    BQAwejELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRva3lvMRIwEAYDVQQHDAlNdXNh
    ...
    g+kVxAXPwbrZKTsWMvsCvD0xXs3nC/FKmlPx5VL+6smAKPTWQr9M/k+4voviboms
    V59KPLVlmxKE
    -----END CERTIFICATE-----
    

创建私钥和证书

为了启用 TLS,需要创建私钥和证书。虽然通常使用公共 CA 颁发的证书,但本指南介绍了如何使用私有 CA 创建自签名证书来测试 mTLS 功能。如果用于 mTLS 的证书由公共 CA 颁发,请跳过这些步骤。

  1. 生成 RSA 私钥。

    $ openssl genrsa -out tacker_api.key 4096
    
  2. 创建一个证书签名请求。

    $ openssl req -new -key tacker_api.key -out tacker_api.csr
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [AU]:JP
    State or Province Name (full name) [Some-State]:Tokyo
    Locality Name (eg, city) []:Musashino
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:OpenstackORG
    Organizational Unit Name (eg, section) []:DevDept
    Common Name (e.g. server FQDN or YOUR name) []:$tacker_host_name
    Email Address []:
    
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    
  3. 使用先前章节中创建的根证书对证书进行自签名。

    $ openssl x509 -req -in tacker_api.csr \
    -CA root_a.pem -CAkey root_a.key -CAcreateserial \
    -out tacker_api.pem -days 365 -sha384
    Certificate request self-signature ok
    subject=C = JP, ST = Tokyo, L = Musashino, O = OpenstackORG, OU = DevDept, CN = $tacker_host_name
    

启用 HTTPS 指南

您可以按照以下步骤在 Tacker API 中配置 HTTPS。

配置 Tacker API 的 HTTPS

  1. 修改 配置选项 以启用 SSL,从而为 Tacker API 实现 HTTPS 支持。

    $ vi /etc/tacker/tacker.conf
    [DEFAULT]
    
    # Enable SSL on the API server (boolean value)
    use_ssl = true
    
    # Certificate file to use when starting the server securely (string value)
    ssl_cert_file = /etc/tacker/tacker_api.pem
    
    # Private key file to use when starting the server securely (string value)
    ssl_key_file = /etc/tacker/tacker_api.key
    
    [v2_vnfm]
    
    # Endpoint of VNFM (self). (string value)
    endpoint = https://$tacker_host_name:9890
    
    [vnf_lcm]
    
    # endpoint_url (string value)
    endpoint_url = https://$tacker_host_name:9890/
    
  2. 重新启动 tacker 服务,以使修改后的配置信息生效。

    $ sudo systemctl restart devstack@tacker
    

验证对 Tacker API 的 HTTPS 访问

  1. 尝试通过 HTTPS 协议访问 Tacker API,以确认服务已成功配置。

    $ curl -i -X GET https://$tacker_host_name:9890/ \
    --cacert multi_ca.pem
    HTTP/1.1 200 OK
    Content-Type: application/json
    Content-Length: 122
    Date: Tue, 01 Oct 2024 03:15:23 GMT
    
    {"versions": [{"id": "v1.0", "status": "CURRENT", "links": [{"rel": "self", "href": "https://$tacker_host_name:9890/v1.0"}]}]}
    
  2. 当 Tacker 切换到 HTTPS 时,用户无法通过 HTTP 协议访问 Tacker API。

    $ curl -i -X GET http://$tacker_host_name:9890/
    curl: (52) Empty reply from server
    

启用 Openstack 命令以使用 HTTPS 启用的 Tacker API

  1. 您必须设置 CA 证书的环境变量,以验证 Tacker 服务器证书,以便访问 HTTPS 启用的 Tacker API。

    $ export OS_CACERT=/opt/stack/certs/multi_ca.pem
    
  2. 更改 nfv-orchestration 端点以访问 HTTPS 启用的 Tacker API。

    $ openstack endpoint list --service nfv-orchestration
    +----------------------------------+-----------+--------------+-------------------+---------+-----------+--------------------------------+
    | ID                               | Region    | Service Name | Service Type      | Enabled | Interface | URL                            |
    +----------------------------------+-----------+--------------+-------------------+---------+-----------+--------------------------------+
    | 1d48e6e978c442b988f22ebc2cf2581e | RegionOne | tacker       | nfv-orchestration | True    | admin     | http://$tacker_host_name:9890/ |
    | 4d687048030942cb8dea98e84ff7d596 | RegionOne | tacker       | nfv-orchestration | True    | internal  | http://$tacker_host_name:9890/ |
    | acd08fcab9164fc89aabbc627771a499 | RegionOne | tacker       | nfv-orchestration | True    | public    | http://$tacker_host_name:9890/ |
    +----------------------------------+-----------+--------------+-------------------+---------+-----------+--------------------------------+
    
    $ openstack endpoint set 1d48e6e978c442b988f22ebc2cf2581e --url https://$tacker_host_name:9890/
    $ openstack endpoint set 4d687048030942cb8dea98e84ff7d596 --url https://$tacker_host_name:9890/
    $ openstack endpoint set acd08fcab9164fc89aabbc627771a499 --url https://$tacker_host_name:9890/
    
    $ openstack endpoint list --service nfv-orchestration
    +----------------------------------+-----------+--------------+-------------------+---------+-----------+---------------------------------+
    | ID                               | Region    | Service Name | Service Type      | Enabled | Interface | URL                             |
    +----------------------------------+-----------+--------------+-------------------+---------+-----------+---------------------------------+
    | 1d48e6e978c442b988f22ebc2cf2581e | RegionOne | tacker       | nfv-orchestration | True    | admin     | https://$tacker_host_name:9890/ |
    | 4d687048030942cb8dea98e84ff7d596 | RegionOne | tacker       | nfv-orchestration | True    | internal  | https://$tacker_host_name:9890/ |
    | acd08fcab9164fc89aabbc627771a499 | RegionOne | tacker       | nfv-orchestration | True    | public    | https://$tacker_host_name:9890/ |
    +----------------------------------+-----------+--------------+-------------------+---------+-----------+---------------------------------+
    
  3. 执行 tacker 命令以确认 OpenStack 命令可以成功访问 Tacker API。

    $ 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 |
    +--------------------------------------+-------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+
    

启用双向 TLS/mTLS 指南

双向 TLS,也称为 mTLS,是 TLS RFC5246 RFC8446 的当代版本,它要求服务器和客户端在握手期间发送证书以及 CertificateVerify 消息,并且服务器要验证 CertificateVerify 和 Finished 消息。以下步骤介绍了如何在 Tacker API 中设置 mTLS。

配置 Tacker API 的 mTLS

注意

在 OAuth 2.0 相互 TLS 客户端身份验证中,您必须使用授权服务器所需的特定主题区分名(例如:Common Name (CN))创建客户端证书。

  1. 修改 配置选项 以启用 mTLS 支持,从而为 Tacker API 提供支持。

    $ vi /etc/tacker/tacker.conf
    [DEFAULT]
    
    # Enable SSL on the API server (boolean value)
    use_ssl = true
    
    # Certificate file to use when starting the server securely (string value)
    ssl_cert_file = /etc/tacker/tacker_api.pem
    
    # Private key file to use when starting the server securely (string value)
    ssl_key_file = /etc/tacker/tacker_api.key
    
    # CA certificate file to use to verify connecting clients (string value)
    ssl_ca_file = /etc/tacker/multi_ca.pem
    
    [v2_vnfm]
    
    # Endpoint of VNFM (self). (string value)
    endpoint = https://$tacker_host_name:9890
    
    [vnf_lcm]
    
    # endpoint_url (string value)
    endpoint_url = https://$tacker_host_name:9890/
    
  2. 重新启动 tacker 服务,以使修改后的配置信息生效。

    $ sudo systemctl restart devstack@tacker
    

验证对 Tacker API 的 mTLS 访问

  1. 尝试通过 mTLS 协议访问 Tacker API,以确认服务已成功配置。要通过 mTLS 访问 Tacker API,需要为客户端创建私钥和证书。您可以按照上一节中的相同步骤 创建私有证书颁发机构 (CA) 来创建客户端私钥和证书。在本示例中,使用 CN 为 root_b.openstack.host 的根 CA 创建了私钥 client.key 和证书 client.pem

    $ curl -i -X GET https://$tacker_host_name:9890/ \
    --cacert multi_ca.pem \
    --cert client.pem \
    --key client.key
    HTTP/1.1 200 OK
    Content-Type: application/json
    Content-Length: 120
    Date: Tue, 01 Oct 2024 05:46:05 GMT
    
    {"versions": [{"id": "v1.0", "status": "CURRENT", "links": [{"rel": "self", "href": "https://$tacker_host_name:9890/v1.0"}]}]}
    
  2. 当 Tacker 切换到 mTLS 时,用户无法通过 HTTPS 协议访问 Tacker API,这意味着没有发送客户端证书。

    $ curl -i -X GET https://$tacker_host_name:9890/ \
    --cacert multi_ca.pem
    curl: (56) OpenSSL SSL_read: error:0A00045C:SSL routines::tlsv13 alert certificate required, errno 0
    

启用 Openstack 命令以使用 mTLS 启用的 Tacker API

  1. 为了使用 openstack 命令访问 mTLS 启用的 Tacker API,除了 CA 证书之外,还必须在环境变量中设置发送到服务器以验证客户端的客户端私钥和证书。

    $ export OS_CACERT=/opt/stack/certs/multi_ca.pem
    $ export OS_KEY=/opt/stack/certs/client.key
    $ export OS_CERT=/opt/stack/certs/client.pem
    
  2. 更改 nfv-orchestration 端点以访问 HTTPS 启用的 Tacker API。

    有关如何更改端点的详细信息,请参阅 启用 Openstack 命令以使用 HTTPS 启用的 Tacker API

  3. 执行 tacker 命令以确认 OpenStack 命令可以成功访问 Tacker API。

    $ 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 |
    +--------------------------------------+-------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+