Skip to content

AWS integration

This guide will walk you through how to set up per-hostname authenticated origin pulls to securely connect to an AWS Application Load Balancer using mutual TLS verify.

You can also find instructions on how to rollback this setup in Cloudflare.

Before you begin

  • You should already have your AWS account and EC2 configured.
  • Note that this tutorial uses command-line interface (CLI) to generate a custom certificate, and API calls to configure Cloudflare Authenticated Origin Pulls.
  • For the most up-to-date documentation on how to set up AWS, refer to the AWS documentation.

1. Generate a custom certificate

  1. Run the following command to generate a 4096-bit RSA private key, using AES-256 encryption. Enter a passphrase when prompted.
Terminal window
openssl genrsa -aes256 -out rootca.key 4096
  1. Create the CA root certificate. When prompted, fill in the information to be included in the certificate. For the Common Name field, use the domain name as value, not the hostname.
Terminal window
openssl req -x509 -new -nodes -key rootca.key -sha256 -days 1826 -out rootca.crt
  1. Create a Certificate Signing Request (CSR). When prompted, fill in the information to be included in the request. For the Common Name field, use the hostname as value.
Terminal window
openssl req -new -nodes -out cert.csr -newkey rsa:4096 -keyout cert.key
  1. Sign the certificate using the rootca.key and rootca.crt created in previous steps.
Terminal window
openssl x509 -req -in cert.csr -CA rootca.crt -CAkey rootca.key -CAcreateserial -out cert.crt -days 730 -sha256 -extfile ./cert.v3.ext
  1. Make sure the certificate extensions file cert.v3.ext specifies the following:
basicConstraints=CA:FALSE

2. Configure AWS Application Load Balancer

  1. Upload the rootca.cert to an S3 bucket.
  2. Create a trust store at your EC2 console, indicating the S3 URI where you uploaded the certificate.
  3. Create an EC2 instance and install an HTTPD daemon. Choose an instance type according to your needs - it can be a minimal instance eligible to AWS Free Tier. This tutorial was based on an example using t2.micro and Amazon Linux 2023.
Terminal window
sudo yum install -y httpd
sudo systemctl start httpd
  1. Create a target group for your Application Load Balancer.
    • Choose Instances as target type.
    • Specify port HTTP/80.
  2. After you finish configuring the target group, confirm that the target group is healthy.
  3. Configure a load balancer and a listener.
    • Choose the Internet-facing scheme.
    • Switch the listener to port 443 so that the mTLS option is available, and select the target group created in previous steps.
    • For Default SSL/TLS server certificate, choose Import certificate > Import to ACM, and add the certificate private key and body.
    • Under Client certificate handling, select Verify with trust store.
  4. Save your settings.
  5. (Optional) Run the following commands to confirm that the Application Load Balancing is asking for the client certificate.
Terminal window
openssl s_client -verify 5 -connect <your-application-load-balancer>:443 -quiet -state

Since you have not yet uploaded the certificate to Cloudflare, the connection should fail (read:errno=54, for example).

You can also run curl --verbose and confirm Request CERT (13) is present within the SSL/TLS handshake:

Terminal window
curl --verbose https://<your-application-load-balancer>
...
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
...

3. Configure Cloudflare

  1. Upload the certificate you created in Step 1 to Cloudflare. You should use the leaf certificate, not the root CA.
Terminal window
MYCERT="$(cat cert.crt|perl -pe 's/\r?\n/\\n/'|sed -e 's/..$//')"
MYKEY="$(cat cert.key|perl -pe 's/\r?\n/\\n/'|sed -e's/..$//')"
request_body=$(< <(cat <<EOF
{
"certificate": "$MYCERT",
"private_key": "$MYKEY",
"bundle_method":"ubiquitous"
}
EOF
))
# Push the certificate
curl --silent \
"https://api.cloudflare.com/client/v4/zones/$ZONEID/origin_tls_client_auth/hostnames/certificates" \
--header "Content-Type: application/json" \
--header "X-Auth-Email: $MYAUTHEMAIL" \
--header "X-Auth-Key: $MYAUTHKEY" \
--data "$request_body"

2.Associate the certificate with the hostname that should use it.

Terminal window
curl --silent --request PUT \
"https://api.cloudflare.com/client/v4/zones/$ZONEID/origin_tls_client_auth/hostnames" \
--header "Content-Type: application/json" \
--header "X-Auth-Email: $MYAUTHEMAIL" \
--header "X-Auth-Key: $MYAUTHKEY" \
--data '{
"config": [
{
"enabled": true,
"cert_id": "<CERT_ID>",
"hostname": "<YOUR_HOSTNAME>"
}
]
}'
  1. Enable the Authenticated Origin Pulls feature on your zone.
Terminal window
curl --request PATCH \
"https://api.cloudflare.com/client/v4/zones/$ZONEID/settings/tls_client_auth" \
--header "X-Auth-Email: $MYAUTHEMAIL" \
--header "X-Auth-Key: $MYAUTHKEY" \
--header "Content-Type: application/json" \
--data '{
"value": "on"
}'

Rollback the Cloudflare configuration

  1. Use a PUT request to disable Authenticated Origin Pulls on the hostname.
Terminal window
curl -s --request PUT \
"https://api.cloudflare.com/client/v4/zones/$ZONEID/origin_tls_client_auth/hostnames" \
--header "Content-Type: application/json" \
--header "X-Auth-Email: $MYAUTHEMAIL" \
--header "X-Auth-Key: $MYAUTHKEY" \
--data '{
"config": [
{
"enabled": false,
"cert_id": "<CERT_ID>",
"hostname": "<YOUR_HOSTNAME>"
}
]
}'
  1. (Optional) Use a GET request to obtain a list of the client certificate IDs. You will need the ID of the certificate you want to remove for the following step.
Terminal window
curl "https://api.cloudflare.com/client/v4/zones/$ZONEID/origin_tls_client_auth/hostnames/certificates" \
--header "X-Auth-Email: $MYAUTHEMAIL" \
--header "X-Auth-Key: $MYAUTHKEY"
  1. Use the Delete hostname client certificate endpoint to remove the certificate you had uploaded.
Terminal window
curl --request DELETE \
"https://api.cloudflare.com/client/v4/zones/$ZONEID/origin_tls_client_auth/hostnames/certificates/$CERTID" \
--header "X-Auth-Email: $MYAUTHEMAIL" \
--header "X-Auth-Key: $MYAUTHKEY"