NAME
Net::Firewall::BlockerHelper::backends::bgp_rtbh - BGP Remote Triggered Black Hole backend (via ExaBGP, GoBGP, or FRR).
VERSION
Version 0.2.0
SYNOPSIS
use Net::Firewall::BlockerHelper;
my $fw_helper = Net::Firewall::BlockerHelper->new(
backend => 'bgp_rtbh',
name => 'rtbh',
options => {
next_hop => '192.0.2.1',
community => '65535:666',
},
);
$fw_helper->init_backend;
$fw_helper->ban( ban => '1.2.3.4' );
$fw_helper->unban( ban => '1.2.3.4' );
$fw_helper->teardown;
DESCRIPTION
Blocks IPs with BGP Remote Triggered Black Holing. Rather than filtering locally, each banned IP is announced to the network as a host route (/32 for IPv4, /128 for IPv6) carrying the well-known BLACKHOLE community (65535:666, RFC 7999). Upstream routers that honor it then drop the traffic, moving the drop off this host and, with a transit provider that accepts blackhole announcements, off the local link entirely.
Announcements are driven through one of three drivers, selected with the driver option: ExaBGP's exabgpcli (the default), gobgp, or frr. The exabgp and gobgp drivers talk to a running daemon that holds the BGP session(s) to the routers, while the frr driver injects a blackhole static route via vtysh for a running bgpd to redistribute. This backend does not manage that session, it only announces and withdraws routes.
Whether the announced prefix blackholes the traffic's source or destination depends on the receiving router: destination based RTBH drops traffic toward the prefix, while source based RTBH (loose uRPF plus the blackhole community) drops traffic from it. As this tool bans attacker source addresses, a source based RTBH setup is the usual pairing.
Requires the configured driver's binary in the PATH (exabgpcli, gobgp, or vtysh) and a running, configured daemon behind it (exabgp, gobgpd, or FRR's bgpd).
METHODS
new
Initiates the object. Errors are fatal with this method.
- options :: A hash of options. See below.
- name :: Required by Net::Firewall::BlockerHelper, otherwise unused.
The options hash accepts the following.
- driver :: Which BGP daemon to drive, 'exabgp', 'gobgp', or 'frr'. The
frr driver injects a blackhole static route via vtysh (which a
redistribute-static route-map on the router tags with the blackhole
community for BGP); it does not use next_hop/community directly.
- Default :: exabgp
- announce_type :: 'rtbh' (announce a blackholed host route) or 'flowspec'
(announce a FlowSpec rule discarding traffic from the source IP).
flowspec is supported by the exabgp and gobgp drivers only.
- Default :: rtbh
- exabgpcli_cmd :: Path to the exabgpcli binary (driver 'exabgp').
- Default :: exabgpcli
- gobgp_cmd :: Path to the gobgp binary (driver 'gobgp').
- Default :: gobgp
- vtysh_cmd :: Path to the vtysh binary (driver 'frr').
- Default :: vtysh
- community :: BGP community attached to every announced route. The
default is the RFC 7999 well-known BLACKHOLE community.
- Default :: 65535:666
- next_hop :: Next hop for IPv4 announcements. On the receiving router
this is what maps to the discard interface.
- Default :: 192.0.2.1
- next_hop6 :: Next hop for IPv6 announcements.
- Default :: 100::1
- mask4 :: Prefix length used for IPv4 announcements.
- Default :: 32
- mask6 :: Prefix length used for IPv6 announcements.
- Default :: 128
- extra :: Optional extra attributes appended verbatim to each announce.
The syntax is driver specific (exabgp 'local-preference 50' vs
gobgp 'local-pref 50').
- Default :: undef
All errors are considered fatal, meaning if new fails it will die.
init
Initiates the backend. The BGP session is owned by the running BGP daemon (exabgp, gobgpd, or FRR), so there is nothing to set up; this only flips the inited flag.
ban
Bans an IP. The value of ban is validated as being a IPv4 or IPv6 address and lowercased, then announced via the configured driver: a exabgpcli announce route or gobgp global rib add of the host route (mask4/mask6 prefix length) with the family-appropriate next hop and the blackhole community, a FlowSpec discard rule when announce_type is flowspec, or a vtysh injected blackhole static route for the frr driver. Banning an already banned IP is a noop.
$fw_helper->ban( ban => $ip );
unban
Unbans an IP. The value of ban is validated as being a IPv4 or IPv6 address and lowercased, then the route announced for it by "ban" is withdrawn via the configured driver (exabgpcli withdraw, gobgp global rib del, or a vtysh no ... blackhole for frr). Unbanning an IP that is not banned is a noop.
$fw_helper->unban( ban => $ip );
ban_cidr
Bans a CIDR range. The value of ban is validated as being a IPv4 or IPv6 CIDR range and lowercased, then announced the same way "ban" announces a single IP, except the range is announced verbatim rather than having the mask4/mask6 host prefix length appended. Banning an already banned range is a noop.
$fw_helper->ban_cidr( ban => '1.2.3.0/24' );
unban_cidr
Unbans a CIDR range. The value of ban is validated as being a IPv4 or IPv6 CIDR range and lowercased, then the route announced for it by "ban_cidr" is withdrawn via the configured driver. Unbanning a range that is not banned is a noop.
$fw_helper->unban_cidr( ban => '1.2.3.0/24' );
list_cidr
List banned CIDR ranges. Returns an array of the currently banned ranges from internal state; the BGP daemon is not queried.
my @banned_cidrs = $fw_helper->list_cidr;
list
List banned IPs. Returns an array of the currently banned single IPs from internal state; the BGP daemon is not queried. CIDR ranges are not included; for those see "list_cidr".
my @banned = $fw_helper->list;
re_init
Re-announces every retained blackhole route. A best effort teardown (failures ignored) is done first, then the announce command is re-run for every banned IP and CIDR range. The BGP daemons do not persist announced state across restarts, so this is how the announcements are restored after the daemon is bounced.
teardown
Withdraws every announced blackhole route, running the driver's withdraw command for each banned IP and CIDR range, and marks the backend as not inited. The ban list is retained, so "re_init" can restore the announcements.
stop
Alias for "teardown".
check
Runs the driver's neighbor summary command (exabgpcli show neighbor summary, gobgp neighbor, or vtysh -c 'show ip bgp summary' for frr) and treats a zero exit as healthy, returning 1, and 0 otherwise. This only confirms the BGP daemon holding the announcements is reachable; whether the sessions to the routers are up and the announcements accepted is not checked.
flush
Removes all bans at once by running the driver's withdraw command for every banned IP and CIDR range, then clearing the ban lists.
ERROR CODES / FLAGS
Error handling is provided by Error::Helper. All errors are considered fatal.
1, notInited
The backend has not been inited yet.
8, optionsNotHash
The item passed to new for options is not a hash.
9, noBanItem
No IP or CIDR range specified to ban or unban.
10, banItemNotIP
The item to ban is not an IP. Either wrong ref type or regexp test using Regexp::IPv4 and Regexp::IPv6 failed.
12, backendInitError
Failed to init the backend.
13, banFailed
Failed to ban the item.
14, unbanFailed
Failed to unban the item.
15, listFailed
Failed to get a list of bans.
16, reInitFailed
Failed to re_init the backend.
17, teardownFailed
Failed to teardown the backend.
18, alreadyInited
init called, but the backend has already been inited.
20, driverInvalid
The driver option is not one of 'exabgp', 'gobgp', or 'frr'.
21, announceTypeInvalid
The announce_type is not 'rtbh' or 'flowspec', or flowspec was requested with the frr driver, which does not support it.
24, checkFailed
The backend check raised an error.
25, flushFailed
Failed to flush the bans.
26, banCidrFailed
Failed to ban the CIDR range.
27, unbanCidrFailed
Failed to unban the CIDR range.
28, cidrItemNotCidr
The item to ban is not a CIDR range. Either wrong ref type or it is not an IPv4 or IPv6 address followed by a prefix length valid for its family.
29, cidrNotSupported
The backend does not support CIDR bans.
30, listCidrFailed
Failed to get a list of CIDR bans.
AUTHOR
Zane C. Bowers-Hadley, <vvelox at vvelox.ent>
LICENSE AND COPYRIGHT
This software is Copyright (c) 2023 by Zane C. Bowers-Hadley.
This is free software, licensed under:
The GNU Lesser General Public License, Version 2.1, February 1999