Generate a Let’s Encrypt signed certificate

Overview

Use this sequence to generate a Let’s Encrypt signed certificate from BIG-IQ. This sequence is mandatory to get a certificate. The steps up to step #6 require administrative privileges and can be performed one time until the challenges expire. After the challenges expire you will need to repeat the sequence.

Sequence

1. Get the Let’s Encrypt provider details

Send a GET request to the CA Provider List API to retrieve the list of certificate authority (CA) providers from BigIQ.

GET https://<BIG-IQ>/mgmt/cm/adc-core/external-ca/provider-list

The JSON in the body of the GET response can look similar to the following example.

{
    "providerList": [
            "Lets Encrypt",
            "Venafi"
    ],
    "generation": 0,
    "lastUpdateMicros": 0,
    "kind": "cm:adc-core:external-ca:provider-list:externalcaproviderliststate",
    "selfLink": "https://localhost/mgmt/cm/adc-core/external-ca/provider-list"
}

2. Get the API endpoints for the Let’s Encrypt server

Send a GET request to the Let’s Encrypt Directory API to retrieve a list of all the API endpoints provided by the Let’s Encrypt server. The JSON in the response can include URLs for resources such as terms of service, nonce, account, order and others which can be accepted for use in subsequent steps of the certificate creation.

GET https://<BIG-IQ>/mgmt/cm/adc-core/external-ca/lets-encrypt/resource-list

The JSON in the body of the GET response can look similar to the following example.

{
    "items": [{
                    "uuid": "59ec6404-afe5-3c23-aa19-b47972578c27",
                    "serverUri": "https://acme-v02.api.letsencrypt.org/",
                    "resourceUrls": {
                            "keyChange": "https://acme-v02.api.letsencrypt.org/acme/key-change",
                            "revokeCert": "https://acme-v02.api.letsencrypt.org/acme/revoke-cert",
                            "newNonce": "https://acme-v02.api.letsencrypt.org/acme/new-nonce",
                            "newAccount": "https://acme-v02.api.letsencrypt.org/acme/new-acct",
                            "newOrder": "https://acme-v02.api.letsencrypt.org/acme/new-order",
                            "termsOfService": "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf"
                    },
                    "generation": 1,
                    "lastUpdateMicros": 1565350119556388,
                    "kind": "cm:adc-core:external-ca:lets-encrypt:resource-list:letsencryptresourceliststate",
                    "selfLink": "https://localhost/mgmt/cm/adc-core/external-ca/lets-encrypt/resource-list/59ec6404-afe5-3c23-aa19-b47972578c27"
            },
            {
                    "uuid": "796d551a-7429-36e4-bc68-687abb8733d3",
                    "serverUri": "https://acme-staging-v02.api.letsencrypt.org/",
                    "resourceUrls": {
                            "keyChange": "https://acme-staging-v02.api.letsencrypt.org/acme/key-change",
                            "revokeCert": "https://acme-staging-v02.api.letsencrypt.org/acme/revoke-cert",
                            "website": "https://letsencrypt.org/docs/staging-environment/",
                            "newNonce": "https://acme-staging-v02.api.letsencrypt.org/acme/new-nonce",
                            "newAccount": "https://acme-staging-v02.api.letsencrypt.org/acme/new-acct",
                            "newOrder": "https://acme-staging-v02.api.letsencrypt.org/acme/new-order",
                            "termsOfService": "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf"
                    },
                    "generation": 1,
                    "lastUpdateMicros": 1565353260651553,
                    "kind": "cm:adc-core:external-ca:lets-encrypt:resource-list:letsencryptresourceliststate",
                    "selfLink": "https://localhost/mgmt/cm/adc-core/external-ca/lets-encrypt/resource-list/796d551a-7429-36e4-bc68-687abb8733d3"
            }
    ],
    "generation": 1,
    "kind": "cm:adc-core:external-ca:lets-encrypt:resource-list:letsencryptresourcelistcollectionstate",
    "lastUpdateMicros": 1565348758357060,
    "selfLink": "https://localhost/mgmt/cm/adc-core/external-ca/lets-encrypt/resource-list"
}

3. Generate the Let’s Encrypt configuration

Send a POST request to the CA Configuration API to generate the certificate authority (CA) configuration. The CA configuration can be used in subsequent steps of the certificate creation.

POST https://<BIG-IQ>/mgmt/cm/adc-core/external-ca/config

The JSON in the body of the POST request can look similar to the following example.

{
    "name": "LE_Staging_Server",
    "caProvider": "Lets Encrypt",
    "webSdkEndPoint": "https://acme-staging-v02.api.letsencrypt.org/",
    "keyAlgorithm": "RSA",
    "keySize": 2048,
    "terms": true
}

4. Generate the domain configuration

Send a POST request to the Let’s Encrypt Domain Configuration API to generate the domain configuration. This step is required for Let’s Encrypt to verify the domain servers before signing the certificates.

POST https://<BIG-IQ>/mgmt/cm/adc-core/external-ca/lets-encrypt/config

The JSON in the body of the POST request can look similar to the following example.

