Mitigate DDoS Attacks

Once you have analyzed the nature of a DDoS violation, you will know what type of traffic is involved and on which PFEs and line cards/FPCs the traffic is arriving. Armed with this information, you can manually begin deployment of stateless filters on the upstream nodes until you reach the border of your network where you can disable the offending peer or apply a filter to discard or rate limit the offending traffic as close to its source as possible. Once the fire is out, so to speak, you can contact the administrators of the peering network to obtain their assistance in tracing the attack to the actual sources of the attack, where corrective actions can be taken.

BGP Flow-Specification to the Rescue

The Junos BGP flow-specification (flow-spec or flow route) feature uses MP-BGP to rapidly deploy filter and policing functionality among BGP speaking nodes on both an intra- and inter-Autonomous System basis. This feature that is well suited to mitigating the effects of a DDoS attack, both locally and potentially over the global Internet, once the nature of the threat is understood. A flow specification is an n-tuple filter definition consisting of various IPv4 match criteria and a set of related actions that is distributed via MP-BGP so that remote BGP speakers can dynamically install stateless filtering and policing or offload traffic to another device for further handling. A given IP packet is said to match the defined flow if it matches all the specified criteria. Flow routes are an aggregation of match conditions and resulting actions for matching traffic that include filtering, rate limiting, sampling, and community attribute modification. Using flow-spec, you can define a filter once, and then distribute that filter throughout local and remote networks–just the medicine needed to nip a DDoS attack as close to the bud as possible.

Unlike BGP-based Remote Triggered Black Holes (RTBH), flow-spec gives you the ability to match on a wide range of match criteria, rather than policy-based matches that are destination IP address–based. And again, with flow-spec you can define match and filtering conditions in a central local and then use BGP to push that information out to both internal and external BGP speakers.

BGP flow-specification network-layer reachability information (NLRI) and its related operation are defined in RFC 5575 “Dissemination of Flow Specification Rules.” Note that Juniper publications still refer to the previous Internet draft “draft-ietf-idr-flow-spec-09,” which relates to the same functionality. In operation, a flow-spec’s filter match criteria are encoded within the flow-spec NLRI, whereas the related actions are encoded in extended communities. Different NLRI are specified for IPv4 versus Layer 3 VPN IPv4 to accommodate the added route-distinguisher and route targets. Once again, the venerable warhorse that is BGP shows its adaptability. A new service is enabled through opaque extensions to BGP, which allows operators to leverage a well-understood and proven protocol to provide new services or enhanced security and network robustness, as is the case with flow-spec. Flow-spec information is said to be opaque to BGP because its not BGP’s job to parse or interpret the flow-spec payload. Instead, the flow-spec information is passed through the flow-spec validation module, and when accepted, is handed to the firewall daemon (dfwd) for installation into the PFEs as a stateless filter and/or policer.

In v11.4, Junos supports flow-spec NLRI for both main instance IPv4 unicast and Layer 3 VPN IPv4 unicast traffic. To enable flow-specification NLRI for main instance MP-BGP, you include the flow statement for the inet address family at the [edit protocols bgp group group-name family inet] hierarchy. To enable flow-specification NLRI for the inet-vpn address family, include the flow statement at the [edit protocols bgp group group-name family inet-vpn] hierarchy level. Note that the flow family is valid only for main instance MP-BGP sessions; you cannot use this family for BGP session within a VRF.

Local and received flow routes that pass validation are installed into the flow routing table instance-name.inetflow.0, where matching packets are then subjected to the related flow-spec’s actions. Flow routes that do not pass validation are hidden in the related table null preference. Any change in validation status results in immediate update to the flow route. Received Layer 3 VPN flow routes are stored in the bgp.invpnflow.0 routing table and still contain their Route Distinguishers (RD). Secondary routes are imported to one or more specific VRF tables according to vrf-import policies. Unlike the inet flow NLRI, inet-vpn flow routes are not automatically validated against a specific VRF’s unicast routing information; this is because such an operation must be performed within a specific VRF context, and based on route-target the same flow NLRI can be imported into multiple VRFs.

Configure Local Flow-Spec Routes

You configure a local flow-specification for injection into BGP at the routing-options hierarchy, either in the main instance or under a supported instance type (VRF or VR). While some form of IDS may be used to provide alerts as to the need for flow-spec, in many cases operators will use SNMP alarms, RE protection filters, or the new DDoS feature to provide notification of abnormal traffic volumes. Using the details provided by these features allows the operator to craft one or more flow-specs to match on the attack vector and either filter outright or rate limit as deemed appropriate.

Flow-spec syntax is very much like a stateless filter; the primary difference is lack of a term function, as flow-specs consist of a single term. Otherwise, just like a filter, the flow-spec consists of a set of match criteria and related actions. As before, a match is only declared when all criteria in the from statement are true, else processing moves to the next flow-specification. The options for flow definition are displayed:

