One thing we all learn quickly after getting started with BGP is that if left to its own devices, the protocol will happily propagate everything everywhere. So when buying transit service from ISPs A and B, your BGP router will send ISP A’s BGP updates to ISP B and vice versa. When peering over an Internet Exchange with peers 1 and 2, peer 1 will be able to send traffic to peer 2 through your network. This is usually not what you want.
So we need to filter our BGP updates. But how?
First, outgoing updates. In smaller networks, this can be done using AS path filters that only allow the network’s own AS number and the ASNs of any BGP-speaking customers. Another way to do the same thing is with a prefix list that lists all the network’s own prefixes and any customer prefixes. Best practice is to combine the two, so only the right prefixes with the right AS paths are allowed. In Cisco-like syntax for this looks as follows:
ip as-path access-list 2 permit ^$
ip prefix-list outfilter seq 5 permit 192.0.2.0/24
router bgp 9000
neighbor 10.0.0.1 remote-as 10000
neighbor 10.0.0.1 prefix-list outfilter out
neighbor 10.0.0.1 filter-list 2 out
The as-path access-list 2 has a regular expression that only allows empty AS paths, which will match locally advertised prefixes. (The local AS will be added to the path after the filter has been applied.) As always, everything not explicitly allowed (that would be all other possible AS paths) is denied by the filter. The prefix-list outfilter simply allows the network’s own prefix, and both filters are applied to BGP neighbor 10.0.0.1 for outgoing updates.
For small networks, these filters work well. However, in networks with many routers it quickly gets tedious to keep the filters in sync across all routers. In those networks, the usual approach is to tag prefixes with a community value as soon as they enter the network, and then allow all prefixes tagged with the appropriate community in outgoing updates.
So far so good. But the hard part is filtering incoming updates. There are currently more than half a million IPv4 prefixes in BGP. I’m sure some of them shouldn’t be there. But how do we know which ones are the bad ones? There is no master list. In the case of a peering relationship with another AS, you could ask them to send a list of prefixes and AS numbers they advertise in BGP and build filters based on that information. But in practice, this doesn’t work very well because there are no established procedures to keep such filters up to date. (However, it is important to do this for BGP-capable customers as a backstop against BGP misconfiguration on their end. Any misconfigurations are unlikely to be caught as updates propagate beyond the first hop.)
So usually, filtering incoming BGP updates is limited to known bad prefixes. The prime example of that would be your own prefixes. No, I’m not saying those are bad. I’m saying it would be bad if someone else were to tell your routers that they have the best path towards your addresses. Without filters, this will happen if someone advertises a subprefix to you that falls within your address block—thanks to the longest match first rule.
The following filter blocks this:
ip prefix-list infilter seq 5 deny 192.0.2.0/24 le 32
ip prefix-list infilter seq 10 permit 0.0.0.0/0 le 24
router bgp 9000
neighbor 10.0.0.1 remote-as 10000
neighbor 10.0.0.1 prefix-list infilter in
The magic is in the “le 32” part. This means that not only 192.0.2.0/24 is filtered, but also all sub-prefixes with a prefix length less than or equal to /32. So 192.0.2.0/25, 192.0.2.1/32, 192.0.2.192/26, … All of them. The second line allows all possible IPv4 prefixes that weren’t reject by the first line, as long as they have a prefix length of no more than 24 bits. This is common practice to avoid excessively long prefixes from taking up space in the BGP table.
There is no need to have an AS path filter that rejects the local AS, as BGP will do that automatically because installing prefixes that already have the local AS in their AS path would create a loop.
In addition to the above, it’s possible to filter bogons and/or martians. Bogons are addresses that haven’t been given out yet. This list is subject to constant change, so it’s important to have a procedure to update bogon filters regularly. And pretty much all usable IPv4 addresses have been given out now, so bogon filtering isn’t likely to catch all that much. However, Team Cymru still keeps its bogon reference up to date for this purpose.
That leaves the martians, the special addresses that shouldn’t be routed in BGP. Examples are 0.0.0.0/8, which represents the default route, 127.0.0.0/8, which contains the localhost address, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, the addresses set aside for private use, and 240.0.0.0/4, which has been tragically reserved for some future use that will never come. See RFC 6890 for the full list.
Remember, good filters make good BGP neighbors.