Blackholing#

Introduction#

Filtering with FlowSpec is a very efficient and flexible way to mitigate DDoS attacks. However, if attack volume exceeds uplink capacity, no local filtering will help. In such cases, RTBH (Remotely Triggered Black Hole) routing is used to drop traffic in the upstream network, before it reaches your infrastructure.

Note

RTBH is usually possible only with IP transit providers. In most cases it’s not supported or not effective on private peerings or IXPs.

Blackholing can also be used if your routers don’t support FlowSpec or are not capable of applying FlowSpec rules in hardware. However, using blackholing as the only mitigation method is not recommended, because it results in collateral damage by dropping all traffic to the targeted IP address, including legitimate traffic.

The best way is to stick with RTBH for large volumetric attacks which can’t be handled locally, and use FlowSpec for the rest.

Hint

If you want to use blackholing along with FlowSpec, it’s recommended to send blackholing routes to the upstreams and not apply them locally, so local, private peering and IXP traffic will still be exchanged.

This is covered in the provided example configurations.

Warning

Unfortunately, blackholing techniques are always a trade-off between mitigation efficiency and collateral damage. Therefore it’s recommended to use blackholing only as a last resort method.

Example use case:

You have two IP transit providers A and B, each with a 100G link. Both are half saturated with legitimate traffic (50G each). Also, you have some PNIs (private peerings) and you are present on some IXPs C and D (both 100G each).

An attacker starts a 10G DDoS attack against some of your IP addresses. If you have FlowSpec filtering in place and properly configured thresholds, all attack traffic will be filtered locally on your edge routers. Now the attacker increases attack volume to 120G. Most of the traffic comes from IP transit providers A and B, so your edge routers are not able to receive it without saturating links to A and B. If you have properly configured blackholing thresholds, the attacked IP will be announced to your edge routers and then redistributed to your upstream providers A and B who will drop all traffic to the attacked IP addresses. Because your local router will not apply this route in its forwarding table, traffic from your PNIs and IXPs C and D will still reach your infrastructure, so legitimate traffic from these sources will not be affected, because the rest of the traffic is filtered more accurately by FlowSpec rules.

This way you can reduce the impact of blackholing. The customer behind the attacked IP is still able to reach important routes via private peerings and IXPs. Only the traffic from IP transit providers is dropped.

Hint

If you have high-capacity IP transit links, you may consider selective blackholing to further reduce the impact of blackholing.

Note

Some IP transit providers allow or require an additional BGP session just for blackholing routes. In that case, you’ll need to configure a new BGP peer in LiveShield and ensure connectivity between LiveShield and your provider’s blackholing BGP router.

Important

You need at least one IPv4/IPv6 unicast BGP session configured in LiveShield to be able to use the blackholing feature.

Please refer to BGP peer.

Create profile#

To use the blackholing feature, you need to create a blackholing profile first. Go to the “Filtering” section in the main menu.

Page with blackholing profile

Then click “+” to add a new profile. A dialog will appear.

Add profile

Settings explained:

  • Name: Profile name, used to identify the profile in the web interface. If you leave it empty, a random name will be generated.

  • BGP Router Restriction: (Optional) If you want routes generated by this profile to be sent only to specific BGP peers, you can select them here. If you leave it empty, routes will be sent to all configured BGP peers.

  • Upstreams: (Optional) If you want to use the selective blackholing feature, you have to select all upstream providers which should receive blackholing routes from this profile.

The newly created profile will appear in the profiles list:

Added blackholing profile

Now you can edit the profile to configure thresholds:

Edit blackholing profile

Click the “Add Threshold” button to add a new threshold:

Edit blackholing thresholds

Settings explained:

  • Protocol: Select the protocol for which you want to define a threshold.

  • Timeout: How long (in seconds) the blackholing route generated by this threshold should be kept active after it’s no longer exceeding the defined thresholds. If the profile is attached to a prefix which has a shorter Maximum timeout value, that value will be used instead. Please refer to the Detection and Filtering (Thresholds).

  • pps Threshold: Packets per second threshold. If the traffic for the selected protocol exceeds this value, a blackholing route will be announced. Set to 0 to disable pps-based detection.

  • bps Threshold: Bits per second threshold. If the traffic for the selected protocol exceeds this value, a blackholing route will be announced. Set to 0 to disable bps-based detection.

