1 package Guardian
::IPtables
;
5 use Exporter
qw(import);
7 our @EXPORT = qw(DoBlock DoUnblock DoFlush);
9 # The path to the iptables executeable.
10 my $iptables = "/usr/sbin/iptables";
12 # The used firewall chain.
16 ## The DoBlock subroutine.
18 ## This subroutine is called, when a given address should be locked by
21 ## Guardian is using the "append" option from IPtables, which will add the new rule
22 ## to the end of the chain to prevent from possible race-conditions when adding/deleting
23 ## rules at the same time.
26 my ($address, $action) = @_;
28 # If no action has been given, default to "DROP".
33 # Call iptables to block the given address.
34 system("$iptables --wait -A $chain -s $address -j $action");
38 ## The DoUnblock subroutine.
40 ## This subroutine can be used to delete all firewall rules (unblock)
41 ## of a previously blocked address.
43 ## To do this a subroutine will be called, which is collecting all rule
44 ## positions in the firewall chain for the given address, which returns
45 ## them in reversed order. This list of rules will be deleted one-by-one
46 ## so multiple entries (if present) for the address will be deleted.
48 ## This approach also eliminates the exact rule argument processing again
49 ## for dropping it. So it is not neccessary to know the additional arguments
50 ## like firewall action (DROP, REJECT) etc.
55 # Get rulepositions for the specified address.
56 my @rules = &_get_rules_positions_by_address
($address);
58 # Loop through the rules array and drop the firewall rules.
59 foreach my $rule (@rules) {
60 # Call iptables to delete the rule.
61 system("$iptables --wait -D $chain $rule");
66 ## The DoFlush subroutine.
68 ## Call this subroutine to entirely flush the IPtables chain.
71 # Call iptalbes and flush the chain.
72 system("$iptables --wait -F $chain");
76 ## Get rules subroutine.
78 ## This subroutine is used to get the rule position of the active
79 ## firewall rules for a given address. Those position will be collected
80 ## and returned in reversed order.
82 sub _get_rules_positions_by_address
($) {
85 # Array to store the rule positions.
88 # Call iptables and list all firewall rules.
89 open(RULES
, "$iptables --wait -L $chain -n -v --line-numbers |");
91 # Read input line by line.
92 foreach my $line (<RULES
>) {
93 # Skip descriptive line.
94 next if ($line =~ /^Chain/);
95 next if ($line =~ /^ pkts/);
97 # Generate array, based on the line content
98 # (seperator is a single or multiple space's)
99 my @comps = split(/\s{1,}/, $line);
100 my ($pos, $pkts, $bytes, $target, $prot, $opt, $in, $out, $source, $destination) = @comps;
102 # Compare the current source address with the given one.
103 # If they are equal, the rule position will be added to the
105 if ($address eq $source) {
111 my @reversed_rules = reverse @rules;
113 # Return the reversed array.
114 return @reversed_rules;