Certificate Management Let's Encrypt script fails to renew certificate of correct VS
search cancel

Certificate Management Let's Encrypt script fails to renew certificate of correct VS

book

Article ID: 421803

calendar_today

Updated On:

Products

VMware Avi Load Balancer

Issue/Introduction

When renewing an existing virtual service certificate or creating a new application certificate CSR the control script "LetsEncryptAlertScriptConfig" will select the first matching fqdn/domain from the list of matching VS VIPs even if the fqdn is a partial match.

Example Certificate with Common Name (CN) and Subject Alternative Name (SAN):

"name": "LetsEncrypt-www.example.org",
--SNIP--
"subject": {
  "common_name": "www.example.org",
  "country": "United States",
  "distinguished_name": "CN=www.example.org",
  "locality": "EXAMPLE",
  "organization": "Broadcom Example",
  "organization_unit": "EXAMPLE",
  "state": "CA"
},
"subject_alt_names": [
  "example.org"
]

Example VSVIP FQDN/Domain configuration that will result in a partial match.

[admin:controller]: > show vsvip test-domain-1 | grep dns_info -A1
| dns_info[1]                 |                                            |
|   fqdn                      | testexample.org                            |

[admin:controller]: > show vsvip test-domain-2 | grep dns_info -A1
| dns_info[1]                 |                                            |
|   fqdn                      | www.example.org                            |
--
| dns_info[2]                 |                                            |
|   fqdn                      | example.com                                |

 

The script uses the API endpoint GET /api/vsvip with the search parameter.  This search parameter returns all matching strings, even partial matches.

# Get VSVIPs/VSs, based on FQDN
rsp = _do_request_avi("vsvip/?search=(fqdn,{})".format(domain), "GET").json()

API endpoint result:

admin@controller:~# sudo curl -sk 'https://localhost/api/vsvip/?search=example.org' -H 'accept: application/json' -H 'X-Avi-Version: 30.2.2' -H 'X-Avi-Tenant: *' -u admin | jq '.results[]|.name, .dns_info[]'
Enter host password for user 'admin':
"test-domain-1"
{
  "algorithm": "DNS_RECORD_RESPONSE_CONSISTENT_HASH",
  "fqdn": "testexample.org",
  "type": "DNS_RECORD_A"
}
"test-domain-2"
{
  "algorithm": "DNS_RECORD_RESPONSE_CONSISTENT_HASH",
  "fqdn": "www.example.org",
  "type": "DNS_RECORD_A"
}
{
  "algorithm": "DNS_RECORD_RESPONSE_CONSISTENT_HASH",
  "fqdn": "example.com",
  "type": "DNS_RECORD_A"
}

Since there was a partial match with domain "testexample.org" and is the first in the list, the control script will select the virtual service with vsvip test-domain-1 and fail with the following stacktrace:

LOG: /var/lib/avi/log/portal-webapp.log

[2025-12-01 21:50:27,624] INFO [cs_container.executeScript:170] {'ExitCode': 1, 'stdout': 
'Running version 0.9.7\n
dry_run is: False\n
disable_check is: False\n
directory_url is https://acme-v02.api.letsencrypt.org/directory\n
Account key not found. Generating account key...\n
Parsing account key...\n
Parsing CSR...\n
Found domains: example.org, www.example.org\n
Getting directory...\n
Directory found!\n
Registering account...\n
Registered!\n
Creating new order...\n
Order created!\n
Verifying example.org...\n
Found VS virtualservice-uuid with fqdn example.org\n
Created httpPolicy with uuid httppolicyset-uuid\n
Added httpPolicySet to VS virtualservice-uuid\n
Validating token from Avi Controller...\n
Cleaning up...\n
Removed httpPolicySet from VS virtualservice-uuid\n
Deleted httpPolicySet\n
', 'stderr': 'Traceback (most recent call last):\n
  File "/run/shm/cs/certificatemanagementprofile-uuid", line 395, in get_crt\n
      reqToken = _do_request(wellknown_url, verify=False)\n
        File "/run/shm/cs/certificatemanagementprofile-uuid", line 107, in _do_request\n
            raise ValueError("{0}:\\n
            Url: {1}\\nData: {2}\\n
            Response Code: {3}\\n
            Response: {4}".format(err_msg, url, data, code, resp_data))\n
            ValueError: Error:\n
            Url: http://example.org/.well-known/acme-challenge/ebDD5v9ravdy_p1HoBxtAzsfi_IiBpOJmZ-AQXLjvAg\n
            Data: None\n
            Response Code: 404\n

Environment

Affects Version(s):

All 22.1.x versions up to 22.1.7-2p11 patch

30.2.1 - 30.2.1-2p6

30.2.2 - 30.2.2-2p6

30.2.3 - 30.2.3-2p4

30.2.4 - 30.2.4-2p2

30.2.5 - 30.2.5-2p1

30.2.6

31.1.1 - 31.1.1-2p3

31.1.2 - 31.1.2-2p1

31.2.1

Cause

This is a logic issue with the control script "LetsEncryptAlertScriptConfig" where it selects the first matching VSVIP even if it's a partial string match.

Resolution

The control script "LetsEncryptAlertScriptConfig" has been updated with a fix to prevent this issue when there are multiple matching domains in VSVIPs.  The updated script will be shipped/included in the next GA release of VMware Avi Load Balancer versions.

Please use the Let's Encrypt script from Broadcom Avi DevOps link below:

Updated_letsencrypt_mgmt_profile_script