For more information about protocols and thresholds, please refer to Detection and Filtering (Thresholds).

Hint

We recommend setting the bps Threshold value for the IP protocol or the most common protocols for volumetric attacks such as IPFRAG and UDP. However, you can also set thresholds for other protocols if you want to be more specific or adjust them to your needs.

Attach profile#

In order to make it work, you have to attach the blackholing profile to prefixes you want to protect.

Go to the Filtering section in the main menu, then edit the desired prefix and change Blackholing Profile to the one you created before.

Attach blackholing profile to prefix

For more information about prefix configuration, please refer to Detection and Filtering.

Operation logic#

Now, when everything is configured inside LiveShield, we can explain how blackholing thresholds work in practice.

Input traffic is continuously monitored and analysed. When traffic for a specific prefix and protocol exceeds defined thresholds in the prefix settings, a new attack is detected and some filtering rules are applied (if prefiltering or advanced filtering is enabled). At the same time, blackholing thresholds start to be evaluated. If traffic exceeds any of the defined blackholing thresholds, a blackholing route is generated and announced to the configured BGP routers (peers). No blackholing profile thresholds are checked if an attack is not detected on a particular IP.

Note

If you set blackholing profile thresholds to lower values than thresholds in the prefix settings, a blackholing route won’t be announced until prefix thresholds are exceeded (and an attack is detected). Blackholing profile thresholds are evaluated only after an attack is detected on a particular IP.

Note

You can have different protocols set in thresholds in prefix settings than in the blackholing profile. Only one prefix protocol threshold needs to be exceeded to start evaluating all of the blackholing profile thresholds.

For example: In prefix settings you set thresholds for DNS and NTP only, but in the blackholing profile you have configured thresholds for UDP and TCP. Only if DNS or NTP thresholds are exceeded will blackholing profile thresholds for UDP and TCP be evaluated. So if a DNS attack is detected and the UDP blackholing threshold is exceeded, a blackholing route will be announced. Also, if a DNS attack is detected and the TCP blackholing threshold is exceeded, a blackholing route will be announced too.

Note

Only one blackholing route is announced for a specific IP. If multiple blackholing thresholds are exceeded, it will be displayed in the web interface, but only one route will be announced for the whole period.

Example router config#

Blackholing configuration is much more complex than FlowSpec. The main concept is to receive blackholing routes from LiveShield, then apply our temporary community and then rewrite it to the one required by the upstream provider.

We will use two example providers PROVIDER_A (RTBH community 1000:666) and PROVIDER_B (RTBH community 2000:666).

Warning

Do not copy-and-paste these lines without adjusting them to your existing configuration!

First, create all necessary communities (local and for each provider, according to their requirements):

set policy-options community PROVIDER_A.RTBH members 1000:666
set policy-options community PROVIDER_B.RTBH members 2000:666
set policy-options community RTBH members 65501:666

Then create a policy to match /32 and /128 routes from LiveShield and apply local community. This policy also contains a rule to allow FlowSpec routes to be accepted. This is necessary if you have FlowSpec and blackholing sessions on the same BGP peer with the same import policy. We will also reject any export towards LiveShield, because there’s no need to send any routes back.

set policy-options policy-statement LIVESHIELD.IN term SET-COMMUNITY-V4 from family inet
set policy-options policy-statement LIVESHIELD.IN term SET-COMMUNITY-V4 from route-filter 0.0.0.0/0 prefix-length-range /32-/32
set policy-options policy-statement LIVESHIELD.IN term SET-COMMUNITY-V4 then community add RTBH
set policy-options policy-statement LIVESHIELD.IN term SET-COMMUNITY-V4 then accept
set policy-options policy-statement LIVESHIELD.IN term SET-COMMUNITY-V6 from family inet6
set policy-options policy-statement LIVESHIELD.IN term SET-COMMUNITY-V6 from route-filter ::/0 prefix-length-range /128-/128
set policy-options policy-statement LIVESHIELD.IN term SET-COMMUNITY-V6 then community add RTBH
set policy-options policy-statement LIVESHIELD.IN term SET-COMMUNITY-V6 then accept
set policy-options policy-statement LIVESHIELD.IN term ACCEPT-FLOWSPEC from rib inetflow.0
set policy-options policy-statement LIVESHIELD.IN term ACCEPT-FLOWSPEC then accept
set policy-options policy-statement LIVESHIELD.IN term ACCEPT-FLOWSPEC-V6 from rib inet6flow.0
set policy-options policy-statement LIVESHIELD.IN term ACCEPT-FLOWSPEC-V6 then accept
set policy-options policy-statement LIVESHIELD.IN then default-action reject
set policy-options policy-statement LIVESHIELD.OUT then default-action reject

