misunderstanding or incorrectly implemented filter?
Hello, (please keep me in CC) we use filters from https://bgpfilterguide.nlnog.net/ One of the first functions checks for bogon ASNs way before the RPKI ROA check:
filter transit_in {
reject_bogon_asns(); [...] if (net.type = NET_IP4) then { if (roa_check(r4, net, bgp_path.last) = ROA_INVALID) then { print "Reject RPKI INVALID announcement ", net, " by AS", bgp_path.last; reject; } } [...]
My assumption was that an announcement from AS0 would never end up at the RPKI ROA check since it is already tested and rejected earlier at the reject_bogon_asns() function but then I found log entries suggesting otherwise:
Reject RPKI INVALID announcement 200.124.231.0/24 by AS0
So I was wondering: - Did I incorrectly assume first match wins? - Is the reject_bogon_asns() function not working as intended?
define BOGON_ASNS = [ 0, # RFC 7607 23456, # RFC 4893 AS_TRANS 64496..64511, # RFC 5398 and documentation/example ASNs 64512..65534, # RFC 6996 Private ASNs 65535, # RFC 7300 Last 16 bit ASN 65536..65551, # RFC 5398 and documentation/example ASNs 65552..131071, # RFC IANA reserved ASNs 4200000000..4294967294, # RFC 6996 Private ASNs 4294967295 # RFC 7300 Last 32 bit ASN ];
function reject_bogon_asns() int set bogon_asns; { bogon_asns = BOGON_ASNS; if ( bgp_path ~ bogon_asns ) then { print "Reject: bogon AS_PATH: ", net, " ", bgp_path; reject; } }
thanks, Christoph
On Fri, Oct 04, 2019 at 10:19:00PM +0000, Christoph wrote:
Hello,
(please keep me in CC)
we use filters from https://bgpfilterguide.nlnog.net/
One of the first functions checks for bogon ASNs way before the RPKI ROA check:
filter transit_in {
reject_bogon_asns(); [...] if (net.type = NET_IP4) then { if (roa_check(r4, net, bgp_path.last) = ROA_INVALID) then { print "Reject RPKI INVALID announcement ", net, " by AS", bgp_path.last; reject; } } [...]
My assumption was that an announcement from AS0 would never end up at the RPKI ROA check since it is already tested and rejected earlier at the reject_bogon_asns() function but then I found log entries suggesting otherwise:
Reject RPKI INVALID announcement 200.124.231.0/24 by AS0
So I was wondering: - Did I incorrectly assume first match wins? - Is the reject_bogon_asns() function not working as intended?
Hello bgp_path.last returns 0 if the last item is AS_SET. There are most likely no AS0 in the path. -- Elen sila lumenn' omentielvo Ondrej 'Santiago' Zajicek (email: santiago@crfreenet.org) OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net) "To err is human -- to blame it on a computer is even more so."
Reject RPKI INVALID announcement 200.124.231.0/24 by AS0
So I was wondering: - Did I incorrectly assume first match wins? - Is the reject_bogon_asns() function not working as intended?
Hello
bgp_path.last returns 0 if the last item is AS_SET. There are most likely no AS0 in the path.
Thank you for your explanation. I looked into the relevant RFC to find out what is supposed to happen in cases where the final segment type is AS_SET: https://tools.ietf.org/html/rfc6811 :
o Route Origin ASN: The origin AS number derived from a Route as follows:
* the rightmost AS in the final segment of the AS_PATH attribute in the Route if that segment is of type AS_SEQUENCE, or
* the BGP speaker's own AS number if that segment is of type AS_CONFED_SEQUENCE or AS_CONFED_SET or if the AS_PATH is empty, or
* the distinguished value "NONE" if the final segment of the <<<< AS_PATH attribute is of any other type. <<<< [...] We observe that no VRP can have the value "NONE" as its VRP ASN. Thus, a Route whose Origin ASN is "NONE" cannot be Matched by any VRP. Similarly, no valid Route can have an Origin ASN of zero [AS0]. Thus, no Route can be Matched by a VRP whose ASN is zero.
It looks like BIRD's mapping from "NONE" to "0" leads to the following problem and attack possibility: RPKI ROAs with an AS0 are used by address holders to state "this prefix is not in use don't accept any announcement containing it" [1]. examples: https://rpki-validator.ripe.net/roas?q=AS0 AS0 in AS_PATH is commonly filtered but the announcements in question do not actually contain any AS0 and will not be filtered. As I understand it BIRD's ROA check as seen in the documentation will return a RPKI validity state of VALID if the last AS_PATH item was of type AS_SET and the address holder created a ROA with AS0 for it. So an attacker could do the following to bypass BIRD's ROA check: - lookup prefixes for which an AS0 ROA exists - announce these prefixes using an AS_SET segment type Can you confirm that? thanks, Christoph [1] https://tools.ietf.org/html/rfc7607 :
By allowing a Resource Public Key Infrastructure (RPKI) resource holder to issue a ROA saying that AS 0 is the only valid origin for a route, we allow them to state that a particular address resource is not in use.
On Sat, Oct 05, 2019 at 10:43:00AM +0000, Christoph wrote:
Reject RPKI INVALID announcement 200.124.231.0/24 by AS0
So I was wondering: - Did I incorrectly assume first match wins? - Is the reject_bogon_asns() function not working as intended?
Hello
bgp_path.last returns 0 if the last item is AS_SET. There are most likely no AS0 in the path.
Thank you for your explanation.
I looked into the relevant RFC to find out what is supposed to happen in cases where the final segment type is AS_SET:
It looks like BIRD's mapping from "NONE" to "0" leads to the following problem and attack possibility:
RPKI ROAs with an AS0 are used by address holders to state "this prefix is not in use don't accept any announcement containing it" [1]. examples: https://rpki-validator.ripe.net/roas?q=AS0
AS0 in AS_PATH is commonly filtered but the announcements in question do not actually contain any AS0 and will not be filtered.
As I understand it BIRD's ROA check as seen in the documentation will return a RPKI validity state of VALID if the last AS_PATH item was of type AS_SET and the address holder created a ROA with AS0 for it.
That is a good point, but the ROA check verifies that ASN is non-zero in order to success: if (asn && (roa->asn == asn) && (roa->max_pxlen >= px->pxlen)) return ROA_VALID; So it should be correct. -- Elen sila lumenn' omentielvo Ondrej 'Santiago' Zajicek (email: santiago@crfreenet.org) OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net) "To err is human -- to blame it on a computer is even more so."
As I understand it BIRD's ROA check as seen in the documentation will return a RPKI validity state of VALID if the last AS_PATH item was of type AS_SET and the address holder created a ROA with AS0 for it.
That is a good point, but the ROA check verifies that ASN is non-zero in order to success:
if (asn && (roa->asn == asn) && (roa->max_pxlen >= px->pxlen)) return ROA_VALID;
So it should be correct.
I assume 'asn' is the equivalent of 'bgp_path.last' there. Thanks for getting back to me and verifying that there is no issue so fast, really appreciated!
participants (2)
-
Christoph -
Ondrej Zajicek