NAME
Net::Firewall::BlockerHelper::backends::azure - Azure NSG backend via the az CLI.
VERSION
Version 0.1.0
SYNOPSIS
use Net::Firewall::BlockerHelper;
my $fw_helper = Net::Firewall::BlockerHelper->new(
backend => 'azure',
name => 'ssh',
options => {
resource_group => 'my-rg',
nsg => 'my-nsg',
rule => 'blocklist',
},
);
$fw_helper->init_backend;
$fw_helper->ban( ban => '1.2.3.4' );
$fw_helper->unban( ban => '1.2.3.4' );
DESCRIPTION
Blocks IPs on Azure by maintaining the --source-address-prefixes of a single deny rule in a Network Security Group, using the az CLI. The full set of currently banned IPs is rendered into the rule on every change, so ban/unban are idempotent. Both IPv4 and IPv6 share the one rule.
This backend manages only the rule's source prefixes. The NSG, the inbound deny security rule, and the NSG's association with the subnets or NICs to be protected must already exist.
Requires the az CLI in the PATH, logged in with rights to update the rule.
NOTES
This backend was written going off the az CLI docs and actual testing is needed to double check a few things as the exact behavior is not clear.
When the ban list goes empty, as at teardown or flush, the rule update ends up passing --source-address-prefixes with no value, and whether the az CLI accepts that or errors needs checking.
METHODS
new
Initiates the backend object. Nothing is contacted at this point; that is done by "init".
- options :: Backend specific options. See below.
- name :: Required by Net::Firewall::BlockerHelper, otherwise unused.
The options hash accepts the following.
- az_cmd :: Path to the az binary.
- Default :: az
- resource_group :: Resource group of the NSG. Required.
- Default :: undef
- nsg :: Network Security Group name. Required.
- Default :: undef
- rule :: Security rule whose source prefixes are managed. Required.
- Default :: undef
- subscription :: Optional subscription; appended as --subscription when set.
- Default :: undef
All errors are considered fatal, meaning if new fails it will die.
init
Initiates the backend, verifying the configured security rule exists via az network nsg rule show. Nothing is created; the NSG and rule must already exist.
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 full set of banned IPs (rendered as /32 or /128 prefixes) and CIDR ranges is then pushed to the rule via az network nsg rule update --source-address-prefixes. 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 rule's source prefixes are re-rendered without it via az network nsg rule update. 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 and lowercased, then added verbatim to the rule's source prefixes via az network nsg rule update. 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 and lowercased, then the rule's source prefixes are re-rendered without it via az network nsg rule update. 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.
my @banned_cidrs = $fw_helper->list_cidr;
list
List banned IPs. Returns an array of the currently banned single IPs from the in-memory ban list; the rule is not queried. CIDR ranges are not included; for those see "list_cidr".
my @banned = $fw_helper->list;
re_init
Tears down (errors ignored) and re-initiates the backend, then re-applies the full retained set of banned IPs and CIDR ranges to the rule via az network nsg rule update.
teardown
Empties the rule's source prefixes. The internal ban list is kept so a following re_init restores them.
stop
Alias for "teardown".
check
Verifies the rule still exists by running az network nsg rule show. Returns 1 if the command exits zero and 0 otherwise.
flush
Removes all bans at once by clearing both the single IP and CIDR ban lists and re-rendering the rule's now empty source prefixes via az network nsg rule update.
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.
24, checkFailed
The backend check raised an error.
25, flushFailed
Failed to flush the bans.
30, resourceGroupNotDefined
The option resource_group is undef or blank.
31, nsgNotDefined
The option nsg is undef or blank.
32, ruleNotDefined
The option rule is undef or blank.
33, banCidrFailed
Failed to ban the CIDR range.
34, unbanCidrFailed
Failed to unban the CIDR range.
35, 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.
36, cidrNotSupported
The backend does not support CIDR bans.
37, 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