{master}[edit routing-options flow]
jnpr@R1-RE0# set ?
Possible completions:
+ apply-groups         Groups from which to inherit configuration data
+ apply-groups-except  Don't inherit configuration data from these groups
> route                Flow route
  term-order           Term evaluation order for flow routes
> validation           Flow route validation options
{master}[edit routing-options flow]
jnpr@R1-RE0# set

The term-order keyword is used to select between version 6 and later versions of the flow-spec specification, as described in the next section. Validation of flow routes, a process intended to prevent unwanted disruption from a feature that is intended to minimize disruption, is an important concept. It too is detailed in a following section. Currently, the validation keyword at the [edit routing-options flow] hierarchy is used to configure tracing for the validation process.

Supported match criteria include:

{master}[edit routing-options flow]
jnpr@R1-RE0# set route test ?
Possible completions:
  <[Enter]>            Execute this command
+ apply-groups         Groups from which to inherit configuration data
+ apply-groups-except  Don't inherit configuration data from these groups
> match                Flow definition
> then                 Actions to take for this flow
  |                    Pipe through a command
{master}[edit routing-options flow]
jnpr@R1-RE0# set route test match ?
Possible completions:
+ apply-groups         Groups from which to inherit configuration data
+ apply-groups-except  Don't inherit configuration data from these groups
  destination          Destination prefix for this traffic flow
+ destination-port     Destination TCP/UDP port
+ dscp                 Differentiated Services (DiffServ) code point (DSCP)
+ fragment
+ icmp-code            ICMP message code
+ icmp-type            ICMP message type
+ packet-length        Packet length
+ port                 Source or destination TCP/UDP port
+ protocol             IP protocol value
  source               Source prefix for this traffic flow
+ source-port          Source TCP/UDP port
+ tcp-flags            TCP flags
{master}[edit routing-options flow]
jnpr@R1-RE0# set route test match

And the supported actions:

{master}[edit routing-options flow]
jnpr@R1-RE0# set route test then ?
Possible completions:
  accept               Allow traffic through
+ apply-groups         Groups from which to inherit configuration data
+ apply-groups-except  Don't inherit configuration data from these groups
  community            Name of BGP community
  discard              Discard all traffic for this flow
  next-term            Continue the filter evaluation after matching this flow
  rate-limit           Rate at which to limit traffic for this flow (9600..1000000000000)
  routing-instance     Redirect to instance identified via Route Target community
  sample               Sample traffic that matches this flow
{master}[edit routing-options flow]
jnpr@R1-RE0# set route test then

A sample flow-specification is shown:

{master}[edit routing-options flow]
jnpr@R1-RE0# show
route flow_http_bad_source {
    match {
        source 10.0.69.0/25;
        protocol tcp;
        port http;
    }
    then {
        rate-limit 10k;
        sample;
    }
}

After the filter chapter, the purpose of the flow_http_bad_source flow-specification should be clear. Once sent to a remote peer, you can expect matching HTTP traffic to be rate limited and sampled (according to its sampling parameters, which are not shown here).

Flow-Spec Algorithm Version

With BGP flow-spec, it’s possible that more than one rule may match a particular traffic flow. In these cases, it’s necessary to define the order at which rules get matched and applied to a particular traffic flow in such a way that the final ordering must not depend on the arrival order of the flow-specification’s rules and must be constant in the network to ensure predictable operation among all nodes.

Junos defaults to the term-ordering algorithm defined in version 6 of the BGP flow-specification draft. In Junos OS Release v10.0 and later, you can configure the router to comply with the term-ordering algorithm first defined in version 7 of the BGP flow specification and supported through RFC 5575, “Dissemination of Flow Specification Routes.” The current best practice is to configure the version 7 term-ordering algorithm. In addition, it’s recommended that the same term-ordering version be used on all routing instances configured on a given router.

In the default term ordering algorithm (draft Version 6), a term with less specific matching conditions is always evaluated before a term with more specific matching conditions. This causes the term with more specific matching conditions to never be evaluated. Draft version 7 made a revision to the algorithm so that the more specific matching conditions are evaluated before the less specific matching conditions. For backward compatibility, the default behavior is not altered in Junos, even though the newer algorithm is considered better. To use the newer algorithm, include the term-order standard statement in the configuration.

Validating Flow Routes

Junos installs flow routes into the flow routing table only if they have been validated using the validation procedure described in the draft-ietf-idr-flow-spec-09.txt, Dissemination of Flow Specification Rules. The validation process ensures the related flow-spec NLRI is valid and goes on to prevent inadvertent DDoS filtering actions by ensuring that a flow-specification for a given route is only accepted when it is sourced from the same speaker that is the current selected active next-hop for that route. Specifically, a flow-specification NLRI is considered feasible if and only if:

  • The originator of the flow-specification matches the originator of the best-match unicast route for the destination prefix embedded in the flow-specification.

  • There are no more specific unicast routes, when compared with the flow destination prefix, that have been received from a different neighboring AS than the best-match unicast route, which has been determined in the first step.

