Enter an AS number and check whether your prefixes can be diverted to a DDoS scrubbing centre during an attack: whether every /24 (/48) split out of your blocks will be RPKI-valid, whether route objects live in a RIR database, whether an LOA will be needed, and whether AS-SET, abuse contact, PeeringDB and ASPA are in order. It also checks the hygiene of your AS-SET — how big it really is, what it pulls in and who else has put your AS into their AS-SETs. The tool then walks you through the fixes step by step, with instructions for your own registry — RIPE NCC, ARIN, APNIC, AFRINIC or LACNIC — and ready-to-paste ROA, route object and LOA drafts. The downloadable version adds prefix lists built with bgpq4.
Everything runs in the browser. There is no server and no account; the browser queries public services directly. Published by ITORO — we protect operator and data centre networks against DDoS attacks.
Wersja polska → README.pl.md · Live: https://itoro.com.pl/narzedzia/scrubbing/
During an attack that exceeds link capacity, traffic is diverted to a scrubbing centre by announcing /24 prefixes carved out of larger blocks. If the ROA was created exactly on the aggregate, every /24 becomes RPKI-invalid and is dropped by validating networks. RPKI and IRR changes take hours to reach filters — RFC 9319 §5.1 says the ROA must exist before the attack. This test finds such gaps in advance.
AS level: AS exists and announces prefixes · abuse contact · aut-num and the AS-SET in its export policy · AS-SET contains your AS, lives in a RIR database and has a hierarchical name · AS-SET in PeeringDB · at least two upstreams · ASPA: providers visible in BGP but missing from your ASPA, entries not visible in BGP, provider-free ASPA (AS0) despite visible upstreams, the scrubbing centre's AS, and a ready ASPA proposal · ROAs for the scrubbing centre's AS when it originates · stale route objects.
AS-SET hygiene: expanded size against customers visible in BGP · nesting depth · largest member sets · IXP/peer sets inside a customer set · members not seen in BGP · who includes your AS in their AS-SETs — see AS-SET hygiene below.
Prefix level: length ≤ /24 and ≤ /48 · RPKI state · how many /24 (/48) blocks will be RPKI-valid after splitting · broad maxLength · AS0 ROAs · other-AS ROAs · route object in a RIR database (not RADB, not RIPE-NONAUTH) · route objects for every /24 · route objects with another origin · resource holder different from the AS holder, or PA space from a LIR (LOA needed) · less specific announced by another AS (upstream LOA needed).
The basis for every test — RFCs, RIPE and RIR documents, talks and articles, scrubbing provider documentation — is listed with authors and links in Sources and credits at the bottom of this page.
An AS-SET is what your upstreams — and a scrubbing centre — use to build the filter for routes they accept from you. RPKI ROAs validate only the origin AS; the transit part of the path is protected by these RPSL-based filters. That makes the AS-SET a security object, not documentation:
- Too big: if your AS-SET expands to thousands of ASes, a route leak from one of your customers passes your upstream's filter. Thousands of AS-SETs on the Internet expand to over 1,000 ASes, some to more than the whole routing table (Doug Madory, Job Snijders, 2025).
- Wrong content: an AS-SET used for filtering should list your customer cone only. IXP member lists and peer lists inside it make it explode. Rule of thumb from Lasse Jarlskov: would you re-advertise this in BGP? If not, it does not belong in your AS-SET.
- Included by others: anyone can add your AS to their AS-SET. With a spoofed origin the announcement is ROA-valid and passes RPSL-based transit filters — this is how the prelude to a hijack attempt presented at DKNOG15 looked. Defence: review who includes you, ask for removal, publish ASPA and monitor the IRRs.
The tool checks:
| Check | Flagged when | Step in the action plan |
|---|---|---|
| Size of each of your AS-SETs | it expands to more than 1,000 ASes or 10× the customers visible in BGP (to fix); over 3× (recommended) | Tidy up the AS-SET |
| Nesting depth | more than 5 levels | Tidy up the AS-SET |
| Largest member sets | a member set brings at least 100 ASes and 30 % of the total | Tidy up the AS-SET |
| IXP and peer sets inside a customer set | member names look like IXP or peer lists | Tidy up the AS-SET |
| Members not seen in BGP | a direct member is not visible as your customer | Tidy up the AS-SET |
| Who includes your AS | AS-SETs of networks with no visible BGP relationship (to fix); peer/IXP lists and sets without an owner AS in the name (recommended) | Check who includes your AS in their AS-SETs |
| Prefix counts and prefix lists | local version with bgpq4 only | Prefix lists section |
| Verdict | not ready / ready with reservations / ready, with counters |
| Action plan | steps in the order worth following, each with instructions for your RIR and a link to its documentation |
| Ready objects | ROAs (per /24 per RFC 9319, or maxLength on the aggregate), route objects in RPSL, an LOA draft with prefixes and holders |
| AS-SET hygiene | size, depth, largest members, IXP/peer sets, stale members, who includes your AS |
| Prefix table | RPKI state, how many /24 (/48) are valid after splitting, route object, holder |
| Prefix lists (local version) | prefix counts of your AS-SETs, Junos prefix-list, full list as .txt (bgpq4) |
| Manual checklist | LOA, tunnel and MSS, propagation time, announcement and withdrawal, routing loops, customer filtering, dry run, RTBH |
| Export | print to PDF, JSON |
Screenshots: AS25152 (K-root, RIPE NCC), 15 October 2026. The tool has a light and a dark theme:
Polish, English, German, French, Spanish, Portuguese, Italian, Dutch, Czech
and Romanian. The page picks the browser language and offers a switcher;
?jezyk=<code> forces one. Polish and English are built in (napisy.js,
rir.js); the other languages load on demand from jezyki/<code>.js.
You can use the tool online at https://itoro.com.pl/narzedzia/scrubbing/
or download it and run it on your own computer. The downloaded version does
everything the online one does and, with bgpq4 installed, adds prefix
lists generated from your AS-SETs (prefix counts, Junos prefix-list,
plain lists to download). Prefix lists exist only in the local version: they
need bgpq4, which talks to IRR servers directly, and a web page cannot do that
from your browser.
- ZIP: download the current version (the same as Code → Download ZIP on the repository page). Numbered versions are on the Releases page. Unpack it anywhere.
- git:
git clone https://github.com/itoro-pl/scrubbing-readiness-test.git
| Option | You need | Prefix lists (bgpq4) |
|---|---|---|
A. Windows — double-click start.bat |
Python 3.8+ (tick Add python.exe to PATH during installation) | no — use option C if you want them |
B. Linux / macOS — run ./start.sh |
Python 3 (usually already installed) + bgpq4 (Debian/Ubuntu: sudo apt install bgpq4, macOS: brew install bgpq4) |
yes, once bgpq4 is installed |
| C. Docker (Windows, Linux, macOS) | Docker Desktop on Windows/macOS, or Docker Engine on Linux | yes, bgpq4 is inside the image |
Do I need Docker for Windows? Only if you want prefix lists on Windows.
For everything else start.bat and Python are enough. (Alternatively, install
bgpq4 in WSL and run ./start.sh there.)
A — Windows: double-click start.bat. The browser opens at
http://127.0.0.1:8765/. Close the window (or press Ctrl+C) to stop.
B — Linux / macOS:
./start.shC — Docker, in the unpacked folder:
docker compose up --buildthen open http://127.0.0.1:8765/. Without Compose:
docker build -t itoro-scrubbing .
docker run --rm -p 127.0.0.1:8765:8765 itoro-scrubbingOptions of the local server: start.bat --port 9000, ./start.sh --port 9000,
--bez-przegladarki (do not open the browser). The server listens only on
127.0.0.1; the Docker example publishes the port on 127.0.0.1 too.
The local server (serwer.py, Python standard library only) serves the files
and two endpoints used only by the local page: /api/status and
/api/prefiksy?zbior=<AS-SET>&ip=4|6[&zrodlo=<IRR>], which run bgpq4 -j.
Input is validated and bgpq4 is called without a shell.
Language: ?jezyk=pl, en, de, fr, es, pt, it, nl, cs, ro (default: browser language). Direct
result: ?as=64496, optionally &op=<scrubbing AS>&tryb=operator.
| Data | Service |
|---|---|
| announced prefixes, ROAs and ASPA, BGP neighbours | RIPEstat Data API |
| route objects in all IRRs, AS-SET expansion, AS-SETs that include your AS | IRR Explorer (NLNOG) |
| resource holder, abuse contact (all RIRs) | RDAP, server chosen by the IANA bootstrap |
| aut-num export policy (RIPE region) | RIPE Database REST API |
| AS-SET used for filters | PeeringDB API |
| prefix lists (local version only) | bgpq4 on your computer |
All of them send CORS headers. If you host the tool behind a
Content-Security-Policy, allow in connect-src:
https://stat.ripe.net https://rest.db.ripe.net https://irrexplorer.nlnog.net https://www.peeringdb.com https://data.iana.org https://rdap.db.ripe.net https://rdap.arin.net https://rdap.apnic.net https://rdap.afrinic.net https://rdap.lacnic.net https://rdap.registro.br https://rdap.org.
| Path | Contents |
|---|---|
index.html |
the page |
app.js |
tests, RDAP lookups and result view; no external libraries |
napisy.js |
all interface texts, PL and EN |
rir.js |
step-by-step instructions for RIPE NCC, ARIN, APNIC, AFRINIC, LACNIC (PL and EN) |
jezyki/ |
DE, FR, ES, PT, IT, NL, CS, RO — interface and RIR instructions |
zrzuty/ |
screenshots used in this README |
serwer.py, start.bat, start.sh |
local server (Python stdlib) with the optional bgpq4 endpoint; one-click start |
Dockerfile, docker-compose.yml |
image with Python and bgpq4 |
skrypty/ |
QA: node skrypty/sprawdz-jezyki.js . (translation structure), python skrypty/sprawdz-uklad.py <url> <AS> (layout in all languages), python skrypty/zrzuty.py <url> <AS> zrzuty pl en (screenshots; Playwright) |
style.css |
light and dark theme, WCAG 2.1 AA contrast |
CHANGELOG.md |
version history (EN, PL) |
There is no ITORO server. The AS number goes from your browser straight to the public services above. The result can be printed to PDF or saved as JSON.
- Large networks: prefix-level lookups cover the first 150 prefixes.
- Requirements not published by providers (LOA wording, tunnels, BGP communities) are listed as a manual checklist, not tested.
- RIR portals change their menus; every instruction links to the RIR's own documentation.
1.2.0 — 19 October 2026: ASPA checks after Ondřej Caletka's DKNOG16 talk — providers missing from
ASPA, entries not seen in BGP, provider-free ASPA with upstreams, a ready ASPA proposal, ASPA rules and a
router checklist item. 1.1.0 — 17 October 2026: AS-SET hygiene checks, „who includes your AS”,
downloadable version (start.bat, start.sh, Docker with bgpq4) with prefix
lists, full author names in sources. 1.0.0 — 15 October 2026: first release.
Details in CHANGELOG.md.
The tests follow four kinds of sources: IETF RFCs; RIPE NCC documents and the documentation of the RIPE Database and other RIRs; operator talks and articles on AS-SET hygiene; and the public onboarding documentation of well-known DDoS mitigation (scrubbing) providers. Checked on 15–17 October 2026. Where a provider does not publish a requirement, we say so instead of guessing.
| Document | What we take from it | Test in the tool |
|---|---|---|
| RFC 6811 — BGP Prefix Origin Validation | the three states: valid, invalid, not found | RPKI state of each announced prefix |
| RFC 9319 (BCP 185) — The Use of maxLength in the RPKI, §5 | use minimal ROAs, avoid maxLength unless it has no effect | „broad maxLength” recommendation; ROA suggestions in two variants (separate ROAs per /24, or maxLength on the aggregate) with the trade-off explained |
| RFC 9319, §5.1 — ROAs for DDoS mitigation services | a provider that announces the customer's prefix needs its own ROA, and the ROA must exist before the attack because RPKI propagates slower than BGP | ROA check for the scrubbing provider's AS („operator announces from its own AS” mode); propagation warning |
| RFC 9319, §6 — RTBH (RTDR) | do not widen ROAs (maxLength, very specific prefixes) to support RTBH | item in „what cannot be checked from outside” |
| RFC 9582 — A Profile for ROAs | maxLength equal to the prefix length is not encoded; ROA semantics | ROA coverage calculation |
| RFC 6483 — Validation of Route Origination, §4 | an AS0 ROA means the prefix must not be routed | AS0 ROA check |
| RFC 7454 (BCP 194) — BGP Operations and Security, §6.1.3 | IPv4 prefixes longer than /24 and IPv6 longer than /48 are commonly filtered; IRR as the basis for prefix filters | prefix length check; split target /24 and /48; route object checks |
| RFC 2622 — RPSL, §5 | hierarchical set names (AS64496:AS-NAME) | AS-SET name check |
| RFC 7999 — BLACKHOLE community | RTBH signalling, separate from diversion | context for the RTBH note |
| ASPA — IETF SIDROPS (draft-ietf-sidrops-aspa-profile, draft-ietf-sidrops-aspa-verification) | a customer's ASPA must list every provider AS on the path | ASPA must include the scrubbing provider's AS |
| Document | What we take from it | Test in the tool |
|---|---|---|
| ripe-705 — Abuse Contact Management in the RIPE Database | abuse-c is mandatory for aut-num and for directly allocated inetnum/inet6num | abuse contact check |
| RIPE Database documentation — Set objects | new as-set objects must have hierarchical names; existing short names stay valid | AS-SET name check (recommendation, not an error) |
| RIPE Database documentation — Protection of objects with hierarchical names | creation of a hierarchical set is authorised by the parent object | rationale for the recommendation |
| RIPE Labs — Out-of-region route(6) and aut-num objects | out-of-region objects moved to source RIPE-NONAUTH (since 4 September 2018) | RIPE-NONAUTH is not treated as an authoritative IRR |
| RIPEstat Data API | announced prefixes, ROAs and ASPA, abuse contact, BGP neighbours | data source |
| RIPE Database REST API | aut-num, as-set, inetnum/inet6num (holder organisation, status PA/PI) | AS-SET contents; LOA need (other organisation, PA space from a LIR) |
| RIR | ROA | IRR (route, as-set) | abuse contact | ASPA |
|---|---|---|---|---|
| RIPE NCC | ROA management | RIPE Database docs | abuse-c FAQ | ASPA in the RPKI Dashboard |
| ARIN | Hosted RPKI | ARIN IRR user guide | POC records | ASPA |
| APNIC | Creating ROAs in MyAPNIC | as-set guide | abuse-c | ASPA at APNIC |
| AFRINIC | RPKI | route objects, as-set | abuse contact | not announced (October 2026) |
| LACNIC | IRR (route objects generated from ROAs) | IRR help | LAC-2018-5 | announcement, October 2026 |
Resource holder and abuse data for every RIR come from RDAP; the authoritative server is found through the IANA RDAP bootstrap (RFC 9224).
| Author(s) | Title, venue, date | What we take from it | Test in the tool |
|---|---|---|---|
| Lasse Jarlskov (Telia Company) | „Securing your AS-set”, BalticNOG 2025, Vilnius, 25 September 2025; same talk at the Netnod meeting, 8 October 2025 (slides, PDF) | three AS-SET types (customers, peers, IXP members) — only the customer set is used to build filters; rule of thumb „would you re-advertise this in BGP?”; bigger is not better, recursion is dangerous; clean up regularly; check your customers' AS-SET sizes; check who includes you | AS-SET size against BGP customers, nesting depth, largest member sets, IXP/peer sets inside a customer set, members not seen in BGP, who includes your AS |
| Lasse Jarlskov (Telia Company); ASPA part with Job Snijders | „Prelude to a BGP hijack?”, DKNOG15, Copenhagen, 7 March 2025 (video) | anyone can put your AS in their AS-SET; with a spoofed origin the route is ROA-valid and passes RPSL-based transit filters; defence: ASPA and monitoring IRRs for new references to your AS | who includes your AS (sets of networks with no BGP relationship are flagged); ASPA recommendation; monitoring step |
| Doug Madory, Job Snijders | „The Scourge of Excessive AS-SETs”, Kentik blog, 23 April 2025 | thousands of AS-SETs expand to over 1,000 ASNs, some beyond the whole routing table; such filters did not stop real route leaks; keep membership minimal, avoid recursion, use hierarchical names, name the authoritative IRR source in PeeringDB | AS-SET size and depth, hierarchical name, PeeringDB AS-SET with source |
| Ondřej Caletka (RIPE NCC) | „Autonomous System Provider Authorisation — New tool for routing security”, DKNOG16, March 2026 (slides, PDF) | ROAs do not protect against forged AS paths or path-preserving leaks — ASPA does; list all providers, backup ones too; do not list plain peers; list non-transparent IXP route servers; update ASPA together with the IRR; on routers reject invalid, start with logging, warn customers who did not list you | providers visible in BGP missing from ASPA, ASPA entries not visible in BGP, provider-free ASPA (AS0) with visible upstreams, ready ASPA proposal, ASPA rules in the action plan, router checklist |
| MANRS | „Module 2: IRRs, RPKI, and PeeringDB” (MANRS training) | document your customer cone with an as-set (e.g. AS64500:AS-CUSTOMERS), register route objects, publish routing policy in aut-num, keep PeeringDB up to date | AS-SET in aut-num export, AS-SET contains your AS, PeeringDB |
| Source | What we take from it |
|---|---|
| MANRS — Network Operators | register routing intent in IRR and RPKI, keep contacts up to date (RIR database, PeeringDB) |
| IRR Explorer (NLNOG) | route objects from all IRRs with their RPKI status — data source |
| PeeringDB API | the AS-SET many operators use to build filters — data source |
The tool itself does not name providers; it refers to „typical requirements of scrubbing centre operators”. The list below is what those requirements are based on.
| Provider | Published requirements | Source |
|---|---|---|
| Cloudflare Magic Transit | minimum /24; IRR entries must match the origin AS; LOA (from the ISP as well if the ISP announces); GRE or IPsec with MSS clamping (≤1436 / ≤1360) set before cut-over; safe withdrawal: announce from your own network first | prerequisites, advertise prefixes |
| Cloudflare BYOIP | IPv4 /24, IPv6 /48; prefix in one of the five RIRs; exact route/route6 object with the announcing origin (an RPKI-derived IRR entry is not enough); ROA verified; at least 5 h provisioning | get started, IRR best practices |
| Lumen DDoS Mitigation | off-net minimum /24 and /48; a customer with ROAs must add a ROA for the Lumen AS or ROV networks drop the announcement; the customer must ignore more specifics of its own space sent back by Lumen | service guide |
| Link11 | only /24 prefixes; route object in an authoritative RIR database, recognised within 48 h; public AS required | FAQ |
| F5 Distributed Cloud Routed DDoS | /24 or shorter; authoritative IRR (RIPE, ARIN…); ROA required; LOA for prefixes the customer does not hold | L3/L4 DDoS mitigation |
| Gcore | prefix from /8 to /24; public AS; LOA mandatory; GRE MTU 1476 / MSS 1436 | network submission |
| OVHcloud BYOIP | IPv4 /24–/19; inetnum must match the range exactly (PA, PI, LEGACY); route object with the OVHcloud or customer origin; range not announced elsewhere | Bring your own IP |
| NASK anti-DDoS (Poland), variant II | AS from RIPE NCC; mask up to /24 (larger blocks protected as a set of /24s); the customer must be able to create route objects and change ROAs; prepend or suppress the /24 to transit | regulations, annex |
| Akamai Prolexic Routed | GRE (RFC 2784) with keepalives, MSS 1436 / 1380, decapsulation capacity ≥ 2× CIR. ROA/IRR/LOA requirements are not published | service descriptions |
| Imperva DDoS Protection for Networks | GRE to at least two data centres; in always-on mode Imperva must be the best path (prepend, local-pref or a more specific prefix). ROA/IRR/LOA requirements are not published | documentation |
Not used, because no public technical requirements were found: Radware, NETSCOUT Arbor Cloud, Corero, Voxility, Path.net and Polish operators other than NASK.
| Test | Sources |
|---|---|
| Every /24 (/48) split out of an announced block is RPKI-valid | RFC 6811, RFC 9319 §5.1, RFC 7454; Link11, NASK, Cloudflare |
| Prefix not longer than /24 (/48) | RFC 7454 §6.1.3; Cloudflare, Lumen, Link11, F5, Gcore, NASK |
| Route object with your AS in a RIR database (not RADB, not RIPE-NONAUTH, not RPKI-derived) | RFC 7454; RIPE Labs (RIPE-NONAUTH); Cloudflare BYOIP, Link11, F5 |
| Route object for each /24 that may be announced | Cloudflare BYOIP (exact match), Link11, NASK |
| LOA when the space belongs to another organisation or is PA from a LIR | Cloudflare, F5, Gcore |
| ROA for the provider's AS when it originates | RFC 9319 §5.1; Lumen |
| ASPA includes the provider's AS | IETF SIDROPS ASPA |
| ASPA lists all providers seen in BGP, no provider-free ASPA with upstreams, ASPA proposal | Ondřej Caletka (DKNOG16, 2026); IETF SIDROPS ASPA |
| abuse-c | ripe-705; MANRS |
| AS-SET contains your AS, hierarchical name | RFC 2622; RIPE Database documentation; MANRS |
| AS0 ROA, conflicting route objects with another origin | RFC 6483; RFC 6811 |
| AS-SET size, depth, largest members, IXP/peer sets, members not seen in BGP | Lasse Jarlskov (BalticNOG 2025); Doug Madory and Job Snijders (2025); MANRS module 2 |
| Who includes your AS in their AS-SETs | Lasse Jarlskov (BalticNOG 2025, DKNOG15) |
| Broad maxLength (recommendation) | RFC 9319 §5 |
Code: AGPL-3.0-or-later (file LICENSE).
Substantive content — test descriptions, RIR instructions, interface texts,
documentation: CC BY-SA 4.0 (file LICENSE-TRESC.md).
Data from external services and the ITORO trademark — see NOTICE.
We deploy and operate DDoS protection systems, mainly in telecommunications networks and data centres. https://itoro.com.pl







