Week: 3 -- Internet-Scale BGP
Points: 20
Time estimate: 90 min lab + 3 hr independent
Deliverable: lab-3-report.md
Objectives
- Deploy Routinator and sync against live RIR RPKI repositories.
- Query the Routinator REST API for ROA validity across a set of prefixes.
- Configure FRR to reject BGP routes with Invalid RPKI state via RTR.
- Simulate a prefix hijack and verify FRR rejects it as Invalid.
Part A: Routinator Deployment and ROA Sync (20 min)
# Start Routinator
docker run -d \
--name routinator \
-p 3323:3323 \
-p 8323:8323 \
nlnetlabs/routinator
# Watch sync progress
docker logs -f routinator 2>&1 | grep -E "valid|invalid|Updating"
# Wait ~5 minutes for initial sync; verify
curl http://localhost:8323/api/v1/status | python3 -m json.tool
Verify ROA database is populated:
# Query total valid ROAs
curl "http://localhost:8323/api/v1/status" | \
python3 -c "import sys,json; d=json.load(sys.stdin); print('Valid ROAs:', d.get('valid_roas', 'N/A'))"
Part B: ROA Validity Queries (30 min)
Query the Routinator REST API for the validity state of specific prefixes. Use these test cases:
# Test each prefix -- record the validity state
PREFIXES=(
"8.8.8.0/24/15169" # Google DNS -- should be Valid
"1.1.1.0/24/13335" # Cloudflare DNS -- should be Valid
"192.0.2.0/24/64512" # Documentation prefix -- should be NotFound
"8.8.8.0/24/64512" # Google prefix, wrong AS -- should be Invalid
"8.8.8.0/25/15169" # Google /24 more-specific, same AS -- depends on maxLength
)
for pao in "${PREFIXES[@]}"; do
IFS='/' read -r prefix len asn <<< "$pao"
result=$(curl -s "http://localhost:8323/api/v1/validity/AS${asn}/${prefix}/${len}")
state=$(echo "$result" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('validated_route',{}).get('validity',{}).get('state','ERROR'))" 2>/dev/null)
echo "${prefix}/${len} AS${asn}: ${state}"
done
Record the validity state for each entry. Pay particular attention to the more-specific query: does the /25 announcement with the correct AS receive Valid or Invalid state? Why?
Part C: FRR RTR Integration and Reject-Invalid Policy (40 min)
Configure an FRR router to connect to Routinator via RTR and apply a route-map that rejects Invalid routes:
# Add FRR container to lab network (reuse Lab 1 infrastructure or deploy new)
docker run -d --name bgp-rtr \
--cap-add NET_ADMIN \
frrouting/frr:v9.1.0
FRR configuration with RPKI:
! FRR config for bgp-rtr
!
rpki
rpki polling_period 3600
rpki cache 172.17.0.2 3323 preference 1
exit
!
router bgp 65100
bgp router-id 10.99.0.1
!
neighbor 10.99.0.2 remote-as 65200
!
address-family ipv4 unicast
neighbor 10.99.0.2 activate
neighbor 10.99.0.2 route-map rm-rpki-filter in
exit-address-family
!
route-map rm-rpki-filter deny 5
match rpki invalid
!
route-map rm-rpki-filter permit 10
!
Verify RPKI session is established:
docker exec bgp-rtr vtysh -c "show rpki prefix-table"
docker exec bgp-rtr vtysh -c "show rpki cache-connection"
Simulate a prefix hijack: configure a second FRR container (bgp-hijacker) that announces a prefix with an invalid origin AS. Verify the bgp-rtr router rejects it:
# bgp-hijacker announces 8.8.8.0/24 from AS 64512 (not the rightful owner AS15169)
# bgp-rtr should reject this as Invalid per the route-map
docker exec bgp-rtr vtysh -c "show bgp ipv4 unicast 8.8.8.0/24"
# Expected: "Route has been filtered by route-map rm-rpki-filter" or not in RIB
Lab Report
Create lab-3-report.md with:
- Routinator status output: total valid ROAs, sync time
- ROA validity table (all 5 test cases; validity state for each)
- Explanation of the /25 more-specific result: is it Valid or Invalid, and why?
show rpki prefix-tableoutput (snippet showing 8.8.8.0/24 entry)- Evidence that the hijacked prefix is rejected (show bgp output or RIB state)
- One-paragraph analysis: "Pakistan Telecom's 2008 YouTube hijack -- would RPKI have prevented it? What would the ROA state have been for 208.65.153.0/24 announced from AS17557?"
Grading
| Component | Points |
|---|---|
| ROA validity table: all 5 entries correct | 6 |
| /25 more-specific explanation: maxLength correctly explained | 3 |
| RTR session: show rpki prefix-table populates correctly | 5 |
| Hijack simulation: Invalid route rejected from RIB | 4 |
| Pakistan Telecom paragraph: historically accurate and technically specific | 2 |
| Total | 20 |