NAME

Net::Firewall::BlockerHelper::backends::aws_wafv2 - AWS WAFv2 IP set backend via the aws CLI.

VERSION

Version 0.1.0

SYNOPSIS

use Net::Firewall::BlockerHelper;

my $fw_helper = Net::Firewall::BlockerHelper->new(
    backend => 'aws_wafv2',
    name    => 'ssh',
    options => {
        scope => 'REGIONAL',
        name4 => 'blocklist-v4',
        id4   => 'aaaa-bbbb',
        name6 => 'blocklist-v6',
        id6   => 'cccc-dddd',
    },
);

$fw_helper->init_backend;
$fw_helper->ban( ban => '1.2.3.4' );
$fw_helper->unban( ban => '1.2.3.4' );

DESCRIPTION

Blocks IPs by maintaining the addresses of AWS WAFv2 IP sets, using the aws CLI. A WAF rule referencing the IP set(s) then blocks the traffic.

A WAFv2 IP set holds a single address family, so this backend manages up to two of them: an IPv4 set (name4/id4) and an IPv6 set (name6/id6). Banning an address of a family whose set is not configured is an error.

Updating an IP set is a two step operation: a get-ip-set to obtain the current LockToken, then an update-ip-set supplying the full desired address list plus that token (WAFv2 uses optimistic locking). The full banned set for the family is rendered on every change.

This backend manages only the IP set contents; the IP set(s) and the WAF rule and Web ACL referencing them must already exist. The Web ACL must also be associated with the resources to be protected, ALBs, API Gateways, and the like for REGIONAL or the distribution for CLOUDFRONT, as a Web ACL nothing uses blocks nothing.

Requires the aws CLI in the PATH, configured with credentials able to get and update the IP sets.

METHODS

new

- options :: Backend specific options. See below.
- name :: Required by Net::Firewall::BlockerHelper, otherwise unused.

The options hash accepts the following.

- aws_cmd :: Path to the aws binary.
    - Default :: aws

- scope :: WAFv2 scope, 'REGIONAL' or 'CLOUDFRONT'.
    - Default :: REGIONAL

- region :: Optional region; appended as --region when set.
    - Default :: undef

- name4 / id4 :: Name and id of the IPv4 IP set.
    - Default :: undef

- name6 / id6 :: Name and id of the IPv6 IP set.
    - Default :: undef

At least the family being banned must have both its name and id set.

All errors are considered fatal, meaning if new fails it will die.

init

Initiates the backend. Runs aws wafv2 get-ip-set for each configured IP set to verify it exists and is reachable, erroring if any of them fail. Nothing is modified.

Note that for bans to have an effect the Web ACL referencing the IP sets must be associated with the resources to be protected. See "DESCRIPTION".

ban

Bans an IP. The value of ban is validated as being a IPv4 or IPv6 address and lowercased, then added to the ban list. The IP set for its family is then updated via a get-ip-set to fetch the current LockToken followed by an update-ip-set supplying the full banned list for that family, with single IPs rendered as /32 or /128 CIDRs. Banning an IP whose family has no IP set configured is an error. 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 removed from the ban list. The IP set for its family is then rewritten without it via a get-ip-set plus update-ip-set pair. Unbanning an IP that is not banned is a noop.

$fw_helper->unban( ban => $ip );

ban_cidr

Bans a CIDR range by adding it to the IP set for its family. WAFv2 IP sets store CIDR ranges natively, so the range is used as is. The value of ban is validated as being a IPv4 or IPv6 CIDR and lowercased. Banning a CIDR whose family has no IP set configured is an error. Banning an already banned CIDR is a noop.

$fw_helper->ban_cidr( ban => '1.2.3.0/24' );

unban_cidr

Unbans a CIDR range by removing it from the IP set for its family, rewriting the set via a get-ip-set plus update-ip-set pair. The value of ban is validated as being a IPv4 or IPv6 CIDR and lowercased. Unbanning a CIDR 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 CIDR ranges from internal state; the IP sets are 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 IP sets are not queried. CIDR ranges are not included; for those see "list_cidr".

my @banned = $fw_helper->list;

re_init

Tears down and re-initiates, then re-applies the full retained ban list, both single IPs and CIDR ranges, to each configured IP set via get-ip-set plus update-ip-set.

$fw_helper->re_init;

teardown

Empties each configured IP set by pushing an empty address list via update-ip-set. The internal ban list is kept so a following re_init restores it. The IP sets themselves are not deleted.

$fw_helper->teardown;

stop

Alias for "teardown".

$fw_helper->stop;

check

Verifies each configured IP set is still fetchable by running aws wafv2 get-ip-set against it. Returns 1 if all succeed and 0 if any fail.

$result=$fw_helper->check;

flush

Removes all bans at once by clearing the internal ban lists, both single IPs and CIDR ranges, and pushing the now empty address list to each configured IP set via update-ip-set.

$fw_helper->flush;

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. A get-ip-set for a configured IP set failed.

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, scopeInvalid

The scope option is not either "REGIONAL" or "CLOUDFRONT".

24, checkFailed

The backend check raised an error.

25, flushFailed

Failed to flush the bans.

30, ipsetNotConfigured

No IP set is configured for the family, IPv4 or IPv6, of the item.

31, banCidrFailed

Failed to ban the CIDR range.

32, unbanCidrFailed

Failed to unban the CIDR range.

33, 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.

34, cidrNotSupported

The backend does not support CIDR bans.

35, 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) 2026 by Zane C. Bowers-Hadley.

This is free software, licensed under:

The GNU Lesser General Public License, Version 2.1, February 1999