如何使用 Python 为 Azure 应用程序网关的侦听器添加新证书

How to add new certificate for a listener of an Azure Application gateway with Python

各位。

我是 Internet 和 Azure 的初学者。我有一个关于使用 Python 向 Azure 应用程序网关的侦听器添加证书的问题。我将我的问题详细描述如下。

1.背景

我使用的Azure环境是:

Resource group name: My_ResourceGroup
Subscription ID: sub_id
Tenant ID: tenant_id
Client: my_client
Service principal password: sp_password

2。顶级域和子域

在资源组 My_ResourceGroup 中,有两个 Azure DNS 提供商,区域分别为 contoso.comchen.contoso.comcontoso.com 是顶级域,而 chen.contoso.com 是子域。

对于chen.contoso.com,我创建了一条A记录,名字为www,IP为10.10.10.10(注意这个IP只是用来测试的)。我还为此域生成了一个证书(cert.pfx 文件)以便使用 HTTPS。

3。将 cert.pfx 证书安装到侦听器

我在资源组 My_ResourceGroup 中有一个现成的 Azure 应用程序网关 contoso-appgw。在这个网关中,有一个监听器contoso-appgw-hl并且在这个监听器中有一个证书cert0.pfx

我想要做的是使用 Azure Python SDK 将 cert.pfx 证书附加(或安装)到侦听器 contoso-appgw-hl 这样操作后,listenercontoso-appgw-hl中应该有两个证书:cert0.pfx(旧的)和cert.pfx(新的)

4.我的代码和参考资料

我的Python代码如下:

from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.network import NetworkManagementClient

# Replace this with your subscription id
subscription_id = 'sub_id'

# Tenant ID for your Azure subscription
TENANT_ID = 'tenant_id'

# Your service principal App ID
CLIENT = 'client'

# Your service principal password
KEY = 'sp_password'

credentials = ServicePrincipalCredentials(
        client_id = CLIENT,
        secret = KEY,
        tenant = TENANT_ID
    )

network_client = NetworkManagementClient(credentials, subscription_id)

network_client.application_gateways.create_or_update(
    'My_ResourceGroup',
    'contoso-appgw',
    {
        'location': 'East US 2',
        'http_listeners': [
            {
                'name': 'contoso-appgw-hl',
                'protocol': 'Https',

                'ssl_certificate': {
                    'data': 'cert.pfx',
                    'name': 'chenkui',
                    'password': '123abc'
                }
            }
        ]
    }
)

我根据以下资源编写了我的代码:

  1. 示例代码:azure application manage sample code
  2. Azure 文档:definition of create_or_update function

请注意,我的代码中的cert.pfx是Base-64格式的证书,因为根据文档需要Base-64格式的证书。

5.错误信息

以上代码失败。上面代码Azure Portal --> contoso-appgw --> Activity log中显示的错误信息是:

Operation name:
    Create or Update Application Gateway

Error code:
    InvalidRequestFormat

Message:
    Cannot parse the request.

即使我使用 Azure 门户(即不使用 Python 代码,而是在浏览器中使用 GUI 门户),添加证书也失败。 Azure Portal --> contoso-appgw --> Activity log中显示的错误信息是:

Operation name:
    Create or Update Application Gateway

Error code: 
    ApplicationGatewaySslCertificateDataMustBeSpecified

Message:
    Data must be specified for Certificate /subscriptions/c72b5b1b-771e-4b65-ba34-a7db981c9dcf/resourceGroups/My_ResourceGroup/providers/Microsoft.Network/applicationGateways/contoso-appgw/sslCertificates/chenkui.

6.我的问题

我的问题如下:

  1. 这些错误消息的含义是什么?
  2. 为什么会出现这些错误?
  3. 我的代码有什么问题,如何解决?

非常感谢!

如果您想将侦听器从 http 转换为 https,可以使用以下 powershell 脚本:

$appgw= Get-AzApplicationGateway -Name "AppGWname" -ResourceGroupName "RG Name"

#$listener= Get-AzApplicationGatewayHttpListener -Name listener1 -ApplicationGateway $appgw

$FEC= Get-AzApplicationGatewayFrontendIPConfig -Name "FrontendIP" -ApplicationGateway $appgw


Add-AzApplicationGatewayFrontendPort -ApplicationGateway $appgw -Name "Name of the Port" -Port 443 

$port = Get-AzApplicationGatewayFrontendPort -ApplicationGateway $appgw -Name "Name of Port"

$passwd = ConvertTo-SecureString  "Passoword" -AsPlainText -Force 


Add-AzApplicationGatewaySSLCertificate -Name "Name of the cert" -CertificateFile "Full path of the cert with.pfx" -Password $passwd -ApplicationGateway $appgw

$cert =Get-AzApplicationGatewaySSLCertificate -Name "Name of cert" -ApplicationGateway $appgw

Set-AzApplicationGatewayHttpListener -ApplicationGateway $appgw -Name "Name of the listener" -FrontendIPConfiguration $FEC -FrontendPort $port -Protocol Https -SslCertificate $cert

Set-AzApplicationGateway -ApplicationGateway $appgw

我找到了更新现有应用程序网关的方法。使用 create_or_update 功能更新现有 Azure 资源时,您必须先 get 它。否则,create_or_update 将创建新资源而不是更新现有资源。

下面的link就是一个很好的例子。它创建和更新 Azure VM。 Create and manage Windows VMs in Azure using Python

因为在Azure中创建和管理资源有统一的方法,所以我们可以应用上面link给出的思路来管理应用程序网关。代码如下

import base64

from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.network.v2019_06_01.models import ApplicationGateway, ApplicationGatewaySslCertificate


def test_appgw():
    # create credentials
    credentials = ServicePrincipalCredentials(
            client_id = CLIENT,
            secret = KEY,
            tenant = TENANT_ID
        )

    # create network client
    network_client = NetworkManagementClient(credentials, subscription_id)

    # get an existing application gateway
    app_gw = network_client.application_gateways.get(RESOURCE_GROUP_NAME, APPLICATION_GATEWAY_NAME)

    # read the pfx certificate and convert it to base-64 string
    with open('certificate.pfx', 'rb') as binary_cert:
        base64_cert = base64.b64encode(binary_cert.read())
        cert_data = base64_cert.decode('utf-8')

    # create an SSL certificate
    ssl_cert = ApplicationGatewaySslCertificate(
        name=ANY_NAME_IS_OK,
        data=cert_data,
        password=THE_PASSWARD_USED_TO_CREATE_CERTIFICATE
    )

    # app_gw.ssl_certificates is a Python list, so we append the new certificate in it
    app_gw.ssl_certificates.append(ssl_cert)

    # update the application gateway
    network_client.application_gateways.create_or_update(
        RESOURCE_GROUP_NAME,
        APPLICATION_GATEWAY_NAME,
        app_gw
    )

if __name__ == "__main__":
    test_appgw()

注:

  1. 使用get函数获取已有的应用程序网关;
  2. ApplicationGatewaySslCertificateclass的第一个参数name是一个字符串。您可以使用您喜欢的任何名称;
  3. 第二个参数data是一个字符串。它不是证书名称,而是 pfx 证书内容的 Base-64 字符串;
  4. 第三个参数password是一个字符串。它应该是您用来创建 pfx 证书的密码。

希望对您有所帮助。