AWS CloudFront
This module is for AWS CloudFront distributions, using the AWS CloudFront Lambda@Edge service.
Supported Runtimes¶
Peakhour supports Lambda runtimes until they reach their deprecation date. You can find the list of supported runtimes in this AWS documentation.
Peakhour supports the following Lambda runtimes:
Language | Supported runtimes |
---|---|
Node.js | nodejs18.x , nodejs20.x , nodejs22.x |
Python | python3.9 , python3.10 , python3.11 , python3.12 , python3.13 |
Installation¶
Prerequisites¶
- Your Peakhour API key, available in your Peakhour account.
- Your domain configured to use Peakhour.
AWS IAM permissions¶
To associate your Lambda@Edge function with your CloudFront distribution and to record logs, you need to create IAM permissions and roles.
- Go to the Identity and Access Management (IAM) page, in the Policies tab.
- Click on the Create policy button.
-
Select JSON in the Policy editor, and paste the following permissions:
View required IAM policy
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "iam:CreateServiceLinkedRole", "lambda:GetFunction", "cloudfront:UpdateDistribution", "lambda:EnableReplication" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": [ "*" ] } ] }
-
Click Next, enter a name for this policy, and click Save.
- Go to the IAM page, in the Role tab.
- Click Create role.
- Select the Trusted entity type to AWS service, select the Use case to Lambda, and click Next.
- Select the IAM policy created in step 4 and click Next.
- Enter a name for this role, and click Create role.
- Click on the Trust relationships tab and Edit trust policy.
-
Paste the following trusted service principals to assume function execution role for your Lambda@Edge:
Configuration of the CloudFront distribution¶
If you don't already have one, refer to this AWS documentation to create a CloudFront distribution.
Create a custom error 403 response¶
This disables the caching of responses with a 403
HTTP code.
- Go to your CloudFront distribution page in the Error pages tab, and click Create custom error response.
- In the Create custom error response page, set the following properties:
- Select HTTP code 403.
- Set minimal TTL 0.
- Check No for Customise error response.
- Click Create custom error response.
Configure the distribution's default behaviour¶
This defines the default behaviour of the CloudFront distribution.
- Go to your CloudFront distribution page in the Behaviours tab, and edit the default behaviour.
- In the Cache key and origin requests section, select Cache policy and origin request policy and set the Origin request policy to
AllViewerExceptHostHeader
. - Click Save changes.
Configuration of the AWS Lambda@Edge function¶
In this section, you will create and configure the AWS Lambda@Edge function to intercept incoming requests and validate them with our service.
Note: It is possible to call and configure the Lambda@Edge function through an existing one. Refer to the advanced configuration section to use an existing Lambda@Edge function.
- Connect to your AWS console and go to the Lambda@Edge homepage.
-
Create a new Lambda@Edge function.
Important: The function must be created in the
us-east-1
region. AWS automatically selects theus-east-1
region when you access the Lambda@Edge portal. Please do not change the region. -
Click Create function, then select Author from scratch.
- In the Basic information section:
- Enter a name for your Lambda function, e.g.
Peakhour-WAF-{YOUR WEBSITE NAME}
. - Select
Node.js 20.x
orPython 3.12
for the runtime. - Click Create function.
- Enter a name for your Lambda function, e.g.
-
In the Code source tab, choose Upload a file from Amazon S3 and paste the URL for the selected module.
https://s3.amazonaws.com/peakhour-lambda-edge/peakhour-lambda-edge-latest.zip
https://s3.amazonaws.com/peakhour-lambda-edge/peakhour-lambda-edge-py-latest.zip
-
Open the
peakhour.js
file (for the Node.js runtime) orpeakhour.py
(for the Python runtime). - Replace
YOUR_PEAKHOUR_API_KEY
with your own Peakhour API key, available in your Peakhour account. You will also need to enter your domain name. - Scroll down to the Runtime settings tab, click Edit.
- In the Runtime settings page:
- Enter the handler name in the Handler field.
=== "Node.js"
peakhour.handler
=== "Python"peakhour.lambda_handler
- Click Save.
- Enter the handler name in the Handler field.
=== "Node.js"
- In the Configuration tab and General configuration menu, click Edit.
- In the Edit basic settings page:
- Set Timeout to 1 sec.
- Select an existing role with the required permissions.
- Click Save.
- Click Actions and select Deploy to Lambda@Edge.
- In the Deploy to Lambda@Edge window, provide the following configuration:
- Select the CloudFront distribution that will send events to the Lambda function.
- Select the default Cache behaviour (
*
). - Select Viewer Request for CloudFront Event.
- Do not check the Include body box.
- Check the Confirm deploy to Lambda@Edge box.
- Click Deploy.
Note: Protection is not operational when the Lambda function is associated with
origin request
. CloudFront will cache requests, even if caching is completely disabled. Most requests will be executed by the AWS caching mechanism, with modified headers (likeuser-agent: Amazon CloudFront
), and will not be intercepted by the Peakhour module. If there is already another function associated with theviewer request
event, refer to the use of an existing lambda function to merge them.
Congratulations! You can now see your traffic in your Peakhour dashboard.
You can refer to the recommended configuration below to enhance the protection of your CloudFront distribution.
Recommended configuration¶
Disable CloudFront caching for requests protected by Peakhour¶
If you are caching dynamic requests (not javascript, css, images) at the CloudFront level and these requests are protected by Peakhour, you must change your backend origin to ask CloudFront not to cache these requests if they contain a set-cookie
in the response.
By default, CloudFront will cache HTTP requests even if the backend returned a cookie. This can lead to unexpected bot detection issues. Your backend/origin needs to return this header: Cache-Control: no-cache="Set-Cookie"
.
You can find more information about this CloudFront behaviour in AWS Documentation, in the Disable caching of Set-Cookie headers section.
If you were caching files that were also protected by Peakhour, you may want to invalidate the cache by following this CloudFront documentation.
Include Client Hints and Fetch Metadata in request headers¶
Client Hints and Fetch Metadata can be collected by the Peakhour module to enhance detection.
For these values to be defined by the browser, an Accept-CH
header must be sent by the origin. You can achieve this by using a response header policy.
- Go to the CloudFront distribution that you want to configure.
- In the Cache key and origin requests section, on the Response headers policy part click Create response headers policy to enable HTTP Client hints.
- In the Create response headers policy tab, set the following:
- On the Details section, set the response headers policy's name: Accept-CH-and-Vary.
- On the Custom headers section, click Add header.
- Set the following values for the new custom headers:
- For the Client Hint:
- Name: Accept-CH.
- Value:
Sec-CH-UA,Sec-CH-UA-Mobile,Sec-CH-UA-Platform,Sec-CH-UA-Arch,Sec-CH-UA-Full-Version-List,Sec-CH-UA-Model,Sec-CH-Device-Memory
. - Check Yes for the Origin override.
- For the Fetch Metadata:
- Name: Vary
- Value:
Sec-Fetch-Dest,Sec-Fetch-Mode,Sec-Fetch-Site,Sec-Fetch-User
. - Check Yes for the Origin override.
- For the Client Hint:
- Click Create.
- Back on the CloudFront distribution page, refresh the response headers policy list and select your Accept-CH-and-Vary custom header.
- Click Save changes.
Associate the Lambda@Edge with non-default distribution behaviours¶
By default, the Lambda@Edge is associated with the default behaviour of the distribution you selected, meaning that requests going through other behaviours, which are ranked higher, will not be protected.
- Go to the CloudFront distribution console that you want to configure.
- Click on Behaviours.
- Select one of the behaviours you want to protect, and click Edit.
- Associate the Lambda@Edge function on the Viewer Request and copy the Peakhour Lambda@Edge ARN, which includes the version number.
- Click Save changes.
Advanced configuration¶
Settings¶
By default, the configuration is located in the first code block of the peakhour.js
(or peakhour.py
) file.
Refer to the list below for the possible configuration settings.
Setting | Description | Required | Default |
---|---|---|---|
PEAKHOUR_API_KEY |
Your Peakhour API key, found in your Peakhour Account. | Yes | |
PEAKHOUR_DOMAIN |
Your domain name as configured in your Peakhour account. | Yes | |
PEAKHOUR_TIMEOUT |
The request timeout to Peakhour API, in milliseconds. | Optional | 300 |
PEAKHOUR_URI_REGEX_INCLUDE |
Regular expression to include URIs in the Peakhour analysed traffic. | Optional | |
PEAKHOUR_URI_REGEX_EXCLUDE |
Regular expression to exclude URIs from the Peakhour analysed traffic. | Optional | List of excluded static assets |
PEAKHOUR_USE_X_FORWARDED_HOST |
Use the X-Forwarded-Host header instead of Host when the application is behind a reverse proxy/load balancer. |
Optional | false |
Note: It is not possible to use environment variables in Lambda@Edge due to an AWS limitation - see Restrictions on edge functions. However you can still follow the steps to configure the module from another function file and override a configuration depending on AWS Secrets Manager for instance.
Protect only a part of a CloudFront Distribution¶
To protect only a part of a CloudFront Distribution, select one of the possibilities below:
- Option 1: Set an exclusion based on file extension. Modify the value
PEAKHOUR_URI_REGEX_EXCLUDE
insidepeakhour.js
(orpeakhour.py
) to exclude hits to the Peakhour API. In this case, the Lambda@Edge function is still executed (and billed) at the Amazon infrastructure level. - Option 2: Set an exclusion based on the path. Define a behaviour in your CloudFront Distribution and attach the Lambda@Edge only to the needed paths. In this case, there is no Lambda execution at the Amazon infrastructure level.
Advanced: Use an existing Lambda@Edge function (only supported with Node.js)
Calling and configuring the module can be done from another file.
The following example explains how to update a handler in an index.js
file.
- Import the Peakhour code as mentioned above.
-
Import the Peakhour module inside your
index.js
file: -
Configure the Peakhour module inside your
index.js
file:// Configure Peakhour module const configuration = { apiKey: 'YOUR_PEAKHOUR_API_KEY', domain: 'your-domain.com', timeout: 300, uriPatternInclusion: null, uriPatternExclusion: /\.(avi|flv|mka|mkv|mov|mp4|mpeg|mpg|mp3|flac|ogg|ogm|opus|wav|webm|webp|bmp|gif|ico|jpeg|jpg|png|svg|svgz|swf|eot|otf|ttf|woff|woff2|css|less|js|map)$/i }; peakhour.configure(configuration);
Note: Update the configuration values (
apiKey
anddomain
are mandatory). Other keys are shown with their default values. -
Update your handler from the
index.js
file to execute the Peakhour protection:exports.handler = (event, context, callback) => { // Call Peakhour handler peakhour.handler(event, context, callback); // [...] }
- Ensure that the handler configured for this Lambda@Edge is
index.handler
in the Runtime settings section.
- Ensure that the handler configured for this Lambda@Edge is
Upgrade¶
To update the code of the Lambda@Edge and publish a new version, apply the following steps:
- Select the lambda function to update.
- Store the active configuration of the module (List of possible settings).
- Click Upload from then Amazon S3 location.
-
Paste the right S3 location depending on the runtime used for the lambda and click Save.
https://s3.amazonaws.com/peakhour-lambda-edge/peakhour-lambda-edge-latest.zip
https://s3.amazonaws.com/peakhour-lambda-edge/peakhour-lambda-edge-py-latest.zip
-
Replace
YOUR_PEAKHOUR_API_KEY
with your Peakhour API key. - Restore other specific configurations stored during Step 2.
- Click Actions and Deploy to Lambda@Edge to deploy this up-to-date version.
- Select the CloudFront distribution and click Deploy.
FAQ¶
How can I integrate Peakhour on a multi-account architecture?¶
If you have multiple CloudFront distributions deployed on different AWS accounts, one Lambda@Edge function per account is required.
You must repeat the configuration of the CloudFront distribution and the configuration of the Lambda@Edge function section for each of your distributions.
Can I integrate Peakhour on CloudFront Functions?¶
It is not possible to set up Peakhour inside CloudFront Functions as they do not provide network access to call third-party APIs. See Restrictions on CloudFront Functions.