Create a BGP peer with LiveShield:

set protocols bgp group LIVESHIELD type internal
set protocols bgp group LIVESHIELD import LIVESHIELD.IN
set protocols bgp group LIVESHIELD export LIVESHIELD.OUT
set protocols bgp group LIVESHIELD peer-as 65501
set protocols bgp group LIVESHIELD neighbor 192.168.100.10 family inet unicast

Modify the existing export policy for PROVIDER_A and PROVIDER_B to match the local community and rewrite it to the provider-specific community:

set policy-options policy-statement PROVIDER_A.OUT term REWRITE-RTBH-COMMUNITY from community RTBH
set policy-options policy-statement PROVIDER_A.OUT term REWRITE-RTBH-COMMUNITY then community set PROVIDER_A.RTBH

set policy-options policy-statement PROVIDER_B.OUT term REWRITE-RTBH-COMMUNITY from community RTBH
set policy-options policy-statement PROVIDER_B.OUT term REWRITE-RTBH-COMMUNITY then community set PROVIDER_B.RTBH

Modify your existing BGP peer configuration to announce BGP routes even if they’re not preferred:

set protocols bgp group PROVIDER_A advertise-inactive
set protocols bgp group PROVIDER_B advertise-inactive

As stated in Introduction, if you want to use FlowSpec along with blackholing, it’s recommended to not apply blackholing routes in the forwarding table, so the blackhole route will be redistributed to the upstream, but not applied locally.

set policy-options policy-statement FIB-FILTER.IN term REJECT-RTBH from community RTBH
set policy-options policy-statement FIB-FILTER.IN term REJECT-RTBH then reject
set policy-options policy-statement FIB-FILTER.IN then default-action accept

set routing-options forwarding-table export FIB-FILTER.IN

Full config example:

interfaces {
   ge-0/0/0 {
      unit 0 {
         description TO_LIVESHIELD;
         family inet {
            address 192.168.100.222/24;
         }
      }
   }
   ge-0/0/1 {
      description PROVIDER_A;
      unit 0 {
         family inet {
            address 192.168.200.1/31;
         }
         family inet6 {
            address fc00::200:1/127;
         }
      }
   }
   ge-0/0/2 {
      description PROVIDER_B;
      unit 0 {
         family inet {
            address 192.168.200.3/31;
         }
      }
   }
}
policy-options {
   prefix-list ANNOUNCE-PREFIXES {
      192.168.66.0/24;
   }
   prefix-list ANNOUNCE-PREFIXES-V6 {
      fc00::66:0/112;
   }
   policy-statement PROVIDER_A.IN {
      then default-action accept;
   }
   policy-statement PROVIDER_A.OUT {
      term REWRITE-RTBH-COMMUNITY {
         from community RTBH;
         then {
            community set PROVIDER_A.RTBH;
            accept;
         }
      }
      term ANNOUNCE-PREFIXES {
         from {
            prefix-list ANNOUNCE-PREFIXES;
         }
         then accept;
      }
      term ANNOUNCE-PREFIXES-V6 {
         from {
            prefix-list ANNOUNCE-PREFIXES-V6;
         }
         then accept;
      }
      then default-action reject;
   }
   policy-statement FIB-FILTER.IN {
      term REJECT-RTBH {
         from community RTBH;
         then reject;
      }
      then default-action accept;
   }
   policy-statement PROVIDER_B.IN {
      then default-action accept;
   }
   policy-statement PROVIDER_B.OUT {
      term REWRITE-RTBH-COMMUNITY {
         from community RTBH;
         then {
            community set PROVIDER_B.RTBH;
            accept;
         }
      }
      term ANNOUNCE-PREFIXES {
         from {
            prefix-list ANNOUNCE-PREFIXES;
         }
         then accept;
      }
      then default-action reject;
   }
   policy-statement LIVESHIELD.IN {
      term SET-COMMUNITY-V4 {
         from {
            family inet;
            route-filter 0.0.0.0/0 prefix-length-range /32-/32;
         }
         then {
            community add RTBH;
            accept;
         }
      }
      term SET-COMMUNITY-V6 {
         from {
            family inet6;
            route-filter ::/0 prefix-length-range /128-/128;
         }
         then {
            community add RTBH;
            accept;
         }
      }
      term ACCEPT-FLOWSPEC {
         from rib inetflow.0;
         then accept;
      }
      term ACCEPT-FLOWSPEC-V6 {
         from rib inet6flow.0;
         then accept;
      }
      then default-action reject;
   }
   policy-statement LIVESHIELD.OUT {
      then default-action reject;
   }
   community PROVIDER_A.RTBH members 1000:666;
   community PROVIDER_B.RTBH members 2000:666;
   community RTBH members 65501:666;
}
routing-options {
   router-id 192.168.100.222;
   forwarding-table {
      export FIB-FILTER.IN;
   }
}
protocols {
   bgp {
      group LIVESHIELD {
         type internal;
         import LIVESHIELD.IN;
         export LIVESHIELD.OUT;
         peer-as 65501;
         neighbor 192.168.100.10 {
            family inet {
               unicast;
               flow;
            }
         }
      }
      group PROVIDER_A {
         type external;
         description PROVIDER_A;
         advertise-inactive;
         import PROVIDER_A.IN;
         export PROVIDER_A.OUT;
         peer-as 1000;
         neighbor 192.168.200.0 {
            family inet {
               unicast;
            }
         }
         neighbor fc00::200:0 {
            family inet6 {
               unicast;
            }
         }
      }
      group PROVIDER_B {
         type external;
         description PROVIDER_B;
         advertise-inactive;
         import PROVIDER_B.IN;
         export PROVIDER_B.OUT;
         peer-as 2000;
         neighbor 192.168.200.2 {
            family inet {
               unicast;
            }
         }
      }
      local-as 65501;
   }
}

