Re: ignore max length as an argument of roa_check
Hi, > Let's assume an IXP has member A who has customer B, who propagates some address range. Who is responsible for originating blackhole route for IP addres from such range propagated to the IXP? FWIW, my understanding of "Local Scope of Blackholes" from https://tools.ietf.org/html/rfc7999#section-3.2 is that it's allowed to cautiously propagate a route tagged with BLACKHOLE when policies are explicitly in place between adjacent networks to treat those routes according to RFC7999. If I got your example right, B originates the BLACKHOLE prefix to ask A to mitigate an attack that they are receiving. B announces it to A. A is a member of IXP, and it has peering relationships with peer n (n could be either another member or a route server). If there is an agreement between A and IXPn to treat BLACKHOLE routes according to RFC7999, in that case (according to my understanding) A could propagate that route to IXPn as it is, with AS_PATH "A, B". The origin AS would still be B. IXPn would be the one in charge of implementing the sanity checks to verify that the route is valid. The point I wanted to raise with my original message is that I believe the current implementation of 'ignore max length' might be a bit too loose. That knob de-facto goes against the way RFC6811 works, and if I understand it correctly, it does it at a very global level, for all the ROAs inside the table. Having a ROA table where the maxLength of all the ROAs is ignored makes that table unusable for strict origin validation, and in my opinion poses an avoidable risk by creating an entity that could still be consumed by roa_check for purposes that are different than the one we're discussing in this thread, that is something-similar-to-origin-validation for blackhole requests handling. On the basis of my experience, sometimes, having a handy solution to quickly solve reachability issues could be seen as the way to go, especially while under pressure, but that would cause more damage than it solves ;-) I believe that turning 'ignore max length' on, seeing that it "solves" the issue, and then forgetting about it could be a very easy and likely path in certain circumstances, and that it could undermine the benefits given by the whole global RPKI/OV deployment effort. To your point, I also believe that RPKI OV as per RFC6811 is not appropriate to handle blackhole requests. In a recent message to Sidrops we can read: > Work in under way to harmonize RPKI & BGP blackholing. The IETF's draft submission window currently is closed, but as soon as it opens, I will upload a document detailing a possible way forward. (1 or 2 weeks from now) (https://mailarchive.ietf.org/arch/msg/sidrops/v0tVaVcT2WHe9vW2x_GKg52KX-E/) It will probably take a bit of time before a solution based on the above will be ready for production, but I believe that in the meantime it could be worth exploring other less intrusive methods to satisfy the request you received, without weakening RPKI OV "too much". If the desire is to really tweak OV in a way that it could deal with such blackhole routes, I'd suggest rethinking the way that config knob is used today. We just heard feedback on this list where the author mentioned the need of dealing with multiple ROAs tables. This seems very suboptimal to me. What do you think about moving that knob to roa_check? That would allow to keep only one ROA table, with all the bits in place to safely perform a strict OV. roa_check could be changed to accept an additional argument, ignore_maxlength, whose default value could be False. Additionally, the code that takes ignore_maxlength=True into consideration could be implemented to kick in only when BLACKHOLE is attached to the route being processed. In my opinion this could be a "good" trade-off solution to still satisfy the original need, while keeping the behaviour of roa_check secure-by-default and not prone to misusage. This seems to me the "least privilege" approach to prefer. Another more drastic proposal could be to just drop the config knob completely and keep the OV implementation secure, leaving it up to other forums to come up with a solution, agreed upon by the community. Discussing this a bit with other people, they proposed the use of SLURM on the receiving network side to tune the RPKI information in a way that the BLACKHOLE routes could still be accepted. I understand that there may be other implications on using a similar approach, which may collide with the original requirement you had, but now that the outcome of the ROAs processing is immediately reflected into the filters it could still be the best trade-off between keeping a secure implementation, not prone to misuse, and a solution able to satisfy the users requirement. WDYT? Cheers, Pier Carlo
ignore max length as an argument of roa_check
Hello, first, thanks to the devs for 2.0.8! I see the option 'ignore max length' was introduced, and that it's possible to enable it at protocol configuration time. ignore max length switch Ignore received max length in ROA records and use max value (32 or 128) instead. This may be useful for implementing loose RPKI check for blackholes. Default: disabled. I was wondering what other people's feelings would be about having a similar option available at validation time, more specifically as an argument of roa_check. If my understanding is correct, being the current option available only at protocol level, it means that all the ROAs that are present inside the ROA table are used as if the maxLength attribute is not set. This means that it wouldn't be possible to configure a filter to perform a strict OV check (where the maxLength is also taken into account) using ROAs from that table. Having that option available at roa_check time, the same table could be used to perform both strict validation and also a loose validation, for example depending on the presence of the BLACKHOLE BGP community: (pseudo-code follows) # ... regular sanity checks done here... if BLACKHOLE { if (roa_check(ignore_max_lenght=True) = ROA_INVALID) then { reject; } accept; } else { if (roa_check() = ROA_INVALID) then { reject; } accept; } (Assuming ignore_max_lenght has default value == False.) Does it make sense? Thanks Pier Carlo Chiodi
Re: BIRD 2.0.7 Segmentation fault when using receive limit
Hi, thanks a lot, I've managed to test it and I confirm that works fine. Can you confirm whether it will be included in 2.0.8? Thanks, Pier Carlo On Sun, 15 Nov 2020 at 16:07, Ondrej Zajicek wrote: > On Sun, Nov 01, 2020 at 02:36:40PM +0100, Pier Carlo Chiodi wrote: > > Hello, was anyone else able to reproduce this issue? > > I've been able to reproduce it also using the code from master. > > > > I paste some more info here, I hope they'll be useful to troubleshoot it. > > > > Thanks > > Hi > > Sorry for late answer, Here is the patch. > > -- > Elen sila lumenn' omentielvo > > Ondrej 'Santiago' Zajicek (email: santi...@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." >
Re: BIRD 2.0.7 Segmentation fault when using receive limit
0x17CF05: rte_update_in (rt-table.c:2493) ==270==by 0x19A84C: rte_update3 (protocol.h:638) ==270==by 0x19E179: bgp_rte_update (packets.c:1331) ==270==by 0x19E6E8: bgp_decode_nlri_ip4 (packets.c:1479) ==270==by 0x1A02B4: bgp_decode_nlri (packets.c:2410) ==270== Address 0xcdcdcdcdcdcdcde5 is not stack'd, malloc'd or (recently) free'd ==270== ==270== ==270== Process terminating with default action of signal 11 (SIGSEGV) ==270== General Protection Fault ==270==at 0x159EB1: net_format (net.c:82) ==270==by 0x15B37F: bvsnprintf (printf.c:246) ==270==by 0x15C3AE: buffer_vprint (printf.c:531) ==270==by 0x1E2D09: vlog (log.c:219) ==270==by 0x1E2E05: log_msg (log.c:244) ==270==by 0x178D34: rte_trace (rt-table.c:555) ==270==by 0x178D78: rte_trace_in (rt-table.c:562) ==270==by 0x17CF05: rte_update_in (rt-table.c:2493) ==270==by 0x19A84C: rte_update3 (protocol.h:638) ==270==by 0x19E179: bgp_rte_update (packets.c:1331) ==270==by 0x19E6E8: bgp_decode_nlri_ip4 (packets.c:1479) ==270==by 0x1A02B4: bgp_decode_nlri (packets.c:2410) ==270== ==270== HEAP SUMMARY: ==270== in use at exit: 156,337 bytes in 589 blocks ==270== total heap usage: 867 allocs, 278 frees, 406,303 bytes allocated ==270== ==270== LEAK SUMMARY: ==270==definitely lost: 0 bytes in 0 blocks ==270==indirectly lost: 0 bytes in 0 blocks ==270== possibly lost: 0 bytes in 0 blocks ==270==still reachable: 156,337 bytes in 589 blocks ==270== suppressed: 0 bytes in 0 blocks ==270== Reachable blocks (those to which a pointer was found) are not shown. ==270== To see them, rerun with: --leak-check=full --show-leak-kinds=all ==270== ==270== For counts of detected and suppressed errors, rerun with: -v ==270== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) Segmentation fault On Sat, 24 Oct 2020 at 16:17, Pier Carlo Chiodi wrote: > Hello, > > I'm getting a "Segmentation fault" error on BIRD 2.0.7 when I use 'receive > limit X'. I've got the error when using either 'action block' or 'action > disable'. In the same scenario, if I change the config to use 'import limit > X' everything works fine. > > The error happens as soon as the daemon receives the first "extra" route > from its peer (in the example, the 5th route while the limit is 4). Output > of '-d -f' can be found at the bottom of this msg. If the number of routes > received from the peer is equal to the limit, the issue is not hit. > > I was able to consistently reproduce what I've mentioned above using the > following config on a Docker container based on Debian 10.1 (Linux > f484b919cd3a 4.19.76-linuxkit #1 SMP Tue May 26 11:42:35 UTC 2020 x86_64 > GNU/Linux - Dockerfile can be found here > https://github.com/pierky/dockerfiles/blob/master/bird/2.0.7/Dockerfile). > > BIRD 1.6.8 works fine. > > Thanks. > > Pier Carlo > > > router id 192.0.2.2; > define rs_as = 999; > > log "/var/log/bird.log" all; > log syslog all; > debug protocols { states, routes, filters, interfaces, events }; > > timeformat base iso long; > timeformat log iso long; > timeformat protocol iso long; > timeformat routeiso long; > > protocol device {}; > > ipv4 table master4 sorted; > ipv6 table master6 sorted; > > filter receive_from_AS1_1 { > if !(source = RTS_BGP ) then > reject "source != RTS_BGP - REJECTING ", net; > > if !(net.type = NET_IP4) then > reject "AFI not enabled for this peer - REJECTING ", net; > > accept; > } > > protocol bgp AS1_1 { > > local as 999; > neighbor 192.0.2.11 as 1; > rs client; > > passive on; > ttl security off; > interpret communities off; > > # --- > ipv4 { > table master4; > > secondary; > > receive limit 4 action block; > > import table on; > import keep filtered on; > import filter receive_from_AS1_1; > > export none; > > # --- > }; > } > > > > > Output of '-d -f': > > > root@f484b919cd3a:~# bird -c /etc/bird/bird.conf -d -f > bird: device1: Initializing > bird: AS1_1: Channel ipv4 connected to table master4 > bird: AS1_1: Initializing > bird: device1: Starting > bird: device1: Scanning interfaces > bird: device1: State changed to up > bird: AS1_1: Starting > bird: AS1_1: State changed to start > bird: Started > bird: AS1_1: Started > bird: AS1_1: Incoming connection from 192.0.2.11 (port 49457) accepted > bird: AS1_1: BGP session established > bird: AS1_1: State changed to up > bird: AS1_1 > added [best] 1.0.1.0/24 unicast > bird: AS1_1 < rejected by protocol 1.0.1.0/24 unicast > bird: AS1_1 > added [best] 1.0.3.0/24 unicast > bird: AS1_1 < rejected by protocol 1.0.3.0/24 unicast > bird: AS1_1 > added [best] 1.0.2.0/24 unicast > bird: AS1_1 < rejected by protocol 1.0.2.0/24 unicast > bird: AS1_1 > added [best] 1.0.5.0/24 unicast > bird: AS1_1 < rejected by protocol 1.0.5.0/24 unicast > bird: Protocol AS1_1 hits route receive limit (4), action: disable > Segmentation fault >
BIRD 2.0.7 Segmentation fault when using receive limit
Hello, I'm getting a "Segmentation fault" error on BIRD 2.0.7 when I use 'receive limit X'. I've got the error when using either 'action block' or 'action disable'. In the same scenario, if I change the config to use 'import limit X' everything works fine. The error happens as soon as the daemon receives the first "extra" route from its peer (in the example, the 5th route while the limit is 4). Output of '-d -f' can be found at the bottom of this msg. If the number of routes received from the peer is equal to the limit, the issue is not hit. I was able to consistently reproduce what I've mentioned above using the following config on a Docker container based on Debian 10.1 (Linux f484b919cd3a 4.19.76-linuxkit #1 SMP Tue May 26 11:42:35 UTC 2020 x86_64 GNU/Linux - Dockerfile can be found here https://github.com/pierky/dockerfiles/blob/master/bird/2.0.7/Dockerfile). BIRD 1.6.8 works fine. Thanks. Pier Carlo router id 192.0.2.2; define rs_as = 999; log "/var/log/bird.log" all; log syslog all; debug protocols { states, routes, filters, interfaces, events }; timeformat base iso long; timeformat log iso long; timeformat protocol iso long; timeformat routeiso long; protocol device {}; ipv4 table master4 sorted; ipv6 table master6 sorted; filter receive_from_AS1_1 { if !(source = RTS_BGP ) then reject "source != RTS_BGP - REJECTING ", net; if !(net.type = NET_IP4) then reject "AFI not enabled for this peer - REJECTING ", net; accept; } protocol bgp AS1_1 { local as 999; neighbor 192.0.2.11 as 1; rs client; passive on; ttl security off; interpret communities off; # --- ipv4 { table master4; secondary; receive limit 4 action block; import table on; import keep filtered on; import filter receive_from_AS1_1; export none; # --- }; } Output of '-d -f': root@f484b919cd3a:~# bird -c /etc/bird/bird.conf -d -f bird: device1: Initializing bird: AS1_1: Channel ipv4 connected to table master4 bird: AS1_1: Initializing bird: device1: Starting bird: device1: Scanning interfaces bird: device1: State changed to up bird: AS1_1: Starting bird: AS1_1: State changed to start bird: Started bird: AS1_1: Started bird: AS1_1: Incoming connection from 192.0.2.11 (port 49457) accepted bird: AS1_1: BGP session established bird: AS1_1: State changed to up bird: AS1_1 > added [best] 1.0.1.0/24 unicast bird: AS1_1 < rejected by protocol 1.0.1.0/24 unicast bird: AS1_1 > added [best] 1.0.3.0/24 unicast bird: AS1_1 < rejected by protocol 1.0.3.0/24 unicast bird: AS1_1 > added [best] 1.0.2.0/24 unicast bird: AS1_1 < rejected by protocol 1.0.2.0/24 unicast bird: AS1_1 > added [best] 1.0.5.0/24 unicast bird: AS1_1 < rejected by protocol 1.0.5.0/24 unicast bird: Protocol AS1_1 hits route receive limit (4), action: disable Segmentation fault
Re: Configuring RPKI returns syntax error, unexpected CF_SYM_UNDEFINED
Hello, you might need to compile BIRD with --enable-libssh. Bests Il dom 10 nov 2019, 20:08 Brooks Swinnerton ha scritto: > Hello, > > I'm trying to configure RPKI in BIRD 2.0.6. With the following > configuration: > > ``` > 200 roa4 table r4; > 201 roa6 table r6; > 202 > 203 protocol rpki gortr { > 204 roa4 { table r4; }; > 205 roa6 { table r6; }; > 206 > 207 remote "rpki.neptunenetworks.org" port 8282; > 208 > 209 retry keep 90; > 210 refresh keep 900; > 211 expire keep 172800; > 212 } > ``` > > I receive the following when loading the configuration: > > ``` > bird> configure soft > Reading configuration from /etc/bird.conf > /etc/bird.conf:203:10 syntax error, unexpected CF_SYM_UNDEFINED > ``` >
Re: BIRD 2.0.0: RFC8097 extended communities and rpki-light
On Wed, Dec 13, 2017 at 04:03:53PM +0100, Ondrej Zajicek wrote: > Hi > > Here is a patch that should fix it. I confirm it's working as in 1.6.3 now. Is there already a scheduled release date for the fixed version? Thanks, -- Pier Carlo Chiodi https://pierky.com
BIRD 2.0.0: RFC8097 extended communities and rpki-light
Hello, while I was running some tests on BIRD 2.0.0 I've noticed that the handling of RFC8097 extended communities is different from 1.6.3. Scenario: - AS10 announces a route to the route server; - the route server adds the (0x4300, 0, 1) ext community (RFC8097); - AS20 receives the route; - clients are always both on 1.6.3. This is the filter I'm using: filter from_client { bgp_ext_community.add((unknown 0x4300, 0, 1)); accept; } The results I get follow: - when 1.6.3 is used on the route server, BIRD treats the community strictly according to RFC4360: If a route has a non-transitivity extended community, then before advertising the route across the Autonomous System boundary the community SHOULD be removed from the route. - when 2.0.0 is used, the community is treated accordingly to draft-ietf-sidrops-route-server-rpki-light-02 and is propagated to the client. Since I didn't find any reference to RFC8097/rpki-light on the web site, I was wondering if I missed something or if this is the expected behaviour. Configs and 'show route' output attached. Bests, -- Pier Carlo Chiodi https://pierky.com router id 192.0.2.10; log "/var/log/bird.log" all; log syslog all; debug protocols all; protocol device { } protocol static own_prefixes { route 1.0.1.0/24 reject; } protocol bgp the_rs { local as 10; neighbor 192.0.2.2 as 999; import all; export all; connect delay time 1; connect retry time 1; } router id 192.0.2.20; log "/var/log/bird.log" all; log syslog all; debug protocols all; protocol device { } protocol bgp the_rs { local as 20; neighbor 192.0.2.2 as 999; import all; export all; connect delay time 1; connect retry time 1; } With BIRD 2.0.0 on the route server: rs$ birdcl show route all BIRD 2.0.0 ready. Table master4: 1.0.1.0/24 unicast [AS10 17:33:32.159] * (100) [AS10i] via 192.0.2.10 on eth0 Type: BGP univ BGP.origin: IGP BGP.as_path: 10 BGP.next_hop: 192.0.2.10 BGP.local_pref: 100 BGP.ext_community: (generic, 0x4300, 0x1) rs$ birdcl show route all export AS20 BIRD 2.0.0 ready. Table master4: 1.0.1.0/24 unicast [AS10 17:33:32.159] * (100) [AS10i] via 192.0.2.10 on eth0 Type: BGP univ BGP.origin: IGP BGP.as_path: 10 BGP.next_hop: 192.0.2.10 BGP.local_pref: 100 BGP.ext_community: (generic, 0x4300, 0x1) from the receiving client: receiver$ birdcl show route all BIRD 1.6.3 ready. 1.0.1.0/24 via 192.0.2.10 on eth0 [the_rs 17:33:32 from 192.0.2.2] * (100) [AS10i] Type: BGP unicast univ BGP.origin: IGP BGP.as_path: 10 BGP.next_hop: 192.0.2.10 BGP.local_pref: 100 BGP.ext_community: (generic, 0x4300, 0x1) With BIRD 1.6.3 on the route server: rs$ birdcl show route all BIRD 1.6.3 ready. 1.0.1.0/24 via 192.0.2.10 on eth0 [AS10 17:36:56] * (100) [AS10i] Type: BGP unicast univ BGP.origin: IGP BGP.as_path: 10 BGP.next_hop: 192.0.2.10 BGP.local_pref: 100 BGP.ext_community: (generic, 0x4300, 0x1) rs$ birdcl show route all export AS20 BIRD 1.6.3 ready. 1.0.1.0/24 via 192.0.2.10 on eth0 [AS10 17:36:56] * (100) [AS10i] Type: BGP unicast univ BGP.origin: IGP BGP.as_path: 10 BGP.next_hop: 192.0.2.10 BGP.local_pref: 100 BGP.ext_community: (generic, 0x4300, 0x1) from the receiving client: receiver$ birdcl show route all BIRD 1.6.3 ready. 1.0.1.0/24 via 192.0.2.10 on eth0 [the_rs 17:36:56 from 192.0.2.2] * (100) [AS10i] Type: BGP unicast univ BGP.origin: IGP BGP.as_path: 10 BGP.next_hop: 192.0.2.10 BGP.local_pref: 100 router id 192.0.2.2; define rs_as = 999; log "/var/log/bird.log" all; log syslog all; debug protocols { states, routes, filters, interfaces, events }; protocol device {}; table master sorted; filter from_client { bgp_ext_community.add((unknown 0x4300, 0, 1)); accept; } protocol bgp AS10 { description "AS10"; local as 999; neighbor 192.0.2.10 as 10; rs client; passive on; ttl security off; interpret communities off; secondary; import keep filtered on; import filter from_client; export all; } protocol bgp AS20 { description "AS20"; local as 999; neighbor 192.0.2.20 as 20; rs client; passive on; ttl security off; interpret communities off; secondary; import keep filtered on; import filter from_client; export all; } router id 192.0.2.2; define rs_as = 999; log "/var/log/bird.log" all; log syslog all; debug protocols { states, route