]>
Commit | Line | Data |
---|---|---|
b08d4dde SS |
1 | package Guardian::IPtables; |
2 | use strict; | |
3 | use warnings; | |
4 | ||
5 | use Exporter qw(import); | |
6 | ||
7 | our @EXPORT = qw(DoBlock DoUnblock DoFlush); | |
8 | ||
9 | # The path to the iptables executeable. | |
10 | my $iptables = "/usr/sbin/iptables"; | |
11 | ||
12 | # The used firewall chain. | |
13 | my $chain = "INPUT"; | |
14 | ||
15 | # | |
16 | ## The DoBlock subroutine. | |
17 | # | |
18 | ## This subroutine is called, when a given address should be locked by | |
19 | ## using IPtables. | |
20 | # | |
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. | |
24 | # | |
25 | sub DoBlock (@) { | |
26 | my ($address, $action) = @_; | |
27 | ||
28 | # If no action has been given, default to "DROP". | |
29 | unless($action) { | |
30 | $action = "DROP"; | |
31 | } | |
32 | ||
33 | # Call iptables to block the given address. | |
34 | system("$iptables --wait -A $chain -s $address -j $action"); | |
35 | } | |
36 | ||
37 | # | |
38 | ## The DoUnblock subroutine. | |
39 | # | |
40 | ## This subroutine can be used to delete all firewall rules (unblock) | |
41 | ## of a previously blocked address. | |
42 | # | |
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. | |
47 | # | |
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. | |
51 | # | |
52 | sub DoUnblock ($) { | |
53 | my ($address) = @_; | |
54 | ||
55 | # Get rulepositions for the specified address. | |
56 | my @rules = &_get_rules_positions_by_address($address); | |
57 | ||
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"); | |
62 | } | |
63 | } | |
64 | ||
65 | # | |
66 | ## The DoFlush subroutine. | |
67 | # | |
68 | ## Call this subroutine to entirely flush the IPtables chain. | |
69 | # | |
70 | sub DoFlush () { | |
71 | # Call iptalbes and flush the chain. | |
72 | system("$iptables --wait -F $chain"); | |
73 | } | |
74 | ||
75 | # | |
76 | ## Get rules subroutine. | |
77 | # | |
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. | |
81 | # | |
82 | sub _get_rules_positions_by_address ($) { | |
83 | my ($address) = @_; | |
84 | ||
85 | # Array to store the rule positions. | |
86 | my @rules; | |
87 | ||
88 | # Call iptables and list all firewall rules. | |
89 | open(RULES, "$iptables --wait -L $chain -n -v --line-numbers |"); | |
90 | ||
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/); | |
96 | ||
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; | |
101 | ||
102 | # Compare the current source address with the given one. | |
103 | # If they are equal, the rule position will be added to the | |
104 | # rules array. | |
105 | if ($address eq $source) { | |
106 | push(@rules, $pos); | |
107 | } | |
108 | } | |
109 | ||
110 | # Reverse the array. | |
111 | my @reversed_rules = reverse @rules; | |
112 | ||
113 | # Return the reversed array. | |
114 | return @reversed_rules; | |
115 | } | |
116 | ||
117 | 1; |