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.
- 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 ↗.
- Run the following command to generate a 4096-bit RSA private key, using AES-256 encryption. Enter a passphrase when prompted.
openssl genrsa -aes256 -out rootca.key 4096
- 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.
openssl req -x509 -new -nodes -key rootca.key -sha256 -days 1826 -out rootca.crt
- 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.
openssl req -new -nodes -out cert.csr -newkey rsa:4096 -keyout cert.key
- Sign the certificate using the
rootca.key
androotca.crt
created in previous steps.
openssl x509 -req -in cert.csr -CA rootca.crt -CAkey rootca.key -CAcreateserial -out cert.crt -days 730 -sha256 -extfile ./cert.v3.ext
- Make sure the certificate extensions file
cert.v3.ext
specifies the following:
basicConstraints=CA:FALSE
- Upload the
rootca.cert
to an S3 bucket ↗. - Create a trust store ↗ at your EC2 console, indicating the S3 URI where you uploaded the certificate.
- 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 ↗.
sudo yum install -y httpdsudo systemctl start httpd
- Create a target group ↗ for your Application Load Balancer.
- Choose Instances as target type.
- Specify port
HTTP/80
.
- After you finish configuring the target group, confirm that the target group is healthy ↗.
- 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.
- Save your settings.
- (Optional) Run the following commands to confirm that the Application Load Balancing is asking for the client certificate.
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:
curl --verbose https://<your-application-load-balancer>...* TLSv1.2 (IN), TLS handshake, Request CERT (13):...
- Upload the certificate you created in Step 1 to Cloudflare. You should use the leaf certificate, not the root CA.
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.
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>" } ]}'
- Enable the Authenticated Origin Pulls feature on your zone.
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"}'
- Use a
PUT
request to disable Authenticated Origin Pulls on the hostname.
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>" } ]}'
- (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.
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"
- Use the Delete hostname client certificate endpoint to remove the certificate you had uploaded.
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"