· 7 min read

AS-SET and IRR Route Objects: Prefix Filtering with bgpq4

Your DDoS provider asks for an AS-SET and IRR route objects because it will announce your prefixes to the internet on your behalf, and its upstreams and IXPs will only accept those announcements if they can verify you own them. The AS-SET tells the provider which ASNs and prefixes to accept from you. The route objects and RPKI ROAs are what the rest of the internet checks before it believes the announcement.

If any of these records are wrong or missing, the failure is usually quiet. The BGP session comes up, but the prefixes never get accepted or propagated, and you find out during an attack. This guide covers what to prepare, how to generate filters with bgpq4, and the mistakes we see most often.

Why a scrubbing provider needs this data

With a cloud scrubbing service for networks with their own ASN, such as NixGuard Edge, your prefixes are announced from the scrubbing edge. Clean traffic comes back to you over a GRE tunnel with a BGP session inside. Two filtering layers matter here:

  1. Provider ingress filter (from you). The provider builds a prefix list from your AS-SET and accepts only those prefixes on your session. This keeps a typo or a leak on your side from hijacking someone else's space.
  2. Upstream and IXP filters (from the provider). Transit providers and IXP route servers check the announcements against IRR route objects and, increasingly, RPKI. If your prefix has no matching route: object and no valid ROA, it may be dropped or deprioritized.

In practice, the provider needs three things from you:

Many providers also ask for a signed LOA (letter of authorization). That is separate from IRR, and having both ready speeds up onboarding.

Step 1: Create the AS-SET

Use a hierarchical name under your ASN. It is clearer and harder to hijack than a flat name. Example for RIPE-style IRR (adjust for your registry):

as-set:   AS64496:AS-CUSTOMERS
descr:    Prefix filtering set for AS64496
members:  AS64496
mnt-by:   EXAMPLE-MNT
source:   RIPE

Keep it small. Add downstream customer ASNs only if you really announce their routes. A bloated AS-SET with nested sets you do not control can pull in prefixes you never intended to announce.

Step 2: Create route and route6 objects

Each prefix needs an object with the right origin:

route:    192.0.2.0/24
origin:   AS64496
mnt-by:   EXAMPLE-MNT
source:   RIPE

route6:   2001:db8::/32
origin:   AS64496
mnt-by:   EXAMPLE-MNT
source:   RIPE

If the provider will originate your prefixes from its own ASN while scrubbing, ask what origin AS will appear in the global table. If it differs from yours, you need a route object and a ROA authorizing that origin as well. If your origin ASN is preserved, your existing objects cover it. Ask before you sign, not during an attack.

Step 3: Publish RPKI ROAs

A ROA binds a prefix, a maximum length and an origin ASN. For a /24 you announce as-is:

Prefix Max length Origin
192.0.2.0/24 24 AS64496
198.51.100.0/22 22 AS64496

Set maxLength to what you actually announce. If you set /22 with max length 24 and never announce the /24s, an attacker can forge-announce a /24 with your origin and still pass validation. If you plan to split a /22 into /24s for traffic engineering during an attack, include those lengths on purpose and nothing beyond. Remember that /24 is the practical limit for IPv4 on the public internet.

Step 4: Generate prefix filters with bgpq4

bgpq4 expands AS-SETs and ASNs from IRR databases into router-ready prefix lists. Run it from a Linux box in your provisioning pipeline.

Cisco IOS-style prefix list (aggregated, max /24):

bgpq4 -4 -A -m 24 -l CUST-OUT-V4 AS64496:AS-CUSTOMERS

The output looks like this:

ip prefix-list CUST-OUT-V4 permit 192.0.2.0/24
ip prefix-list CUST-OUT-V4 permit 198.51.100.0/22 le 24

The le part depends on -m and -R. Review the output before you deploy.

Juniper:

bgpq4 -4 -J -A -m 24 -l CUST-OUT-V4 AS64496:AS-CUSTOMERS