Verification#

First, check if the BGP session with LiveShield is established:

/usr/share/liveshield/analyser/gobgp/gobgp neighbor

It should give you the following output:

Peer               AS  Up/Down State       |#Received  Accepted
192.168.100.222 65501 03:17:33 Establ      |        0         0

In order to check if the unicast address family is established, use:

/usr/share/liveshield/analyser/gobgp/gobgp neighbor 192.168.100.222

It should give you the following output:

[...]
  Neighbor capabilities:
   multiprotocol:
      ipv4-unicast:   advertised and received

You should see advertised and received near the unicast address family.

During an attack, you can check announced routes with:

/usr/share/liveshield/analyser/gobgp/gobgp global rib -a vpnv4

This should give you output similar to the following:

   Network                            Labels     Next Hop             AS_PATH              Age        Attrs
*> 192.168.100.10:0:192.168.66.101/32 [0]        0.0.0.0                                   01:36:02   [{Origin: ?} {Extcomms: [192.168.100.10:0]}]

Selective blackholing#

If you have high-capacity upstream links to your IP transit providers, you may consider using the selective blackholing feature to further reduce the impact of blackholing on legitimate traffic.

With this feature, you can configure different thresholds for each upstream provider and announce blackholing routes only to those upstreams which are actually affected by the attack.

Note

Selective blackholing requires that you have properly configured upstream providers in the BGP settings.

This requires your traffic to have 802.1Q VLAN tags for distinguishing different upstream providers. Otherwise, LiveShield Worker won’t be able to differentiate traffic.

Warning

Selective blackholing is a little bit slower than regular blackholing, because LiveShield has to keep track of traffic for each upstream separately.

There are two ways to achieve selective blackholing (it depends on your upstream providers’ agreements):

  • You can configure LiveShield to announce blackhole routes to your routers, but with additional communities for each upstream provider which is exceeding the defined thresholds. You can configure these communities in the Upstreams menu.

  • If you have a direct separate BGP session with your upstream provider just for blackholing routes (established directly from LiveShield), you should also configure BGP Router Restriction in the Upstreams menu (for each upstream). Please be sure to allow blackhole route announcements only on the BGP session which is matching the upstream provider.

Example:

We have three upstream providers A, B and C. They are all terminated on two edge routers R1 and R2.

  • Provider A accepts /32 blackhole routes with community 1000:666 on the BGP session from router R1.

  • Provider B accepts /32 blackhole routes with community 2000:666 on the BGP session from router R2.

  • Provider C accepts /32 blackhole routes without any special community but requires a separate BGP session, which can be established directly from LiveShield.

Selective blackholing architecture example

Example of configured BGP Routers (Peers) in Devices, BGP Routers tab:

Selective blackholing BGP peers example

In the Upstreams menu, we have configured three upstreams as follows:

Selective blackholing upstreams example

As you can see, each upstream has a different VLAN tag to allow LiveShield to distinguish traffic. Also, each upstream has a different blackholing community, except upstream C which uses a separate BGP session for blackholing routes.

The most important part is the BGP Router Restriction setting. Upstream A and B are restricted to router R1 and R2, because we have a BGP session only from these routers. The decision where to send the blackhole route will be performed by our R1 and R2 routers, based on communities. Upstream C is restricted to the C_RTBH peer, because blackhole routes for this upstream will be announced directly from LiveShield, only on this session.

Thresholds#

In order to use selective blackholing, you need to configure thresholds for each upstream in the blackholing profile.

Go to Filtering, then Blackholing Profiles and edit the desired profile or add a new one. More details about profile creation can be found in the Create profile section.

Selective blackholing profile example

In order to convert it to a selective blackholing profile, you need to add Upstreams from the list and configure thresholds for each of them.

Selective blackholing thresholds example

You can have different thresholds for each upstream, but please remember to add all upstreams which you want to use for selective blackholing and configure thresholds for each.

Warning

If you don’t add an upstream to the blackholing profile or you don’t configure thresholds for it, no blackholing will be applied on that upstream.

Note

If you configure BGP Router Restriction in the blackholing profile, only those BGP peers will receive blackholing routes. If your upstream is restricted to a BGP peer which is not in the profile restriction list, no blackholing route will be sent to that upstream.

Hint

You can have different profiles for different prefixes (even more specific). You can use selective blackholing only for some prefixes and regular blackholing for others.

If you want to check which upstreams are used for blackholing during an attack, you can check the Blackholing details in the Attacks menu (you have to click on a specific attack).

Blackholing details history

Example router config#

Before you start, please read the blackholing example configuration section, because this is the basic configuration required for blackholing to work (regular non-selective blackholing). In this section we will show you only the differences required for selective blackholing.

Warning

Do not copy-and-paste these lines without adjusting them to your existing configuration!

First, start with adding additional combined communities (combining local RTBH community 65501:666 with specific upstream RTBH community 1000:666 or 2000:666 respectively):

set policy-options community PROVIDER_A_W_LOCAL.RTBH members 65501:666
set policy-options community PROVIDER_A_W_LOCAL.RTBH members 1000:666

set policy-options community PROVIDER_B_W_LOCAL.RTBH members 65501:666
set policy-options community PROVIDER_B_W_LOCAL.RTBH members 2000:666

Then, all we have to do is to change our export policy for each upstream provider to announce the route only if the local RTBH community is present and/or a specific RTBH community for that provider is present. Then rewrite communities to leave only the specific provider RTBH community (PROVIDER_A.RTBH or PROVIDER_B.RTBH respectively).

Note

This example covers a scenario with regular (full) blackholing and selective blackholing together. If just the local RTBH community is present, the route will be announced to all upstreams. If local RTBH is present along with an additional community, the specific provider RTBH community is checked to achieve selective blackholing.

Note

If you already have configuration from the regular blackholing example, you’ll need to remove existing terms and insert new ones in the correct order (at the beginning of the statement).

We don’t recommend pure copy-and-paste, but here are the commands for deleting old terms:

delete policy-options policy-statement PROVIDER_A.OUT term REWRITE-RTBH-COMMUNITY
delete policy-options policy-statement PROVIDER_B.OUT term REWRITE-RTBH-COMMUNITY

After setting new terms, you can reposition them with:

insert policy-options policy-statement PROVIDER_A.OUT term REWRITE-RTBH-COMMUNITY before term ANNOUNCE-PREFIXES
insert policy-options policy-statement PROVIDER_A.OUT term REWRITE-RTBH-SELECTIVE-COMMUNITY after term REWRITE-RTBH-COMMUNITY

