Fastly CDN (VCL)
DataDome Fastly module detects and protects against bot activity.
DataDome Bot protection can be integrated directly inside Fastly.
Before the regular Fastly process starts, a preflight request is performed on the closest DataDome endpoint. Depending on the API response, the module either blocks the request or lets Fastly proceed with the regular process.
The module has been implemented to ensure the best user experience: if any errors were to occur during the preflight, or if the timeout is reached, the module will automatically disable its blocking mechanism and allow the regular Fastly process to proceed.
Prerequisites
You need to Contact Fastly support to enable some features to be able to use DataDome Bot Protection
Send an email :
- To: [email protected]
- Subject: Pragmas needed on Service XXXXXXXXXX for DataDome support
In order to enable DataDome support please set these pragmas:
• fix_unsent_body_drain
• no_body_if_bereq_is_get_or_head
on the following service:
• Service XXXXXXXXXX
• Account YYYYYYYYYY
Thanks!
How to integrate DataDome Bot Protection inside Fastly ?
DataDome provides 3 integration options:
- A. [Recommended] VCL snippets through the Fastly dashboard
- B. Dynamic snippets through the Fastly API
- C. [Deprecated]Custom VCL through the Fastly dashboard
You can find the code here
A. VCL snippets through the Fastly dashboard
Before integrating DataDome, you need to ask Fastly Support to enable DataDome support for your Fastly service as described here.
- Create a Fastly service or use an existing one, then create a new version of this service by cloning the actual one.
- Go to VCL snippets
- Download and extract our Fastly module. Fastly snippets are available inside the snippet folder. Upload them one by one :
- Start with the
init
one.
Update your own server server key (You can find it inside our dashboard) on line
- Do the same things from all others vcl snippets :
recv
,miss
,pass
,fetch
,error
anddeliver
).
For each one, you need to select the corresponding subroutine.
At the end you should have 7 snippets like this. Double check for each one the type is correct.
- Click
activate
to deploy the new Fastly configuration.
- You are now protected by DataDome
B. Regular VCL snippets with Terraform
You need to provide Terraform with your Fastly API key.
Follow the Fastly documentation to create it.
When you have your key, you must export a FASTLY_API_KEY
environment variable in the shell from where you will launch Terraform commands
export FASTLY_API_KEY=<your API key>
.
- Copy/Paste
locals
variable anddynamic snippet
block in your exising Terraform code.
provider "fastly" {}
locals {
# Define all the datadome snippet names needed here
datadome_snippets = toset([
"init",
"recv",
"pass",
"fetch",
"deliver",
"miss",
"error"
])
}
# Create fastly service
resource "fastly_service_v1" "main" {
# name = "datadome_protected_service"
# your existing domain
# your existing backend
# This dynamic block create a `snippet` block
# for each datadome snippet defined in the locals
dynamic "snippet" {
for_each = local.datadome_snippets
content {
type = snippet.value
priority = 10
name = format("datadome_%s", snippet.value)
content = file(format("%s/%s.vcl", path.module, snippet.value))
}
}
}
C. Custom VCL
- Download the latest version of the module
- Connect to your Fastly console, and go to the Configuration tab
- Switch to Required Services
- Click
configuration
->clone active
- Go to
Origin
->Hosts
- Confirm that another upstream has the name
origin
- Go to Custom VCL and click
Upload your first VCL file
- Input name, for example
datadome
, and uploaddatadome.vcl
from the distribution
- Click Create
- Go into the file and update the code at the
Edit VCL
block. You must replace your Server API Key ([that you can find inside your Dashboard](https://app.datadome.co/dashboard/config/protection/keys>) ) near line 48
- Update Shield Backend Name with the actual name near line 460. If you don't use it, feel free to comment this line
- Click the
Activate
button on the top-right side
Settings
The Fastly module doesn't have a dedicated block for settings and you should update them in a different location in the file.
Setting | Line number | Comments |
---|---|---|
License key | ~48 | Your license key |
Timeout | Backend configuration | Fastly uses standard varnish timeouts. You can find the details here |
Regex | ~381 | Regex that should be matched or not matched to process the request in DataDome |
datadome_restore_referrer | ~125 | Set to true to restore original referrer when a challenge is passed. |
datadome_enable_graphql_support | ~127 | Set to true to enable GraphQL extraction of operation name on POST request. |
datadome_enable_replay_protection | ~129 | Set to true to prevent replay attack in case of Early-Data requests. |
Shielding
This only applies to custom VCL.
If you use shielding you should update the shield backend name and the region name inside the FASTLY recv
. This is region specific, and the backend name depends on your use of SSL/TLS to connect to your upstream. All theses values are actual for 2020-03-04T12:12:44Z
Name | Condition | Backend | SSL Backend |
---|---|---|---|
Amsterdam | -AMS | shield_amsterdam_nl | ssl_shield_amsterdam_nl |
Ashburn - BWI | -BWI | shield_bwi_va_us | ssl_shield_bwi_va_us |
Ashburn - DCA | -DCA | shield_dca_dc_us | ssl_shield_dca_dc_us |
Atlanta - FTY | -FTY | shield_fty_ga_us | ssl_shield_fty_ga_us |
Atlanta - PDK | -PDK | shield_pdk_ga_us | ssl_shield_pdk_ga_us |
Auckland | -AKL | shield_auckland_akl | ssl_shield_auckland_akl |
Bogota | -BOG | shield_bog_bogota_co | ssl_shield_bog_bogota_co |
Boston | -BOS | shield_bos_ma_us | ssl_shield_bos_ma_us |
Brisbane | -BNE | shield_brisbane_au | ssl_shield_brisbane_au |
Cape Town | -CPT | shield_cpt_capetown_za | ssl_shield_cpt_capetown_za |
Chicago - CHI | -CHI | shield_chi_il_us | ssl_shield_chi_il_us |
Chicago - MDW | -MDW | shield_mdw_il_us | ssl_shield_mdw_il_us |
Chicago - PWK | -PWK | shield_pwk_il_us | ssl_shield_pwk_il_us |
Copenhagen | -CPH | shield_cph_copenhagen_dk | ssl_shield_cph_copenhagen_dk |
Dallas | -DFW | shield_dallas_tx_us | ssl_shield_dallas_tx_us |
Dallas - DAL | -DAL | shield_dal_tx_us | ssl_shield_dal_tx_us |
Denver | -DEN | shield_den_co_us | ssl_shield_den_co_us |
Dublin | -DUB | shield_dub_dublin_ie | ssl_shield_dub_dublin_ie |
Frankfurt | -FRA | shield_frankfurt_de | ssl_shield_frankfurt_de |
Frankfurt - Interxion | -HHN | shield_hhn_frankfurt_de | ssl_shield_hhn_frankfurt_de |
Fujairah Al Mahta | -FJR | shield_fjr_ae | ssl_shield_fjr_ae |
Helsinki | -HEL | shield_hel_helsinki_fi | ssl_shield_hel_helsinki_fi |
Hong Kong | -HKG | shield_hongkong_hk | ssl_shield_hongkong_hk |
Houston | -IAH | shield_iah_tx_us | ssl_shield_iah_tx_us |
Jacksonville | -JAX | shield_jax_fl_us | ssl_shield_jax_fl_us |
Johannesburg | -JNB | shield_jnb_johannesburg_za | ssl_shield_jnb_johannesburg_za |
London - LCY | -LCY | shield_london_city_uk | ssl_shield_london_city_uk |
London - LON | -LON | shield_lon_london_uk | ssl_shield_lon_london_uk |
London - Slough | -LHR | shield_london_uk | ssl_shield_london_uk |
Los Angeles - BUR | -BUR | shield_bur_ca_us | ssl_shield_bur_ca_us |
Los Angeles - LAX | -LAX | shield_lax_ca_us | ssl_shield_lax_ca_us |
Madrid | -MAD | shield_mad_madrid_es | ssl_shield_mad_madrid_es |
Manchester | -MAN | shield_man_manchester_uk | ssl_shield_man_manchester_uk |
Melbourne | -MEL | shield_melbourne_au | ssl_shield_melbourne_au |
Miami | -MIA | shield_miami_fl_us | ssl_shield_miami_fl_us |
Milan | -MXP | shield_mxp_milan_it | ssl_shield_mxp_milan_it |
Minneapolis | -MSP | shield_msp_mn_us | ssl_shield_msp_mn_us |
Montreal | -YUL | shield_yul_montreal_ca | ssl_shield_yul_montreal_ca |
New York City | -JFK | shield_jfk_ny_us | ssl_shield_jfk_ny_us |
New York City - LGA | -LGA | shield_lga_ny_us | ssl_shield_lga_ny_us |
Newark | -EWR | shield_ewr_nj_us | ssl_shield_ewr_nj_us |
Osaka | -ITM | shield_osaka_jp | ssl_shield_osaka_jp |
Oslo | -OSL | shield_osl_oslo_no | ssl_shield_osl_oslo_no |
Palo Alto | -PAO | shield_pao_ca_us | ssl_shield_pao_ca_us |
Paris | -CDG | shield_cdg_par_fr | ssl_shield_cdg_par_fr |
Perth | -PER | shield_perth_au | ssl_shield_perth_au |
San Jose | -SJC | shield_sjc_ca_us | ssl_shield_sjc_ca_us |
Sao Paulo | -GRU | shield_gru_br_sa | ssl_shield_gru_br_sa |
Seattle | -SEA | shield_sea_wa_us | ssl_shield_sea_wa_us |
Singapore | -SIN | shield_singapore_sg | ssl_shield_singapore_sg |
Stockholm | -BMA | shield_stockholm_bma | ssl_shield_stockholm_bma |
Sydney | -SYD | shield_sydney_au | ssl_shield_sydney_au |
Tokyo | -TYO | shield_tyo_tokyo_jp | ssl_shield_tyo_tokyo_jp |
Tokyo - HND | -HND | shield_hnd_tokyo_jp | ssl_shield_hnd_tokyo_jp |
Toronto | -YYZ | shield_yyz_on_ca | ssl_shield_yyz_on_ca |
Vienna | -VIE | shield_vie_vienna_at | ssl_shield_vie_vienna_at |
Wellington | -WLG | shield_wellington_wlg | ssl_shield_wellington_wlg |
FAQ
- Subject: Pragmas needed on Service XXXXXXXXXX for DataDome support
In order to enable DataDome support please set these pragmas:
• fix_unsent_body_drain
• no_body_if_bereq_is_get_or_head
on the following service:
• Service XXXXXXXXXX
• Account YYYYYYYYYY
Thanks!
How to log the enriched headers?
Before any setup, please read carefully our requirements about the enriched headers.
- Setup a real-time logging providers
- Edit the log format. DataDome's headers are available in the
req.http
object. For examplereq.http.x-datadome-isbot
.
Please, find below an example with Loggly:
{
"timestamp":"%{begin:%Y-%m-%dT%H:%M:%S}t",
"client_ip":"%{req.http.Fastly-Client-IP}V",
"geo_country":"%{client.geo.country_name}V",
"geo_city":"%{client.geo.city}V",
"url":"%{json.escape(req.url)}V",
"request_referer":"%{json.escape(req.http.referer)}V",
"request_user_agent":"%{json.escape(req.http.User-Agent)}V",
"fastly_is_edge":%{if(fastly.ff.visits_this_service == 0, "true", "false")}V,
"response_state":"%{json.escape(fastly_info.state)}V",
"response_status":%{resp.status}V,
"response_reason":%{if(resp.response, "%22"+json.escape(resp.response)+"%22", "null")}V,
"response_body_size":%{resp.body_bytes_written}V,
"request_method":"%{json.escape(req.method)}V",
"request_protocol":"%{json.escape(req.proto)}V",
"fastly_server":"%{json.escape(server.identity)}V",
"host":"%{if(req.http.Fastly-Orig-Host, req.http.Fastly-Orig-Host, req.http.Host)}V",
"datadome-isbot":"%{json.escape(req.http.x-datadome-isbot)}V",
"datadome-botname":"%{json.escape(req.http.x-datadome-botname)}V",
"datadome-ruletype":"%{json.escape(req.http.x-datadome-ruletype)}V",
"datadome-captchapassed":"%{json.escape(req.http.x-datadome-captchapassed)}V"
}
POST requests with a body are broken
You should ask Fastly Support to enable DataDome support for your Fastly service as described here.
How to integrate DataDome Bot Protection with Signal Sciences WAF
Both integrations can work together with a configuration change on the custom VCL's miss
and pass
subroutine snippets.
The call to edge_security
that triggers Signal Sciences should only be done when the request is not being handled by DataDome, meaning that any call edge_security
line should be replaced with the following piece of code:
if (req.backend != datadome) {
call edge_security;
}
Find below an example of how the generated final VCL should look like in the miss
and pass
subroutine snippets:
sub vcl_miss {
#--FASTLY MISS BEGIN
[...]
if (req.backend != datadome) {
call edge_security;
}
# Snippet datadome_miss : 100
# Start of `miss.vcl` for DataDome-2.19.0
call set_origin_header;
# End of `miss.vcl` for DataDome-2.19.0
#--FASTLY MISS END
return(fetch);
}
sub vcl_pass {
#--FASTLY PASS BEGIN
[...]
if (req.backend != datadome) {
call edge_security;
}
# Snippet datadome_pass : 100
# Start of `pass.vcl` for DataDome-2.19.0
call set_origin_header;
# End of `pass.vcl` for DataDome-2.19.0
#--FASTLY PASS END
}
How to restore the Referer
request header after a challenge has been passed?
Referer
request header after a challenge has been passed?When passing a DataDome challenge on browsers other than Firefox, the referrer value is updated which can lead to inconsistent results in website analytics.
To restore the Referer
header to its original value for your backend:
- Contact our support team, they will review your requirements and provide you with the best recommendations.
- Ensure that you have DataDome Fastly module version 2.20.4 or higher,
- Set the boolean value of
datadome_restore_referrer
totrue
in thevcl_recv
subroutine.
sub vcl_recv {
# Configure the regular expression below to match URLs that
# should be checked by DataDome
declare local var.datadome_restore_referrer BOOL;
# set var.datadome_restore_referrer = true; # uncomment to enable
How can I enable GraphQL support on POST
requests?
POST
requests?Starting from version 2.21.0
it is possible to enable graphQL support and extract operation type and operation name from the request body.
- Set the boolean value of
datadome_enable_graphql_support
totrue
in thevcl_recv
subroutine.
set var.datadome_enable_graphql_support = true; # uncomment to enable
Once enabled, POST
requests targeting a graphql
endpoint with content-type: application/json
will be analysed to extract GraphQL operation name and type.
Updated 5 days ago