This produces a policy-options block you can load with load patch or load set. Then apply it to the session toward the scrubbing edge:

policy-options {
    policy-statement TO-SCRUB {
        term OWN-PREFIXES {
            from {
                family inet;
                prefix-list-filter CUST-OUT-V4 orlonger;
            }
            then accept;
        }
        term REJECT-REST {
            then reject;
        }
    }
}
protocols bgp group SCRUB export TO-SCRUB

Use orlonger only if you intend to announce more-specifics. Use exact otherwise.

BIRD on Linux:

bgpq4 -4 -b -A -m 24 -l CUST_V4 AS64496:AS-CUSTOMERS

Include the generated set in a filter:

filter to_scrub {
    if net ~ CUST_V4 then accept;
    reject;
}

MikroTik RouterOS v7: bgpq4 has no native RouterOS output. For a handful of prefixes, write the filter by hand:

/routing filter rule
add chain=to-scrub rule="if (dst in 192.0.2.0/24 && dst-len == 24) { accept }"
add chain=to-scrub rule="reject"

For larger sets, generate the lines with a script from bgpq4 -j (JSON output).

Always do the same for IPv6 (-6) if you run dual-stack, and use -S RIPE,RADB (or the sources your registry uses) so you only trust the databases you maintain.

Step 5: Filter your side of the tunnel too

The provider filters you, but you should also filter the provider. On the BGP session inside the GRE tunnel:

If you use RTBH or FlowSpec, keep those policies separate. Blackhole /32s are usually accepted by a dedicated policy tagged with a community. The ordinary prefix filter should not need to allow /32s.

Step 6: Verify before you need it

Check what the world sees:

whois -h whois.radb.net -- '-i origin AS64496'
bgpq4 -4 -l TEST AS64496:AS-CUSTOMERS

Then confirm that each prefix has a route object in the registry you expect, a valid ROA in a public RPKI validator (Routinator, rpki-client or a web validator), and the right origin on a looking glass. Run the same checks every time you add a prefix.

Common mistakes

A short pre-onboarding checklist

  1. AS-SET exists, is hierarchical and contains only the ASNs you originate.
  2. route and route6 objects exist for every prefix, with correct origin.
  3. ROAs match the prefix lengths you will announce.
  4. You know the origin ASN seen in the global table during scrubbing.
  5. Your export and import policies on the tunnel BGP session are in place.
  6. LOA, if required, is signed.
  7. You tested on-demand announcement before relying on it.

Where NixMon fits

Clean IRR and RPKI data is what makes mitigation fast. Detection comes first, though. NixMon analyzes NetFlow v5/v9, IPFIX and sFlow, with per-IP and per-prefix bps/pps thresholds. It can trigger BGP blackhole, FlowSpec, on-prem firewall or NixGuard Edge actions. If you own an ASN and at least one /24, you can run NixGuard Edge always-on or on-demand, and your AS-SET is used for prefix filtering. You can start a 15-day free trial with no credit card to see how detection and BGP actions work with your own flow data.

Frequently asked questions

Why does my DDoS provider need my AS-SET?

The provider builds an ingress prefix filter from it, so it accepts only the prefixes you are authorized to announce. This protects both you and the wider internet from leaks and hijacks.

Is an IRR route object enough, or do I also need an RPKI ROA?

Have both. Many networks still filter on IRR data, and a growing number drop RPKI-invalid routes. A route object without a ROA, or the reverse, can leave your prefix partially filtered.

What maxLength should I use in my ROA?

Use the longest prefix you actually plan to announce. For a /24 that is 24. A looser maxLength lets forged more-specifics validate, and a tighter one invalidates your own splits.

Can bgpq4 generate filters for MikroTik?

Not natively. It supports formats like Cisco, Juniper, BIRD and JSON. For RouterOS, write the filter by hand for a few prefixes, or generate it with a script from the JSON output.

Start your 15-day free NixMon trial. No credit card needed.Learn more