insert policy-options policy-statement PROVIDER_B.OUT term REWRITE-RTBH-COMMUNITY before term ANNOUNCE-PREFIXES
insert policy-options policy-statement PROVIDER_B.OUT term REWRITE-RTBH-SELECTIVE-COMMUNITY after term REWRITE-RTBH-COMMUNITY
set policy-options policy-statement PROVIDER_A.OUT term REWRITE-RTBH-COMMUNITY from community RTBH
set policy-options policy-statement PROVIDER_A.OUT term REWRITE-RTBH-COMMUNITY from community-count 1 equal
set policy-options policy-statement PROVIDER_A.OUT term REWRITE-RTBH-COMMUNITY then community set PROVIDER_A.RTBH
set policy-options policy-statement PROVIDER_A.OUT term REWRITE-RTBH-COMMUNITY then accept
set policy-options policy-statement PROVIDER_A.OUT term REWRITE-RTBH-SELECTIVE-COMMUNITY from community PROVIDER_A_W_LOCAL.RTBH
set policy-options policy-statement PROVIDER_A.OUT term REWRITE-RTBH-SELECTIVE-COMMUNITY then community set PROVIDER_A.RTBH
set policy-options policy-statement PROVIDER_A.OUT term REWRITE-RTBH-SELECTIVE-COMMUNITY then accept

set policy-options policy-statement PROVIDER_B.OUT term REWRITE-RTBH-COMMUNITY from community RTBH
set policy-options policy-statement PROVIDER_B.OUT term REWRITE-RTBH-COMMUNITY from community-count 1 equal
set policy-options policy-statement PROVIDER_B.OUT term REWRITE-RTBH-COMMUNITY then community set PROVIDER_B.RTBH
set policy-options policy-statement PROVIDER_B.OUT term REWRITE-RTBH-COMMUNITY then accept
set policy-options policy-statement PROVIDER_B.OUT term REWRITE-RTBH-SELECTIVE-COMMUNITY from community PROVIDER_B_W_LOCAL.RTBH
set policy-options policy-statement PROVIDER_B.OUT term REWRITE-RTBH-SELECTIVE-COMMUNITY then community set PROVIDER_B.RTBH
set policy-options policy-statement PROVIDER_B.OUT term REWRITE-RTBH-SELECTIVE-COMMUNITY then accept

Full config example:

