Managing rules on the Fastly WAF

      Last updated July 13, 2020

    The Fastly WAF uses firewall versions. With firewall versions, you can roll back changes you've made to your WAF by deploying a previous firewall version. This allows you to quickly redeploy a known good firewall version if changes deployed to your WAF start causing false positives.

    You can also update rules individually. As Fastly publishes new rules or updates old rules, you can choose to apply those updates on a rule by rule basis at a time that's convenient for you.

    Cloning a firewall version

    Before you can manage any active rules on your WAF, you'll need to have an editable firewall version. Much like working with service versions, if the current version you're viewing is locked, you can clone the firewall version to edit it.

    Using the Fastly WAF dashboard

    To clone the firewall version in the Fastly WAF dashboard, click the clone link next to the version number. This should display a new firewall version number with a blue icon beside it.

    Using the API

    Before you can clone a firewall version, you'll need to see what your current active version is and check to see if you already have a firewall version that you're editing. If you've been editing your firewall frequently, you might have a long list of firewall versions, so you can limit the list of returns. First, you can see the full list of firewall versions for your WAF with the following request:

    1
    2
    
    curl -sg -H "Fastly-Key:$token" \
      "https://api.fastly.com/waf/firewalls/:FIREWALL_ID/versions?page[size]=5"
    

    Each version returned in that list will contain an active field and a locked field. If active is true, that firewall version is the current deployed version. If locked is true, that firewall version is no longer editable. For an uneditable firewall version, you will need to clone it to make any edits:

    1
    2
    3
    4
    
    curl -X PUT -s \
      -H "Fastly-Key:$token" \
      -H "content-type: application/vnd.api+json" \
      "https://api.fastly.com/waf/firewalls/:FIREWALL_ID/versions/:VERSION_NUMBER/clone"
    

    Activating a firewall version

    Using the Fastly WAF dashboard

    After you've made changes to your cloned firewall version, click the green Activate button to deploy the new firewall version.

    You may find you need to roll back to a previous firewall version. Use the version selector to choose the previous version, then click the green Activate button to reactivate that version.

    Using the API

    After you've made changes to your firewall version, you can activate it with the following request:

    1
    2
    3
    4
    5
    
    curl -X PUT -s \
         -H "Fastly-Key:$token" \
         -H "Content-Type: application/vnd.api+json" \
         -H "Accept: application/vnd.api+json" \
         "https://api.fastly.com/waf/firewalls/:FIREWALL_ID/versions/:VERSION_NUMBER/activate"
    

    As you make edits to your firewall, you may find that you need to quickly roll back a change that you've made. A previously used firewall version can be re-activated. When re-activated, that firewall version's associated active rules and rule revisions will be deployed.

    Firewall version deployment happens asynchronously. To check the status of your firewall version, make a GET request for the version:

    1
    2
    3
    4
    5
    
    curl -X PUT -s \
         -H "Fastly-Key:$token" \
         -H "Content-Type: application/vnd.api+json" \
         -H "Accept: application/vnd.api+json" \
         "https://api.fastly.com/waf/firewalls/:FIREWALL_ID/versions/:VERSION_NUMBER/activate"
    

    When the firewall version has been fully deployed, the last_deployment_status will be completed and the active status will be true. If the firewall version fails to deploy, the last_deployment_status will be failed and the error will be captured in the error attribute.

    Finding a rule

    Using the Fastly WAF dashboard

    Before you can add new rules to your WAF, you have to find the rules you want to add. Once you've logged into the Fastly WAF dashboard summary page for a single WAF, navigate to the Manage Rules page. From here, you can use the sidebar to filter the rules already on your WAF by Status, Publisher, or Attack type. If you'd like to see rules that are not already on your WAF, expand the Scope menu and select Include all. Aside from Status, any filters you'd previously applied would continue to filter for the rules not already on your WAF.

    the WAF Manage rules page

    Using the API

    You can also get a list of rules by making calls directly to our API using an API token of a user with at least Engineer permissions.

    Given that this will return a list of several thousand rules, using filters can help you find the rules that you're interested in. For example, you might want to see all rules for a Drupal application:

    1
    2
    
    curl -sg -H "Fastly-Key:$token" \
        "https://api.fastly.com/waf/rules?filter[waf_tags][name]=application-drupal"
    

    You can get a list of all tags for this filter:

    1
    2
    
    curl -s -H "Fastly-Key:$token" \
        "https://api.fastly.com/waf/tags"
    

    You can also filter to exclude rules already added to your firewall:

    1
    2
    
    curl -sg -H "Fastly-Key:$token" \
        "https://api.fastly.com/waf/rules?filter[waf_firewall.id][not][match]=:FIREWALL_ID"
    

    You might notice that this will again return several thousand rules. You can combine filters to return just the rules you're interested in:

    1
    2
    
    curl -sg -H "Fastly-Key:$token" \
        "https://api.fastly.com/waf/rules?filter[waf_firewall.id][not][match]=:FIREWALL_ID&filter[waf_tags][name]=application-drupal"
    

    Fastly has three publishers of firewall rules: OWASP, Trustwave, and Fastly itself. You can filter the rule list by publisher:

    1
    2
    
    curl -sg -H "Fastly-Key:$token" \
        "https://api.fastly.com/waf/rules?filter[publisher]=owasp"
    

    If you'd like to know more about how a rule would potentially block traffic, look at the Rule revision. A rule can have many revisions, which is how Fastly can update the definition of a rule without impacting your service until you're ready to update to the new revision. Rule revisions contain both the ModSec source and the generated VCL. To view a list of revisions for a rule, grab the rule ID and run a request to:

    1
    2
    
    curl -s -H "Fastly-Key:$token" \
        "https://api.fastly.com/waf/rules/:RULE_ID/revisions"
    

    To view the ModSec source and the generated VCL on a specific revision:

    1
    2
    
    curl -s -H "Fastly-Key:$token" \
        "https://api.fastly.com/waf/rules/:RULE_ID/revisions/:REVISION_NUMBER?include=source,vcl"
    

    Adding rules

    Rules that have been added to your WAF are called "active rules." This is the association between a rule, a particular revision of that rule, and a firewall version of your WAF. Before you can add any active rules to your WAF, you must have an editable firewall version.

    Using the Fastly WAF dashboard

    When you find a rule you would like to add to your WAF, use the menu on the right to select a status for the active rule. You can use the menu to set the status on any rules you'd like to add to your WAF. When you're done adding rules, click the green Activate button to deploy the firewall version with all of your newly added rules.

    add WAF rule dropdown menu

    Using the API

    You can add an active rule to your WAF via ModSec rule ID. The active rule will be added with the most recent updated revision. If Fastly releases another rule revision in the future, you can update the active rule to the most recent version at your convenience. When you add active rules to your WAF, you can use the status attribute to set the active rule to log or block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    curl -X POST -s \
      -H "Content-Type: application/vnd.api+json" \
      -H "Fastly-Key:$token" \
      -d @- \
      "https://api.fastly.com/waf/firewalls/:FIREWALL_ID/versions/:VERSION_NUMBER/rules" \
    <<JSON
    {
      "data": {
        "type": "waf_active_rule",
        "attributes": {
          "status": "log",
          "modsec_rule_id": MODSEC_RULE_ID
        }
      }
    }
    JSON
    

    You can add active rules from a previous rule revision using the rule revision ID:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    curl -X POST -s \
      -H "Content-Type: application/vnd.api+json" \
      -H "Fastly-Key:$token" \
      -d @- \
      "https://api.fastly.com/waf/firewalls/:FIREWALL_ID/versions/:VERSION_NUMBER/rules" \
    <<JSON
    {
      "data": {
        "type": "waf_active_rule",
        "attributes": {
          "status": "log"
        },
        "relationships": {
          "waf_rule_revision": {
            "data": {
              "type": "waf_rule_revision",
              "id": "RULE_REVISION_ID"
            }
          }
        }
      }
    }
    JSON
    

    If you'd like to add many rules at once, create a file to setup the JSON for your request body. You can set the status for each rule and you can use a mix of ModSec rule IDs and rule revision IDs:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    
    {
      "data": [
        {
          "type": "waf_active_rule",
          "attributes": {
            "status": "block"
          },
          "relationships": {
            "waf_rule_revision": {
              "data": {
                "type": "waf_rule_revision",
                "id": "RULE_REVISION_ID"
              }
            }
          }
        },
        {
          "type": "waf_active_rule",
          "attributes": {
            "status": "block",
            "modsec_rule_id": MODSEC_RULE_ID,
            "revision": 1
          }
        },
        {
          "type": "waf_active_rule",
          "attributes": {
            "status": "block",
            "modsec_rule_id": MODSEC_RULE_ID
          }
        }
      ]
    }
    

    The request to add these rules to a firewall version is:

    1
    2
    3
    4
    5
    6
    
    curl -X POST -s \
      -H "Content-Type: application/vnd.api+json; ext=bulk" \
      -H "Fastly-Key:$token" \
      -H "Accept: application/vnd.api+json; ext=bulk" \
      "https://api.fastly.com/waf/firewalls/:FIREWALL_ID/versions/:VERSION_NUMBER/rules" \
      -d @/path/to/json-document.json
    

    When you're done adding rules to your WAF, be sure to activate your firewall version to see those rules in production.

    Removing a rule

    If you're seeing an active rule generating false positives, you'll need to remove it from your WAF. You cannot keep the active rule on your WAF in a disabled state. Before you can remove any active rules from your WAF, you must have an editable firewall version.

    Using the Fastly WAF dashboard

    Clone the firewall version and find the rule you would like to remove. Click on the Remove link for that rule, then deploy the new firewall version. You can remove as many rules as needed before you deploy the firewall version.

    Using the API

    If you want to remove an active rule from your WAF, you can use the active rule ID to delete the rule from an editable firewall version.

    1
    2
    3
    4
    
    curl -X DELETE -s \
      -H "Content-Type: application/vnd.api+json" \
      -H "Fastly-Key:$token" \
      "https://api.fastly.com/waf/firewalls/:FIREWALL_ID/versions/:VERSION_NUMBER/rules/:ACTIVE_RULE_ID"
    

    If you would like to remove several rules at once, you can make a single bulk request. First, save your rules to a JSON file. You can reference an active rule ID or use ModSec rule IDs to remove the rules from your WAF:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    {
      "data": [
        {
          "type": "waf_active_rule",
          "attributes": {
            "modsec_rule_id": MODSEC_RULE_ID
          }
        },
        {
          "type": "waf_active_rule",
          "id": "ACTIVE_RULE_ID"
        }
      ]
    }
    

    You can then use this JSON file as the body on the delete request:

    1
    2
    3
    4
    5
    6
    
    curl -X DELETE -s \
      -H "Accept: application/vnd.api+json; ext=bulk" \
      -H "Content-Type: application/vnd.api+json; ext=bulk" \
      -H "Fastly-Key:$token" \
      "https://api.fastly.com/waf/firewalls/:FIREWALL_ID/versions/:VERSION_NUMBER/rules" \
      -d @/path/to/rules-to-delete.json
    

    When you've removed any rules you no longer need, activate the firewall version to deploy your changes to production.

    Updating a rule status to log or block

    Active rules have a status field that can be updated to change your WAF behavior. You can change the status of an active rule from log => block or from block => log. You cannot change the status of a scoring rule. Before you can change the status of any active rules on your WAF, you must have an editable firewall version.

    Using the Fastly WAF dashboard

    On an editable firewall version, find a rule with a status you need to update. Use the menu to the right of the rule to choose the status you'd prefer. You can update the status on as many rules as needed. When you're done, activate the firewall version to deploy your changes to production.

    change rule status dropdown menu

    Using the API

    On an editable firewall version, you can update a single active rule status using the active rule ID:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    curl -X PATCH -s \
      -H "Fastly-Key:$token" \
      -H "content-type: application/vnd.api+json" \
      "https://api.fastly.com.net/waf/firewalls/:FIREWALL_ID/versions/:VERSION_NUMBER/rules/:ACTIVE_RULE_ID" \
      -d @- \
    <<JSON
      {
        "data": {
          "id": "ACTIVE_RULE_ID",
          "type": "waf_active_rule",
          "attributes": {
            "status": "block"
          }
        }
      }
    JSON
    

    You can update the status of multiple active rules on your WAF using the rule revision ID or the ModSec ID for each rule. To update multiple rules at once, start by saving the request body in a JSON file:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    {
      "data": [
        {
          "type": "waf_active_rule",
          "attributes": {
            "status": "block",
            "modsec_rule_id": MODSEC_RULE_ID
          }
        },
        {
          "type": "waf_active_rule",
          "attributes": {
            "status": "block"
          },
          "relationships": {
            "waf_rule_revision": {
              "data": {
                "type": "waf_rule_revision",
                "id": "RULE_REVISION_ID"
              }
            }
          }
        }
      ]
    }
    

    Then, you can make a request to update the status of all rules listed in your JSON file:

    1
    2
    3
    4
    5
    6
    
    curl -X POST -s \
      -H "Accept: application/vnd.api+json; ext=bulk" \
      -H "Content-Type: application/vnd.api+json; ext=bulk" \
      -H "Fastly-Key:$token" \
      "https://api.fastly.com/waf/firewalls/:FIREWALL_ID/versions/:VERSION_NUMBER/rules" \
      -d @/path/to/update-rule-status.json
    

    You can move all of the active rules on your firewall version to either log or block using the bulk update endpoint. Active rules in block status will block traffic that trigger those active rules on your WAF. To prevent false positives, you may choose to tune your WAF first.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    curl -X PATCH -s \
      -H "Accept: application/vnd.api+json" \
      -H "Content-Type: application/vnd.api+json" \
      -H "Fastly-Key:$token" \
      -d @- \
      "https://api.fastly.com/waf/firewalls/:FIREWALL_ID/versions/:VERSION_NUMBER/rules/bulk"
    <<JSON
    {
      "data": {
        "type": "waf_active_rule",
        "attributes": {
          "status": "block"
        }
      }
    }
    

    Viewing all revisions for a rule (API only)

    When you add an active rule to your WAF, the default is to add the most recent rule revision for the referenced rule. You can add an active rule with a previous rule revision once you know the rule revision ID. To view all details and the revisions for a rule:

    1
    2
    
    curl -sg -H "Fastly-Key:$token" \
        "https://api.fastly.com/waf/rules/:RULE_ID?include=waf_rule_revisions"
    

    In this return, the state will tell you if a rule is the latest version or if it's outdated. To see all rules with rule revisions updated since a specific date, start by getting the list of rules:

    1
    2
    
    curl -sg -H "Fastly-Key:$token" \
        "https://api.fastly.com/waf/rules?filter[waf_rule_revisions.created_at][gt]="YYYY-MM-DD""
    

    You can further filter this list to only show the rules already on your WAF that have updates since a specific date:

    1
    2
    
    curl -sg -H "Fastly-Key:$token" \
        "https://api.fastly.com/waf/rules?filter[waf_rule_revisions.created_at][gt]="YYYY-MM-DD&filter[waf_firewall.id][not][match]=:FIREWALL_ID""
    

    Once you have the list of rules, you can query each rule to get the latest rule revision:

    1
    2
    
    curl -sg -H "Fastly-Key:$token" \
        "https://api.fastly.com/waf/rules/:RULE_ID/revisions?filter[state]=latest"
    

    To view the VCL or the source of a rule revision, use the rule revision number to make the following request:

    1
    2
    
    curl -sg -H "Fastly-Key:$token" \
        "https://api.fastly.com/waf/rules/:RULE_ID/revisions/:REVISION_NUMBER?include=source,vcl"
    

    Finding outdated rules (API only)

    You can find any active rules on your WAF that have updated rule revisions:

    1
    2
    3
    
    curl -g \
      -H "Fastly-Key:$token" \
      "https://api.fastly.com/waf/firewalls/:FIREWALL_ID/versions/:VERSION_NUMBER/rules?filter[outdated]=true"
    

    Updating to the latest revision (API only)

    If you have any outdated active rules that you would like to update to the latest revision, you can update the rules one at a time on an editable firewall version:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    curl -X PATCH \
      -H "Accept: application/vnd.api+json" \
      -H "Content-Type: application/vnd.api+json" \
      -H "Fastly-Key:$token" \
      -d @- \
      "https://api.fastly.com/waf/firewalls/:FIREWALL_ID/versions/:VERSION_NUMBER/rules/:ACTIVE_RULE_ID" \
    <<JSON
    {
      "data": {
        "id": "ACTIVE_RULE_ID",
        "type": "waf_active_rule",
        "attributes": {
          "revision": "latest"
        }
      }
    }
    JSON
    

    When you're updating a single rule, you can also specify a specific rule revision number instead of latest.

    You can use the bulk endpoint to update all of the outdated active rules on a firewall version:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    curl -X PATCH -s \
      -H "Accept: application/vnd.api+json" \
      -H "Content-Type: application/vnd.api+json" \
      -H "Fastly-Key:$token" \
      -d @- \
      "https://api.fastly.com/waf/firewalls/:FIREWALL_ID/versions/:VERSION_NUMBER/rules/bulk"
    <<JSON
    {
      "data": {
        "type": "waf_active_rule",
        "attributes": {
          "revision": "latest"
        }
      }
    }
    JSON
    

    You can only update to the latest revision when bulk updating all of the active rules on your firewall version. You cannot select a specific revision.

    Understanding the types of rules

    Active rules have a status field that tells your VCL how to respond if a request triggers the rule. There are three possible statuses:

    Active rules that have a status of log or block are considered strict rules. If a request triggers these active rules, Fastly will follow the protocol of the status and either log or log and block the request.

    Active rules that have a status of score are only used to build a total score at the end of their assessment. This score is then used to determine if Fastly should log or log and block the request. See more about this behavior in Understanding scoring active rule behavior.

    Understanding scoring active rule behavior

    Scoring rules assign a score and categorize requests. These rules do not block requests. When a request is run past your WAF, for each scoring rule that a request triggers, the corresponding score is added to a running total for the category, or categories, the rule belongs to.

    The running total of each category is compared to the threshold defined for that category once all the rules are processed. Depending on the status of the threshold rule, your WAF will log or log and block the request if the running score exceeds the value set for the threshold rule. Lowering the values of your thresholds makes your WAF more likely to log or block requests, which might return false positives. Raising the values of the thresholds means that the request must potentially trigger more scoring rules before the request is blocked.

    Tuning your WAF

    Running live traffic through your WAF is the best way to tune it. As you add active rules and adjust thresholds and scores, you want to avoid false positives blocking legitimate traffic wherever possible.

    When you first set up your WAF, one option is to add any active rules you're interested in using in log mode. After you've logged traffic for a couple of weeks, you can analyze how requests triggered active rules in order to determine if an active rule looks like it will block legitimate traffic. If the active rule is a threshold rule for scoring rules, you can tweak the threshold value for that active rule. If the active rule is a strict match rule, you can choose to remove the rule from your WAF.

    When you check your logs and it looks like Fastly is ready to block malicious traffic and let legitimate traffic through to your origin, then change the status of all of your rules to block. At that point, Fastly will start to block any requests that match against what you've identified as malicious.

    Back to Top