Disclosure up front: I run IPYE, a company that leases IP space. Most of this article is practical how-to; IPYE appears where a free /48, LOA, or ROA helps you try the work, with a short call to action at the end.
BIRD 2 is a small, fast routing daemon with a filter language that makes export policy explicit. That suits a single-prefix edge: you want to announce one aggregate and accept a controlled set of routes. This article builds a production-oriented BIRD 2 config for a free IPv6 /48 from IPYE, using ASN 64496, an upstream 64497 at 2001:db8:0:1::1, and the prefix 2001:db8:100::/48.
Install and keep the config in Git
On Debian or Ubuntu, apt install bird2 installs the daemon with its config at /etc/bird/bird.conf. Put that file under version control from the first day and deploy it with a check:
bird -p -c /etc/bird/bird.conf && birdc configure bird -p parses the file and exits, so a syntax error never reaches the running daemon. birdc configure reloads gracefully and keeps sessions up when only filters change.
Base configuration
router id 192.0.2.1; log syslog all; define OUR_ASN = 64496; define OUR_V6 = [ 2001:db8:100::/48 ]; protocol device { } protocol kernel kernel6 { ipv6 { import none; export filter { if source = RTS_BGP then accept; reject; }; }; merge paths on; } protocol static static6 { ipv6; route 2001:db8:100::/48 blackhole; } The static blackhole gives BIRD a route to originate and keeps unused parts of the prefix from bouncing back upstream. Specific addresses on interfaces win over the blackhole because they are longer matches.
Filters before protocols
filter export_upstream { if net ~ OUR_V6 && source = RTS_STATIC then accept; reject; } filter import_upstream { if net.len > 48 then reject; if net ~ [ 2001:db8::/32+, fc00::/7+, fe80::/10+, ::/8+ ] then reject; if bgp_path.len > 64 then reject; accept; } The export filter is the safety net that matters most: it accepts only the exact aggregate from the static protocol and rejects everything else, including routes learned from other peers. Note the + operator, which matches the prefix and all longer ones.
In production, drop 2001:db8::/32 from your own bogon list only if you are actually using documentation space in a lab; on the Internet it should always be rejected.
The BGP protocol
protocol bgp upstream1 { description "VPS upstream"; local 2001:db8:0:1::2 as OUR_ASN; neighbor 2001:db8:0:1::1 as 64497; hold time 30; graceful restart on; ipv6 { import limit 1000 action restart; import filter import_upstream; export filter export_upstream; }; } For a multihop route server, add multihop 2; and make sure a route to the server exists. If the provider requires MD5, add a password line and load the secret from a file that is not in Git, using BIRD's include statement.
Verification
birdc show protocols all upstream1 birdc show route export upstream1 birdc show route for 2001:db8:100::1 all show route export is the line to check before you tell anyone the prefix is live. It prints exactly what BIRD is sending after the filter. If it lists more than your /48, stop and fix the filter.
Test filters without a live session
BIRD can evaluate a filter against a route already in its table:
birdc eval '2001:db8:100::/48 ~ [ 2001:db8:100::/48 ]' birdc show route filter export_upstream The second command lists routes in the master table that would pass the export filter. Running it in CI against a staging daemon is a cheap way to catch a filter edit that suddenly exports more than one prefix.
Match the origin to the paperwork
The upstream will usually ask for an LOA naming AS64496; download it from the IPYE portal. The ROA is created automatically, so the last check is a validator: run routinator vrps --noupdate | grep 2001:db8:100 and confirm the origin matches the local ... as line in BIRD. If you later change ASN in the IPYE dashboard, update OUR_ASN, reload, and recheck the VRP before you expect global reachability.
Adding a second peer
Use a template so both sessions share the same policy:
template bgp upstream_tpl { local as OUR_ASN; hold time 30; ipv6 { import filter import_upstream; export filter export_upstream; }; } protocol bgp upstream2 from upstream_tpl { neighbor 2001:db8:0:2::1 as 64498; } Logs and metrics
Send BIRD logs to syslog and alert on lines that contain BGP session state changes. For metrics, the bird_exporter project exposes protocol state and route counts to Prometheus; alert when the exported route count for an upstream is anything other than one.
Do this next
Claim a free /48 from IPYE, drop it into OUR_V6, and confirm show route export lists only that prefix before the first session comes up. Questions: ipye@turnel.com.
About IPYE
IPYE (https://ipye.com) leases IPv4, IPv6 and ASN space with instant setup. Your first IPv6 /48 is free for the first year, a real allocation you can announce on your own ASN, with a LOA from the portal and the ROA created automatically. ASN and region changes apply automatically. IPv4 /24 to /22 leases include LOA, ROA and per-/24 rDNS; WHOIS is editable on IPv6 /44 and larger. Locations: Los Angeles, New York, Ashburn, Salt Lake City, London, Amsterdam, Frankfurt. Claim your free /48: https://my.ipye.com/products/ipv6-rental. Questions: ipye@turnel.com.
Disclosure: I run IPYE