The underlying concept is that the neighboring AS that advertises the best unicast route for a destination is allowed to advertise flow-spec information for that destination prefix. Stated differently, dynamic filtering information is validated against unicast routing information, such that a flow-spec filter is accepted if, and only if, it has been advertised by the unicast next-hop that is advertising the destination prefix and there are no unicast routes more specific than the flow destination, with a different next-hop AS number. Ensuring that another neighboring AS has not advertised a more specific unicast route before validating a received flow-specification ensures that a filtering rule affects traffic that is only flowing to the source of the flow-spec and prevents inadvertent filtering actions that could otherwise occur. The concept is that, if a given routing peer is the unicast next-hop for a prefix, then the system can safely accept from the same peer a more specific filtering rule that belongs to that aggregate.

You can bypass the validation process and use your own import policy to decide what flow-spec routes to accept using the no-validate switch:

[protocols bgp group <name>]
family inet {
    flow {
    no-validate <policy-name>;
    }
}

Bypassing the normal validation steps can be useful in the case where there is one system in the AS in charge of advertising filtering rules that are derived locally, perhaps via an Intrusion Detection System (IDS). In this case, the user can configure a policy that, for example, accepts BGP routes with an empty as-path to bypass the normal validation steps.

In addition, you can control the import and export of flow routes through import and export policy statements, respectively, which are applied to the related BGP peering sessions in conventional fashion. These policies can match on various criteria to include route-filter statements to match against the destination address of a flow route and the ability to use a from rib inetflow.0 statement to ensure that only flow-spec routes can be matched. You can apply Forwarding Table export policy to restrict flow route export to the PFE. The default policy is to advertise all locally defined flow-routes and to accept for validation all received flow-routes.

You can confirm the validation status of a flow route with a show route detail command. In this, a Layer 3 VPN flow route is shown:

. . .
vrf-a.inetflow.0: 2 destinations, 2 routes (2 active, 0 holddown, 0 hidden)
10.0.1/24,*,proto=6,port=80/88 (1 entry, 1 announced)
        *BGP    Preference: 170/-101
                Next-hop reference count: 2
                State: <Active Ext>
                Peer AS: 65002
                Age: 3:13:32
                Task: BGP_65002.192.168.224.221+1401
                Announcement bits (1): 1-BGP.0.0.0.0+179
                AS path: 65002 I
                Communities: traffic-rate:0:0
                Validation state: Accept, Originator: 192.168.224.221
                Via: 10.0.0.0/16, Active
                Localpref: 100
                Router ID: 201.0.0.6

In the output, the Validation state field confirms the flow route was validated (as opposed to rejected) and confirms the originator or the flow route as IP address 192.168.224.221. The via: field indicates which unicast route validated the flow-spec route, which in this case was 10.0/16. Use the show route flow validation command to display information about unicast routes that are used to validate flow specification routes.

You can trace the flow-spec validation process by adding the validation flag at the [edit routing-options flow] hierarchy:

{master}[edit routing-options flow]
jnpr@R1-RE0# show
validation {
    traceoptions {
        file flow_trace size 10m;
        flag all detail;
    }
}

Limit Flow-Spec Resource Usage

Flow-spec routes are essentially firewall filters, and like any filter there is some resource consumption and processing burden that can vary as a function of the filter’s complexity. However, unlike a conventional filter that requires local definition, once flow-spec is enabled on a BGP session, the remote peer is effectively able to cause local filter instantiation, potentially up until the point of local resource exhaustion, which can lead to bad things. To help guard against excessive resource usage in the event of misconfigurations or malicious intent, Junos allows you to limit the number of flow routes that can be in effect.

Use the maximum-prefixes statement to place a limit on the number of flow routes that can be installed in the inetflow.0 RIB:

set routing-options rib inetflow.0 maximum-prefixes <number>
set routing-options rib inetflow.0 maximum-prefixes threshold <percent>

To limit the number of flow-spec routes permitted from a given BGP peer, use the prefix-limit statement for the flow family:

set protocols bgp group x neighbor <address> family inet flow prefix-limit
  maximum <number>
set protocols bgp group x neighbor <address> family inet flow prefix-limit
  teardown <%>

Summary

The Junos BGP flow-specification feature is a powerful tool against DDoS attacks that works well alongside your routing engine protection filters and the Trio DDoS prevention feature. Even a hardened control plane can be overrun with excessive traffic that is directed to a valid service such as SSH. Once alerted to the anomalous traffic, you can use flow-spec to rapidly deploy filters to all BGP speakers to eliminate the attack traffic as close to the source as possible, all the while being able to maintain connectivity to the router to perform such mitigation actions, thanks to your having the foresight to deploy best practice RE protection filters along with built-in DDoS protections via Trio FPCs.

Get Juniper MX Series now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.