]>
Commit | Line | Data |
---|---|---|
ec187877 SS |
1 | #!/usr/bin/perl |
2 | ############################################################################### | |
3 | # # | |
4 | # IPFire.org - A linux based firewall # | |
5 | # Copyright (C) 2007-2022 IPFire Team <info@ipfire.org> # | |
6 | # # | |
7 | # This program is free software: you can redistribute it and/or modify # | |
8 | # it under the terms of the GNU General Public License as published by # | |
9 | # the Free Software Foundation, either version 3 of the License, or # | |
10 | # (at your option) any later version. # | |
11 | # # | |
12 | # This program is distributed in the hope that it will be useful, # | |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | |
15 | # GNU General Public License for more details. # | |
16 | # # | |
17 | # You should have received a copy of the GNU General Public License # | |
18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | |
19 | # # | |
20 | ############################################################################### | |
21 | ||
22 | use strict; | |
23 | use POSIX; | |
24 | ||
25 | # Load perl module to talk to the kernel syslog. | |
26 | use Sys::Syslog qw(:DEFAULT setlogsock); | |
27 | ||
28 | require '/var/ipfire/general-functions.pl'; | |
29 | require "${General::swroot}/ipblocklist-functions.pl"; | |
30 | require "${General::swroot}/lang.pl"; | |
31 | ||
32 | # Hash to store the settings. | |
33 | my %settings = (); | |
34 | ||
ec187877 | 35 | # Establish the connection to the syslog service. |
82fea6d5 | 36 | openlog('ipblocklist', 'cons', 'user'); |
ec187877 SS |
37 | |
38 | # Grab the configured providers. | |
39 | &General::readhash("${General::swroot}/ipblocklist/settings", \%settings); | |
40 | ||
41 | # Check if the blocklist feature is enabled. | |
42 | unless ($settings{'ENABLE'} eq "on") { | |
43 | # Exit. | |
44 | exit 0; | |
45 | } | |
46 | ||
47 | # Check if the red device is active. | |
48 | unless (-e "${General::swroot}/red/active") { | |
49 | # Log to syslog. | |
50 | &_log_to_syslog("<ERROR> Could not update any blocklist - The system is offline!"); | |
51 | ||
52 | # Exit. | |
53 | exit 1; | |
54 | } | |
55 | ||
56 | # Get all available blocklists. | |
57 | my @blocklists = &IPblocklist::get_blocklists(); | |
58 | ||
ac8e283e SS |
59 | # Array to store successfully update blocklists. |
60 | # They need to be reloaded. | |
61 | my @updated_blocklists = (); | |
62 | ||
ec187877 SS |
63 | # Gather the details, when a list got modified last time. |
64 | my %modified = (); | |
65 | ||
66 | # Read-in data if the file exists. | |
67 | &General::readhash($IPblocklist::modified_file, \%modified ) if (-e $IPblocklist::modified_file); | |
68 | ||
69 | # Loop through the array of blocklists. | |
70 | foreach my $blocklist (@blocklists) { | |
71 | # Skip if the blocklist is not enabled. | |
72 | next if($settings{$blocklist} ne "on"); | |
73 | ||
74 | # Get current time. | |
75 | my $time = time(); | |
76 | ||
77 | # Get time, when the blocklist has been downloaded last. | |
78 | my $last_download_time = $modified{$blocklist}; | |
79 | ||
80 | # Get the holdoff rate in seconds for the current processed blocklist. | |
81 | my $rate_time = &IPblocklist::get_holdoff_rate($blocklist); | |
82 | ||
83 | # Calculate holdoff time. | |
84 | my $holdoff_time = $last_download_time + $rate_time; | |
85 | ||
86 | # Check if enough time has passed since the last download of the list. | |
87 | if ($time <= $holdoff_time) { | |
88 | # To frequent updates, log to syslog. | |
89 | &_log_to_syslog("<INFO> Skipping $blocklist blocklist - Too frequent update attempts!"); | |
90 | ||
91 | # Skip this provider. | |
92 | next; | |
93 | } | |
94 | ||
95 | # Try to download and update the blocklist. | |
96 | my $return = &IPblocklist::download_and_create_blocklist($blocklist); | |
97 | ||
98 | # Check if we got a return code. | |
99 | if ($return) { | |
100 | # Handle different return codes. | |
101 | if ($return eq "not_modified") { | |
102 | # Log notice to syslog. | |
103 | &_log_to_syslog("<INFO> Skipping $blocklist blocklist - It has not been modified!"); | |
104 | } elsif ($return eq "dl_error") { | |
105 | # Log error to the syslog. | |
106 | &_log_to_syslog("<ERROR> Could not update $blocklist blocklist - Download error\!"); | |
107 | } else { | |
108 | # Log error to syslog. | |
109 | &_log_to_syslog("<ERROR> Could not update $blocklist blocklist - Unexpected error\!"); | |
110 | } | |
111 | } else { | |
41d3d33d SS |
112 | # Get the filename of the blocklist. |
113 | my $ipset_db_file = &IPblocklist::get_ipset_db_file($blocklist); | |
114 | ||
115 | # Set the correct ownership. | |
116 | &IPblocklist::set_ownership($ipset_db_file); | |
117 | ||
ec187877 SS |
118 | # Log successfull update. |
119 | &_log_to_syslog("<INFO> Successfully updated $blocklist blocklist."); | |
ac8e283e SS |
120 | |
121 | # Add the list to the array of updated blocklists. | |
122 | push(@updated_blocklists, $blocklist); | |
123 | } | |
124 | } | |
125 | ||
126 | # Check if a blocklist has been updated and therefore needs to be reloaded. | |
127 | if (@updated_blocklists) { | |
41d3d33d SS |
128 | # Set correct ownership to the modified file. |
129 | &IPblocklist::set_ownership($IPblocklist::modified_file); | |
130 | ||
ac8e283e SS |
131 | # Loop through the array. |
132 | foreach my $updated_blocklist (@updated_blocklists) { | |
133 | # Get the blocklist file. | |
134 | my $ipset_db_file = &IPblocklist::get_ipset_db_file($updated_blocklist); | |
135 | ||
136 | # Call safe system function to reload/update the blocklist. | |
41d3d33d | 137 | &General::safe_system("ipset", "restore", "-f", "$ipset_db_file"); |
404b5137 SS |
138 | |
139 | # The set name contains a "v4" as suffix. | |
140 | my $set_name = "$updated_blocklist" . "v4"; | |
141 | ||
142 | # Swap the sets to use the new one. | |
41d3d33d | 143 | &General::safe_system("ipset", "swap", "$set_name", "$updated_blocklist"); |
404b5137 SS |
144 | |
145 | # Destroy the old blocklist. | |
41d3d33d | 146 | &General::safe_system("ipset", "destroy", "$set_name"); |
ec187877 SS |
147 | } |
148 | } | |
149 | ||
150 | END { | |
151 | # Close connection to syslog. | |
152 | closelog(); | |
153 | } | |
154 | ||
155 | # | |
156 | # Tiny function to sent the error message to the syslog. | |
157 | # | |
158 | sub _log_to_syslog($) { | |
159 | my ($message) = @_; | |
160 | ||
161 | # The syslog function works best with an array based input, | |
162 | # so generate one before passing the message details to syslog. | |
163 | my @syslog = ("ERR", "$message"); | |
164 | ||
165 | # Send the log message. | |
166 | syslog(@syslog); | |
167 | } | |
168 | ||
169 | 1; |