interfaces {
   ge-0/0/0 {
      unit 0 {
         description TO_LIVESHIELD;
         family inet {
            address 192.168.100.222/24;
         }
      }
   }
   ge-0/0/1 {
      description PROVIDER_A;
      unit 0 {
         family inet {
            address 192.168.200.1/31;
         }
         family inet6 {
            address fc00::200:1/127;
         }
      }
   }
   ge-0/0/2 {
      description PROVIDER_B;
      unit 0 {
         family inet {
            address 192.168.200.3/31;
         }
      }
   }
}
policy-options {
   prefix-list ANNOUNCE-PREFIXES {
      192.168.66.0/24;
   }
   prefix-list ANNOUNCE-PREFIXES-V6 {
      fc00::66:0/112;
   }
   policy-statement PROVIDER_A.IN {
      then default-action accept;
   }
   policy-statement PROVIDER_A.OUT {
      term REWRITE-RTBH-COMMUNITY {
            from {
               community RTBH;
               community-count 1 equal;
            }
            then {
               community set PROVIDER_A.RTBH;
               accept;
            }
      }
      term REWRITE-RTBH-SELECTIVE-COMMUNITY {
            from community PROVIDER_A_W_LOCAL.RTBH;
            then {
               community set PROVIDER_A.RTBH;
               accept;
            }
      }
      term ANNOUNCE-PREFIXES {
            from {
               prefix-list ANNOUNCE-PREFIXES;
            }
            then accept;
      }
      term ANNOUNCE-PREFIXES-V6 {
            from {
               prefix-list ANNOUNCE-PREFIXES-V6;
            }
            then accept;
      }
      then default-action reject;
   }
   policy-statement FIB-FILTER.IN {
      term REJECT-RTBH {
         from community RTBH;
         then reject;
      }
      then default-action accept;
   }
   policy-statement PROVIDER_B.IN {
      then default-action accept;
   }
   policy-statement PROVIDER_B.OUT {
      term REWRITE-RTBH-COMMUNITY {
            from {
               community RTBH;
               community-count 1 equal;
            }
            then {
               community set PROVIDER_B.RTBH;
               accept;
            }
      }
      term REWRITE-RTBH-SELECTIVE-COMMUNITY {
            from community PROVIDER_B_W_LOCAL.RTBH;
            then {
               community set PROVIDER_B.RTBH;
               accept;
            }
      }
      term ANNOUNCE-PREFIXES {
            from {
               prefix-list ANNOUNCE-PREFIXES;
            }
            then accept;
      }
      then default-action reject;
   }
   policy-statement LIVESHIELD.IN {
      term SET-COMMUNITY-V4 {
         from {
            family inet;
            route-filter 0.0.0.0/0 prefix-length-range /32-/32;
         }
         then {
            community add RTBH;
            accept;
         }
      }
      term SET-COMMUNITY-V6 {
         from {
            family inet6;
            route-filter ::/0 prefix-length-range /128-/128;
         }
         then {
            community add RTBH;
            accept;
         }
      }
      term ACCEPT-FLOWSPEC {
         from rib inetflow.0;
         then accept;
      }
      term ACCEPT-FLOWSPEC-V6 {
         from rib inet6flow.0;
         then accept;
      }
      then default-action reject;
   }
   policy-statement LIVESHIELD.OUT {
      then default-action reject;
   }
   community PROVIDER_A.RTBH members 1000:666;
   community PROVIDER_A_W_LOCAL.RTBH members [ 65501:666 1000:666 ];
   community PROVIDER_B.RTBH members 2000:666;
   community PROVIDER_B_W_LOCAL.RTBH members [ 65501:666 2000:666 ];
   community RTBH members 65501:666;
}
routing-options {
   router-id 192.168.100.222;
   forwarding-table {
      export FIB-FILTER.IN;
   }
}
protocols {
   bgp {
      group LIVESHIELD {
         type internal;
         import LIVESHIELD.IN;
         export LIVESHIELD.OUT;
         peer-as 65501;
         neighbor 192.168.100.10 {
            family inet {
               unicast;
               flow;
            }
         }
      }
      group PROVIDER_A {
         type external;
         description PROVIDER_A;
         advertise-inactive;
         import PROVIDER_A.IN;
         export PROVIDER_A.OUT;
         peer-as 1000;
         neighbor 192.168.200.0 {
            family inet {
               unicast;
            }
         }
         neighbor fc00::200:0 {
            family inet6 {
               unicast;
            }
         }
      }
      group PROVIDER_B {
         type external;
         description PROVIDER_B;
         advertise-inactive;
         import PROVIDER_B.IN;
         export PROVIDER_B.OUT;
         peer-as 2000;
         neighbor 192.168.200.2 {
            family inet {
               unicast;
            }
         }
      }
      local-as 65501;
   }
}

Verification:

Let’s assume that upstream provider A is exceeding the defined blackholing thresholds, so the RTBH route should be announced with community 1000:666 only to that upstream.

Check if the route is correctly announced:

/usr/share/liveshield/analyser/gobgp/gobgp global rib -a vpnv4

This should give you output similar to the following:

   Network                            Labels     Next Hop             AS_PATH              Age        Attrs
*> 192.168.100.10:0:192.168.66.101/32 [0]        0.0.0.0                                   00:00:05   [{Origin: ?} {Communities: 1000:666} {Extcomms: [192.168.100.10:0]}]

As you can see, it contains the community 1000:666 only, which is correct for upstream provider A. This is configurable in the Upstreams menu.

Note

Extcomms are used for internal LiveShield purposes. This defines to which BGP peers the route should be announced. It’s tied to the GoBGP VRF feature. You can ignore this attribute unless you are familiar with GoBGP and the vpnv4 family.

Verify with provider#

After completing configuration and verification on your side, it’s recommended to check if your upstream providers are receiving the blackhole routes as expected.

The easiest way is to look for looking glass services provided by your upstreams.

Here is the list of the most popular ones (maybe you’ll find your provider on that list):

Search for your provider’s looking glass or ask them directly.

Here is an example of a correctly received blackhole route on an upstream provider’s looking glass:

Looking glass working example (twelve99)

As you can see, the /32 route is accepted and traffic is discarded.