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:
- 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.
- 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:
- An AS-SET (or just your ASN) that expands to the ASNs you originate.
- IRR route/route6 objects for each prefix with the correct origin.
- RPKI ROAs matching the origin and the prefix lengths you will announce.
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:
- Outbound: announce only your own prefixes (the lists above).
- Inbound: accept only what you expect, usually a default route or nothing. Do not accept the full table or your own prefixes back.
- Set a sensible
maximum-prefixlimit. - Enable origin validation (ROV) where your platform supports it, so a bad ROA state is visible.
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
- Stale or duplicate route objects. An old object for the same prefix with a previous origin in RADB, while the current one is in RIPE, can cause inconsistent filters. Delete the stale objects.
- Missing IPv6. Teams create IPv4 objects and forget
route6and ROAs for v6. - Wrong maxLength. Too loose invites forged more-specifics. Too tight invalidates your own /24 splits, and ROV networks will drop them.
- Provider origin not covered. The scrubbing edge originates from a different ASN, and no ROA or route object exists for it.
- Wrong IRR source. You updated one IRR, but the provider's filters query another. Say which IRR you maintain, and check which sources the provider trusts.
- Changing objects at the last minute. Providers refresh filters on a schedule, often every few hours. Objects created during an attack may not be accepted in time.
- Oversized AS-SETs. Nested sets you do not control can pull in unrelated prefixes, or get your session rejected.
- Maintainer problems. Objects protected by a
mnt-bywhose credentials nobody remembers cannot be fixed under pressure. - No IRR for the parent block. The registry may require a covering inetnum or allocation record before it accepts route objects.
A short pre-onboarding checklist
- AS-SET exists, is hierarchical and contains only the ASNs you originate.
routeandroute6objects exist for every prefix, with correct origin.- ROAs match the prefix lengths you will announce.
- You know the origin ASN seen in the global table during scrubbing.
- Your export and import policies on the tunnel BGP session are in place.
- LOA, if required, is signed.
- 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.