{
    "externalCaConfigReference": {
            "link": "https://localhost/mgmt/cm/adc-core/external-ca/config/5194e771-18d1-377d-8706-1d3102ebb312"
    },
    "domains": [{
                    "domainName": "letsencrypt.example1.de"
            },
            {
                    "domainName": "letsencrypt.example2.de"
            }
    ]
}

The JSON in the body of the POST response can include values for authenticationUrl. You can use the returned value of authenticationUrl as the value of authLocation in step 5. For example, the JSON in the body of the response can look similar to the following.

{
    "uuid": "a812b8da-4a11-3dca-8bd4-7f247352c49a",
    "externalCaConfigReference": {
            "link": "https://localhost/mgmt/cm/adc-core/external-ca/config/5194e771-18d1-377d-8706-1d3102ebb312"
    },
    "name": "LE_Staging_Server",
    "domains": [{
                    "domainName": "letsencrypt.example1.de",
                    "authenticationUrl": "https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/3919567",
                    "authExpiryDate": "2019-09-12T08:26:10Z",
                    "challengeToken": "-----omitted from sample-----",
                    "httpChallengeContent": "-----omitted from sample-----",
                    "httpChallengeUrl": "https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/7139283/lb5-OQ",
                    "dnsChallengeContent": "-----omitted from sample-----",
                    "dnsChallengeUrl": "https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/7139283/u6VmaQ",
                    "tlsChallengeCertContent": "-----BEGIN CERTIFICATE-----omitted from sample-----END CERTIFICATE-----",
                    "tlsChallengeKeyContent": "-----omitted from sample-----",
                    "tlsChallengeUrl": "https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/7139283/SjNpbA"
            },
            {
                    "domainName": "letsencrypt.example2.de",
                    "authenticationUrl": "https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/7139174",
                    "authExpiryDate": "2019-09-12T08:26:10Z",
                    "challengeToken": "-----omitted from sample-----",
                    "httpChallengeContent": "-----omitted from sample-----",
                    "httpChallengeUrl": "https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/7139174/vMAd_g",
                    "dnsChallengeContent": "-----omitted from sample-----",
                    "dnsChallengeUrl": "https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/7139174/1GybMg",
                    "tlsChallengeCertContent": "-----BEGIN CERTIFICATE-----omitted from sample-----END CERTIFICATE-----",
                    "tlsChallengeKeyContent": "-----omitted from sample-----",
                    "tlsChallengeUrl": "https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/7139174/YesVuA"
            }
    ],
    "accountLocation": "https://acme-staging-v02.api.letsencrypt.org/acme/acct/10550349",
    "accountCreatedData": "2019-08-13T09:35:28Z",
    "generation": 1,
    "lastUpdateMicros": 1565696148351388,
    "kind": "cm:adc-core:external-ca:lets-encrypt:config:letsencryptconfigstate",
    "selfLink": "https://localhost/mgmt/cm/adc-core/external-ca/lets-encrypt/config/a812b8da-4a11-3dca-8bd4-7f247352c49a"
}

5. Generate challenge content for the domains

Send a POST request to the Let’s Encrypt Challenge Content API to generate challenge content for each of the domains. Challenge content is generated by Let’s Encrypt and can expire over time. The Let’s Encrypt configuration can keep track of changes and take actions involving the Let’s Encrypt server.

POST https://<BIG-IQ>/mgmt/cm/adc-core/external-ca/lets-encrypt/challenge

The JSON in the body of the POST request can look similar to the following example. You can use the value of authenticationUrl returned in step 4 as the value of authLocation in this step.

{
    "externalCaConfigReference": {
            "link": "https://localhost/mgmt/cm/adc-core/external-ca/config/5194e771-18d1-377d-8706-1d3102ebb312"
    },
    "authLocation": "https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/3919567",
    "accountLocation": "https://acme-staging-v02.api.letsencrypt.org/acme/acct/10550349"
}

6. Authenticate for domains

Send a POST request to the Let’s Encrypt Authenticate API to authenticate for the domains. The Let’s Encrypt server uses the challenge contents saved in the previous step to authenticate the domains. The Let’s Encrypt configuration orchestrates the authentication.

POST https://<BIG-IQ>/mgmt/cm/adc-core/external-ca/lets-encrypt/authenticate

The JSON in the body of the POST request can look similar to the following example.

{
    "externalCaConfigReference": {
            "link": "https://localhost/mgmt/cm/adc-core/external-ca/config/5194e771-18d1-377d-8706-1d3102ebb312"
    },
    "authenticationUrl": "https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/3919567",
    "forceValidate": false,
    "checkOnlyStatus": false,
    "status": "valid",
    "generation": 0,
    "lastUpdateMicros": 0
}

7. Request a signed certificate

After the previous steps have been completed, the BIG-IQ is ready to request a signed certificate from the Let’s Encrypt server. Send a POST request to the Let’s Encrypt Request Certificate API to request a signed certificate by proving the certificate signing request (CSR).

POST https://<BIG-IQ>/mgmt/cm/adc-core/external-ca/lets-encrypt/csr-request

The JSON in the body of the POST request can look similar to the following example.

{
    "certificateName": "le_cert",
    "domainName": "letsencrypt.example1.de",
    "externalCaConfigReference": {
            "link": "https://localhost/mgmt/cm/adc-core/external-ca/config/5194e771-18d1-377d-8706-1d3102ebb312"
    }
}