'Install SSL certificates in my AWS canary puppeteer script

I am trying to write a script for testing my API which is deployed in AWS EKS in Cloudwatch synthetics (Canary). But I don't see the provision to add my certificate and key along with my API request.

How can I insert certificate along with the request header of the API? In my local I am appending the certificates using fs and append it to the axios headers. If the certificate needs to be append in puppeteer script, how can I achieve it?

Error message for reference

ERROR: Request failed. Request: https://myapirequestdns.com/api/v1.0/testroute/testdomain ERROR: Failure reason: Error: read ECONNRESET Stack: Error: read ECONNRESET at TLSWrap.onStreamRead (internal/stream_base_commons.js:209:20) at TLSWrap.callbackTrampoline (internal/async_hooks.js:130:17)



Solution 1:[1]

This is the code we use at the top of our canary function running syn-nodejs-puppeteer-3.5 to retrieve and use a certificate, private key, and CA from AWS secrets manager:

const synthetics = require('Synthetics');
const log = require('SyntheticsLogger');
const syntheticsConfiguration = synthetics.getConfiguration();

const AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});
const secretsManager = new AWS.SecretsManager();

// We need to load a client certificate to authenticate to endpoints that require mTLS, specified in these env variables
const secretName    = process.env.SECRET_NAME
const keyItemName   = process.env.KEY_ITEM_NAME
const certItemName  = process.env.CERT_ITEM_NAME
const caItemName    = process.env.CA_ITEM_NAME

// Function to retrieve specified key/cert from specified secret and return them as plain strings
const getKeyAndCertAndCA = async function () {
  // Retrieve secret
  const data    = await secretsManager.getSecretValue({SecretId: process.env.SECRET_NAME}).promise();
  // Turn secret string into object
  const secret  = JSON.parse(data.SecretString);
  // Base64 decode the cert and key and return them
  const key     = Buffer.from(secret[keyItemName], 'base64').toString('ascii');
  const cert    = Buffer.from(secret[certItemName], 'base64').toString('ascii');
  const ca      = Buffer.from(secret[caItemName], 'base64').toString('ascii');
  return [ key, cert, ca ];
}

Then, just inside the apiCanaryBlueprint function, load the key/cert/CA

const apiCanaryBlueprint = async function () {
    // Load TLS client cert and key for calls requiring TLS
    const [ key, cert, ca ] = await getKeyAndCertAndCA();

and then later, when setting requestOptions, specify the key, cert, and ca parameters:

      let requestOptions = {
          hostname: url.host,
          method: 'GET',
          path: url.path,
          port: '443',
          protocol: 'https:',
          body: "",
          headers: {},
          key: key,
          cert: cert,
          ca: ca
          };
  • You must configure your canary environment variables to specify the secret name and what keys (not private key) the certificate, private key, and CA are stored under within the secret;
  • The secret item must have the cert, private key, and CA included as base64 strings.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 TonyLovesDevOps