[ixpmanager] route server template/32bit ASNs
Andreas Polyrakis
apolyr at noc.grnet.gr
Fri Aug 7 07:56:18 IST 2015
On 08/06/2015 08:52 PM, Stefan Kaltenbrunner wrote:
>> Attached you can find our implementation of route servers, including the
>> IXPmanager templates.
>>
>> We follow approach #2, with extended communities. Although Nick's
>> concerns are valid, we have not encountered cases with members with
>> routers not supporting this feature yet.
>>
>> If you decide to follow our implementation, I can send you an improved
>> version of the function master_to_as() -- but this one also works fine.
> thanks a lot for those examples - would love to see the improved version
> of master_to_as() as well as getting those docs in a plain text format
> because it kinda looks like the PDF has some lines cut off :/
>
>
Hello Stefan,
I attach the header.cfg and neighbor.cfg that you can use to replace (or
even better, skin) your IXPmanager installation.
The improved master_to_as() function:
(a) has an additional parameter for debugging. The bird configuration
produced by IXPmanager always set this parameter to OFF (0), but when
debugging a specific peer you can set this value manually to ON (1) so
that debug messages will be printed in the log file for this specific peer
(b) augments the community-based policy so that extended communities can
be used even for 16-bit ASNs. Some of our members found confusing that
they had to use a mix of standard and extended communities, so now they
have the option of using only extended communities for prefix
advertisement control.
I also attach the html page that describes our policy to our members.
The initial pdf I sent you is from a documentation that we have uploaded
to the euroix wiki
https://wiki.euro-ix.net/index.php/BCP/Technical/Routeserver/BIRD/Samples/GR-IX
If you are a euroix member you can access this directly.
I hope these help. I will be on vacation for the next two weeks, further
replies may be a bit delayed.
If you have some comments on our implementation or documentation, or if
you improve them, please share :-)
Regards
--
-----------------------------------------------------------------------
Andreas Polyrakis - apolyr at noc.grnet.gr
GRNET NOC Technical Manager
Greek Research & Technology Network - http://www.grnet.gr
56, Mesogion Av., Ampelokipi, 11527 Athens, Greece
Mobile: +30 6972832445 Office: +30 2107474249 Fax: +30 2107474490
-----------------------------------------------------------------------
-------------- next part --------------
### Customer ID: {$int.cid} - Full name: {$int.cname} - Shortname: {$int.cshortname}
### AS number: {$int.autsys} - IPv4/6 address: {$int.address} - ID in peering VLAN: {$int.vliid} ({$int.fvliid})
### Full location name: {$int.location_name} - Location shortname: {$int.location_shortname} - Location tag: {$int.location_tag}
### Peering macro: {$int.peeringmacro} - Maximum # of prefixes: {$int.maxprefixes} - BGP MD5 secret: {$int.bgpmd5secret}
table t_{$int.cshortname}{$int.vliid};
filter peer_{$int.cshortname}{$int.vliid}_to_master
prefix set {$int.cshortname}_prefixes;
int set {$int.cshortname}_ASNs;
{
# Basic prefix validation. Do not propagate funny prefixes.
# Check first AS in AS-PATH, esp to prevent route servers peering to each other
if !(avoid_martians()) then reject;
if (bgp_path.first != {$int.autsys} ) then reject;
{* Only do filtering if this is enabled per client *}
{if $int['irrdbfilter'] }
# Check AS-PATH against the appropriate IRRDB macro
{$int.cshortname}_ASNs = [ {foreach $irrdbAsns as $a}{$a.asn}{if not $a at last},{/if} {if $a at iteration % 10 == 0} # {$int.cshortname}-{$int.vliid} - AS{$int.autsys} - {$int.address}
{/if}{/foreach} ];
if !(bgp_path.last ~ {$int.cshortname}_ASNs ) then reject "REJECTING ",net.ip,"/",net.len," received by {$int.cshortname}-{$int.vliid}, AS{$int.autsys}: Origin AS",bgp_path.last," not in AS-SET: {$int.peeringmacro}";
{if count( $prefixes )}
# Check each prefix against the route objects originating from the ASNs in the appropriate IRRDB macro
{$int.cshortname}_prefixes = [ {foreach $prefixes as $p}{$p.prefix}{if not $p at last},{/if} {/foreach} ];
if ! (net ~ {$int.cshortname}_prefixes ) then reject "REJECTING ",net.ip,"/",net.len," received by {$int.cshortname}-{$int.vliid}, AS{$int.autsys}: No route object with origin AS",bgp_path.last," for this prefix";
{else}
# Deny everything because the IRRDB returned nothing
reject;
{/if}
{else}
# This ASN was configured not to use IRRDB filtering
{/if}
# Prepend 1,2,3 times, if (RSasn,65001), (RSasn,65002), (RSasn,65003) have been set
if (RSasn,65501) ~ bgp_community then bgp_path.prepend(RSasn);
if (RSasn,65502) ~ bgp_community then { bgp_path.prepend(RSasn); bgp_path.prepend(RSasn); }
if (RSasn,65503) ~ bgp_community then { bgp_path.prepend(RSasn); bgp_path.prepend(RSasn); bgp_path.prepend(RSasn); }
# Mark prefixies with "site" community
{if $int.location_shortname eq "EIE"}
bgp_community.add ((RSasn,65101));
{/if}
{if $int.location_shortname eq "LH"}
bgp_community.add ((RSasn,65102));
{/if}
{if $int.location_shortname eq "MED"}
bgp_community.add ((RSasn,65103));
{/if}
# Done filtering & manipulation. Accept!
accept;
}
protocol pipe p_{$int.cshortname}{$int.vliid} {
description "Pipe for {$int.cshortname}{$int.vliid} (AS{$int.autsys} - {$int.address})";
table master;
mode transparent;
peer table t_{$int.cshortname}{$int.vliid};
import filter peer_{$int.cshortname}{$int.vliid}_to_master;
export where master_to_as({$int.autsys},"{$int.location_shortname}",0);
}
protocol bgp b_{$int.cshortname}{$int.vliid} from grix_rs_client {
description "BGP for {$int.cshortname}{$int.vliid} (AS{$int.autsys} - {$int.address})";
neighbor {$int.address} as {$int.autsys};
route limit {$int.maxprefixes};
table t_{$int.cshortname}{$int.vliid};
bfd on; # This should be configured for specific peers in the future.
{if $int.bgpmd5secret} password "{$int.bgpmd5secret}";{/if}
}
-------------- next part --------------
#################################################################################
#
# Bird Route Server configuration for VLAN: {$vlan->getName()} (Tag: {$vlan->getNumber()})
#
# -------------------------------------------------------------------------------
# This configuration was generated automatically by IXP Manager
# Generated: {$smarty.now|date_format:'Y-m-d H:i:s'}
#
# Attention: Do not edit manually, it will be overwritten automatically.
#
#################################################################################
#################################################################################
# BASIC DOCUMENTATION
#
#
# 1. Communities
# --------------
#
# ** Advertisement Control: **
# RSasn,PeerAS (1<=PeerAS<65000) or route origin extended community ro,RSasn,PeerAS, PeerAS>65536): Do not advertise to PeerAS
# RSasn,0 : Inverse advertising policy (do not advertise to any peers, except from those defined with RSasn:PeerASn)
#
# ** Prepending (communities can be combined)**
# RSasn,65501: prepend one time
# RSasn,65502: prepend two times
# RSasn,65503: prepend three times
#
# ** MED: **
# RSasn,65000: Do not alter incoming MED for IX switching optimisation
#
# ** Site-Marking: **
# RSasn,65101: Prefix received from a peering at EIE site
# RSasn,65102: Prefix received from a peering at LH site
# RSasn,65103: Prefix received from a peering at MED site
#
#
# 2. Route selection
# ------------------
# 1. Prefer route with the highest Local Preference attribute.
# (no practical use, Local Pref is not used in our implementation)
# 2. Prefer route with the shortest AS path.
# (in use)
# 3. Prefer IGP origin over EGP and EGP origin over incomplete.
# (in use)
# 4. Prefer the lowest value of the Multiple Exit Discriminator.
# (in use, BUT only MED from prefixes advertised by peerings of the SAME AS are compared (always-compare-med not enabled))
# 5. Prefer routes received via eBGP over ones received via iBGP.
# (no practical use, all peerings are eBGP)
# 6. Prefer routes with lower internal distance to a boundary router.
# (no practical use, all distances are the same)
# 7. Prefer older routes
# (this is not part of the route selection algorithm but it is a configurable option of the route server to avoid unstable toutes)
# 8. Prefer the route with the lowest value of router ID of the advertising router.
# (in use)
#
#
#################################################################################
timeformat base iso long;
timeformat log iso long;
timeformat protocol iso long;
timeformat route iso long;
log "{#rsconfLogfile#}" all;
log syslog all;
log stderr all;
# Turn on global debugging of all protocols
#debug protocols all;
define RSasn = {#rsconfASN#};
define RSaddress = {#rsconfListenAddr#};
router id {#rsconfRouterID#};
listen bgp address {#rsconfListenAddr#};
# ignore interface up/down events
protocol device { }
protocol direct { }
### Filter Martians Function
# This function excludes weird networks
# rfc1918, class D, class E, too long and too short prefixes
function avoid_martians()
prefix set martians;
{
{if $proto eq 6}
martians = [
::/0, # Default (can be advertised as a route in BGP to peers if desired)
::/96, # IPv4-compatible IPv6 address <E2><80><93> deprecated by RFC4291
::/128, # Unspecified address
::1/128, # Local host loopback address
::ffff:0.0.0.0/96+, # IPv4-mapped addresses
::224.0.0.0/100+, # Compatible address (IPv4 format)
::127.0.0.0/104+, # Compatible address (IPv4 format)
::0.0.0.0/104+, # Compatible address (IPv4 format)
::255.0.0.0/104+, # Compatible address (IPv4 format)
0000::/8+, # Pool used for unspecified, loopback and embedded IPv4 addresses
0200::/7+, # OSI NSAP-mapped prefix set (RFC4548) <E2><80><93> deprecated by RFC4048
3ffe::/16+, # Former 6bone, now decommissioned
2001:db8::/32+, # Reserved by IANA for special purposes and documentation
2002:e000::/20+, # Invalid 6to4 packets (IPv4 multicast)
2002:7f00::/24+, # Invalid 6to4 packets (IPv4 loopback)
2002:0000::/24+, # Invalid 6to4 packets (IPv4 default)
2002:ff00::/24+, # Invalid 6to4 packets
2002:0a00::/24+, # Invalid 6to4 packets (IPv4 private 10.0.0.0/8 network)
2002:ac10::/28+, # Invalid 6to4 packets (IPv4 private 172.16.0.0/12 network)
2002:c0a8::/32+, # Invalid 6to4 packets (IPv4 private 192.168.0.0/16 network)
fc00::/7+, # Unicast Unique Local Addresses (ULA) <E2><80><93> RFC 4193
fe80::/10+, # Link-local Unicast
fec0::/10+, # Site-local Unicast <E2><80><93> deprecated by RFC 3879 (replaced by ULA)
ff00::/8+ # Multicast
];
{else}
martians = [
10.0.0.0/8+,
169.254.0.0/16+,
172.16.0.0/12+,
192.0.0.0/24+,
192.0.2.0/24+,
192.168.0.0/16+,
198.18.0.0/15+,
198.51.100.0/24+,
203.0.113.0/24+,
224.0.0.0/4+,
240.0.0.0/4+,
0.0.0.0/32-,
0.0.0.0/0{ldelim}28,32{rdelim},
0.0.0.0/0{ldelim}0,7{rdelim}
];
{/if}
# Avoid RFC1918 and similar networks
if net ~ martians then {
print "REJECTING ",net.ip,"/",net.len," received by ",from,": Martian/too long/too short prefix";
return false;
}
return true;
}
### Filtering between members Function
# Applied on the pipes between the master table and each members' table
# peeras: the AS of the peer towards which the prefixes are exported
# site: the GR-IX POP name where the peering is located
# dbg: set to 1 to print debug messages for this peer (check the log file)
function master_to_as(int peeras;string site;int dbg)
{
# reject non-BGP routes
if ! (source = RTS_BGP) then {
if (dbg=1) then print "DEBUG ",peeras,": REJECT ",net.ip,"/",net.len," from ",from,", REASON: not a BGP prefix";
return false;
}
if ( ((RSasn,0) ~ bgp_community) || ((rt,RSasn,0) ~ bgp_ext_community) ) then { # Default reject policy. Allow only (Rsasn,peeras) or (rt,Rsasn,peeras)
if !( (peeras <= 65535 && ((RSasn,peeras) ~ bgp_community))
|| ((rt,RSasn,peeras) ~ bgp_ext_community)
) then {
if (dbg=1) then print "DEBUG ",peeras,": REJECT ",net.ip,"/",net.len," from ",from,", REASON: Default reject and not implicitely allowed ",bgp_community," - ",bgp_ext_community;
return false;
}
} else { # Default accept policy. Deny (Rsasn,peeras) or (rt,Rsasn,peeras)
if ( (peeras <= 65535 && ((RSasn,peeras) ~ bgp_community))
|| ((rt,RSasn,peeras) ~ bgp_ext_community)
) then {
if (dbg=1) then print "DEBUG ",peeras,": REJECT ",net.ip,"/",net.len," from ",from,", REASON: Default announce, but explicitely forbidden ",bgp_community," - ",bgp_ext_community;
return false;
}
}
if !((RSasn,65000) ~ bgp_community) then { # MED values are not used by the member; they can be used to optimised switching within the exchange
bgp_med = 0;
if ( site = "EIE" && (RSasn,65102) ~ bgp_community ) then bgp_med = 2;
if ( site = "EIE" && (RSasn,65103) ~ bgp_community ) then bgp_med = 4;
if ( site = "LH" && (RSasn,65101) ~ bgp_community ) then bgp_med = 2;
if ( site = "LH" && (RSasn,65103) ~ bgp_community ) then bgp_med = 2;
if ( site = "MED" && (RSasn,65101) ~ bgp_community ) then bgp_med = 4;
if ( site = "MED" && (RSasn,65102) ~ bgp_community ) then bgp_med = 2;
}
if (dbg=1) then print "DEBUG ",peeras,": ACCEPT ",net.ip,"/",net.len," from ",from," ",bgp_community," - ",bgp_ext_community;
return true;
}
### ETH0 BFD configuration
protocol bfd rs_bfd {
interface "eth0" {
interval 400ms;
multiplier 5;
passive on;
};
}
### GR-IX Route Server Client Template
template bgp grix_rs_client {
local as RSasn;
source address RSaddress;
rs client; # Preserve AS-PATH, next-hop and MED
passive on; # Do not initiate bgp sessions
prefer older on; # Do not bread ties through IDs; keep the older (more stable) route
interpret communities off; # Do not respect NO-EXPORT and NO-ADVERTISE (and preserve them in the outgoing advertisements)
graceful restart on; # Participate in graceful restart recovery
error wait time 60,43200;
export all;
{if $proto eq 4}
import filter {
## Prevent BGP NEXT_HOP Hijacking
if !( from = bgp_next_hop ) then
reject "REJECTING ",net.ip,"/",net.len,": BGP neighbor address [", from, "] does not match next hop address [", bgp_next_hop, "]";
accept;
};
{else}
import all;
{/if}
}
############### END OF COMMON CONFIG, PER MEMBER CONFIGURATION FOLLOWS ###############
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.inex.ie/pipermail/ixpmanager/attachments/20150807/a94d201a/attachment.html>
More information about the ixpmanager
mailing list