]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - html/cgi-bin/guardian.cgi
guardian.cgi: Send commands through socket connection.
[people/pmueller/ipfire-2.x.git] / html / cgi-bin / guardian.cgi
CommitLineData
01dbccb1
SS
1#!/usr/bin/perl
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
b5f7d903 5# Copyright (C) 2016 IPFire Team <info@ipfire.org> #
01dbccb1
SS
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
22use strict;
b5f7d903 23use Locale::Codes::Country;
af6856af 24use Guardian::Socket;
01dbccb1
SS
25
26# enable only the following on debugging purpose
eff1feb8
SS
27#use warnings;
28#use CGI::Carp 'fatalsToBrowser';
01dbccb1
SS
29
30require '/var/ipfire/general-functions.pl';
31require "${General::swroot}/lang.pl";
32require "${General::swroot}/header.pl";
33
34#workaround to suppress a warning when a variable is used only once
b1597f87
MF
35my @dummy = (
36 ${Header::colourred},
37 ${Header::colourgreen}
38);
39
01dbccb1
SS
40undef (@dummy);
41
42my $string=();
43my $memory=();
44my @memory=();
45my @pid=();
46my @guardian=();
01dbccb1
SS
47
48# Path to the guardian.ignore file.
49my $ignorefile ='/var/ipfire/guardian/guardian.ignore';
50
52958991
SS
51# Hash which contains the supported modules and the
52# file locations on IPFire systems.
53my %module_file_locations = (
54 "HTTPD" => "/var/log/httpd/error_log",
55 "OWNCLOUD" => "/var/owncloud/data/owncloud.log",
56 "SNORT" => "/var/log/snort.alert",
57 "SSH" => "/var/log/messages",
58);
59
01dbccb1
SS
60our %netsettings = ();
61&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
62
63our %color = ();
64our %mainsettings = ();
65&General::readhash("${General::swroot}/main/settings", \%mainsettings);
66&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
67
28981fac
SS
68# Pakfire meta file for owncloud.
69# (File exists when the addon is installed.)
bfb860ce 70my $owncloud_meta = "/opt/pakfire/db/installed/meta-owncloud";
28981fac 71
01dbccb1
SS
72our %settings = ();
73
28981fac
SS
74$settings{'ACTION'} = '';
75
01dbccb1 76$settings{'GUARDIAN_ENABLED'} = 'off';
723648ac
SS
77$settings{'GUARDIAN_MONITOR_SNORT'} = 'on';
78$settings{'GUARDIAN_MONITOR_SSH'} = 'on';
79$settings{'GUARDIAN_MONITOR_HTTPD'} = 'on';
80$settings{'GUARDIAN_MONITOR_OWNCLOUD'} = '';
52958991 81$settings{'GUARDIAN_LOG_FACILITY'} = 'syslog';
a35a0668
SS
82$settings{'GUARDIAN_LOGLEVEL'} = 'info';
83$settings{'GUARDIAN_BLOCKCOUNT'} = '3';
01dbccb1
SS
84$settings{'GUARDIAN_BLOCKTIME'} = '86400';
85$settings{'GUARDIAN_LOGFILE'} = '/var/log/guardian/guardian.log';
52958991 86$settings{'GUARDIAN_SNORT_PRIORITY_LEVEL'} = '3';
01dbccb1 87
28981fac
SS
88# Default settings for owncloud if installed.
89if ( -e "$owncloud_meta") {
723648ac 90 $settings{'GUARDIAN_MONITOR_OWNCLOUD'} = 'off';
28981fac 91}
01dbccb1
SS
92
93my $errormessage = '';
94
95&Header::showhttpheaders();
96
97# Get GUI values.
98&Header::getcgihash(\%settings);
01dbccb1 99
f8c3bfe0
SS
100# Check if guardian is running and grab some stats.
101&daemonstats();
922ddf0e 102my $pid = $pid[0];
f8c3bfe0 103
01dbccb1
SS
104## Perform input checks and save settings.
105#
106if ($settings{'ACTION'} eq $Lang::tr{'save'}) {
01dbccb1 107 # Check for valid blocktime.
96655fa6 108 unless(($settings{'GUARDIAN_BLOCKTIME'} =~ /^\d+$/) && ($settings{'GUARDIAN_BLOCKTIME'} ne "0")) {
01dbccb1 109 $errormessage = "$Lang::tr{'guardian invalid blocktime'}";
a35a0668
SS
110 }
111
112 # Check if the bloccount is valid.
96655fa6 113 unless(($settings{'GUARDIAN_BLOCKCOUNT'} =~ /^\d+$/) && ($settings{'GUARDIAN_BLOCKCOUNT'} ne "0")) {
a35a0668 114 $errormessage = "$Lang::tr{'guardian invalid blockcount'}";
01dbccb1
SS
115 }
116
117 # Check Logfile.
96655fa6 118 unless($settings{'GUARDIAN_LOGFILE'} =~ /^[a-zA-Z0-9\.\/]+$/) {
a35a0668 119 $errormessage = "$Lang::tr{'guardian invalid logfile'}";
01dbccb1
SS
120 }
121
01dbccb1 122 # Only continue if no error message has been set.
96655fa6 123 if($errormessage eq '') {
01dbccb1
SS
124 # Write configuration settings to file.
125 &General::writehash("${General::swroot}/guardian/settings", \%settings);
126
127 # Update configuration files.
128 &BuildConfiguration();
129 }
130
131## Add a new entry to the ignore file.
132#
133} elsif ($settings{'ACTION'} eq $Lang::tr{'add'}) {
134
135 # Check if any input has been performed.
136 if ($settings{'NEW_IGNORE_ENTRY'} ne '') {
137
138 # Check if the given input is no valid IP-address or IP-address with subnet, display an error message.
139 if ((!&General::validip($settings{'NEW_IGNORE_ENTRY'})) && (!&General::validipandmask($settings{'NEW_IGNORE_ENTRY'}))) {
140 $errormessage = "$Lang::tr{'guardian invalid address or subnet'}";
141 }
142 } else {
143 $errormessage = "$Lang::tr{'guardian empty input'}";
144 }
145
146 # Go further if there was no error.
147 if ($errormessage eq '') {
148 my $new_entry = $settings{'NEW_IGNORE_ENTRY'};
149
150 # Open file for appending the new entry.
151 open (FILE, ">>$ignorefile") or die "Unable to open $ignorefile for writing";
152
153 # Write the new entry to the ignore file.
154 print FILE "$new_entry\n";
155 close(FILE);
156 }
157
f8c3bfe0
SS
158 # Check if guardian is running.
159 if ($pid > 0) {
af6856af
SS
160 # Send reload command through socket connection.
161 &Guardian::Socket::Client("reload");
f8c3bfe0
SS
162 }
163
01dbccb1
SS
164## Remove entry from ignore list.
165#
166} elsif ($settings{'ACTION'} eq $Lang::tr{'remove'}) {
167 my $id = 0;
168
169 # Open ignorefile and read content.
170 open(FILE, "<$ignorefile") or die "Unable to open $ignorefile.";
171 my @current = <FILE>;
172 close(FILE);
173
174 # Re-open ignorefile for writing.
175 open(FILE, ">$ignorefile") or die "Unable to open $ignorefile for writing";
176 flock FILE, 2;
177
178 # Read line by line from ignorefile and write them back except the line with the given ID.
179 # So this line is missing in the new file and the entry has been deleted.
180 foreach my $line (@current) {
181 $id++;
a35a0668 182 unless ($settings{'ID'} eq $id) {
01dbccb1
SS
183 print FILE "$line";
184 }
185 }
186 close(FILE);
187
f8c3bfe0
SS
188 # Check if guardian is running.
189 if ($pid > 0) {
af6856af
SS
190 # Send reload command through socket connection.
191 &Guardian::Socket::Client("reload");
f8c3bfe0
SS
192 }
193
01dbccb1
SS
194## Block a user given address or subnet.
195#
196} elsif ($settings{'ACTION'} eq $Lang::tr{'block'}) {
197
c973d6da
SS
198 # Assign some temporary variables used for input validation.
199 my $input = $settings{'ADDRESS_BLOCK'};
200 my $green = $netsettings{'GREEN_ADDRESS'};
201 my $blue = $netsettings{'BLUE_ADDRESS'};
202 my $orange = $netsettings{'ORANGE_ADDRESS'};
203 my $red = $netsettings{'RED_ADDRESS'};
01dbccb1 204
c973d6da
SS
205 # Get gateway address.
206 my $gateway = &General::get_gateway();
01dbccb1 207
c973d6da
SS
208 # Check if any input has been performed.
209 if ($input eq '') {
210 $errormessage = "$Lang::tr{'guardian empty input'}";
211 }
212
213 # Check if the given input is localhost (127.0.0.1).
214 elsif ($input eq "127.0.0.1") {
215 $errormessage = "$Lang::tr{'guardian blocking of this address is not allowed'}";
216 }
217
218 # Check if the given input is anywhere (0.0.0.0).
219 elsif ($input eq "0.0.0.0") {
220 $errormessage = "$Lang::tr{'guardian blocking of this address is not allowed'}";
221 }
222
223 # Check if the given input is one of the interface addresses or our gateway.
224 elsif ($input eq "$green" || $input eq "$blue" || $input eq "$orange" || $input eq "$red" || $input eq "$gateway") {
225 $errormessage = "$Lang::tr{'guardian blocking of this address is not allowed'}";
226 }
227
228 # Check if the given input is a valid IP address.
229 elsif (!&General::validip($input)) {
230 $errormessage = "$Lang::tr{'guardian invalid address or subnet'}";
231 }
01dbccb1
SS
232
233 # Go further if there was no error.
234 if ($errormessage eq '') {
235 my $block = $settings{'ADDRESS_BLOCK'};
236
af6856af
SS
237 # Send command to block the specified address through socket connection.
238 &Guardian::Socket::Client("block $block");
01dbccb1
SS
239 }
240
241## Unblock address or subnet.
242#
243} elsif ($settings{'ACTION'} eq $Lang::tr{'unblock'}) {
244
245 # Check if no empty input has been performed.
246 if ($settings{'ADDRESS_UNBLOCK'} ne '') {
247
248 # Check if the given input is no valid IP-address or IP-address with subnet, display an error message.
249 if ((!&General::validip($settings{'ADDRESS_UNBLOCK'})) && (!&General::validipandmask($settings{'ADDRESS_UNBLOCK'}))) {
250 $errormessage = "$Lang::tr{'guardian invalid address or subnet'}";
251 }
252
253 } else {
254 $errormessage = "$Lang::tr{'guardian empty input'}";
255 }
256
257 # Go further if there was no error.
258 if ($errormessage eq '') {
259 my $unblock = $settings{'ADDRESS_UNBLOCK'};
260
af6856af
SS
261 # Send command to unblock the given address through socket connection.
262 &Guardian::Socket::Client("unblock $unblock");
01dbccb1
SS
263 }
264
265## Unblock all.
266#
267} elsif ($settings{'ACTION'} eq $Lang::tr{'unblock all'}) {
268
af6856af
SS
269 # Send flush command through socket connection.
270 &Guardian::Socket::Client("flush");
01dbccb1
SS
271}
272
36dbcf2e
SS
273# Load settings from file.
274&General::readhash("${General::swroot}/guardian/settings", \%settings);
01dbccb1
SS
275
276# Call functions to generate whole page.
277&showMainBox();
278&showIgnoreBox();
279
280# Display area only if guardian is running.
f8c3bfe0 281if ( ($memory != 0) && ($pid > 0) ) {
01dbccb1
SS
282 &showBlockedBox();
283}
284
285# Function to display the status of guardian and allow base configuration.
286sub showMainBox() {
287 my %checked = ();
7899718f 288 my %selected = ();
01dbccb1
SS
289
290 $checked{'GUARDIAN_ENABLED'}{'on'} = '';
291 $checked{'GUARDIAN_ENABLED'}{'off'} = '';
292 $checked{'GUARDIAN_ENABLED'}{$settings{'GUARDIAN_ENABLED'}} = 'checked';
723648ac
SS
293 $checked{'GUARDIAN_MONITOR_SNORT'}{'off'} = '';
294 $checked{'GUARDIAN_MONITOR_SNORT'}{'on'} = '';
295 $checked{'GUARDIAN_MONITOR_SNORT'}{$settings{'GUARDIAN_MONITOR_SNORT'}} = "checked='checked'";
296 $checked{'GUARDIAN_MONITOR_SSH'}{'off'} = '';
297 $checked{'GUARDIAN_MONITOR_SSH'}{'on'} = '';
298 $checked{'GUARDIAN_MONITOR_SSH'}{$settings{'GUARDIAN_MONITOR_SSH'}} = "checked='checked'";
299 $checked{'GUARDIAN_MONITOR_HTTPD'}{'off'} = '';
300 $checked{'GUARDIAN_MONITOR_HTTPD'}{'on'} = '';
301 $checked{'GUARDIAN_MONITOR_HTTPD'}{$settings{'GUARDIAN_MONITOR_HTTPD'}} = "checked='checked'";
302 $checked{'GUARDIAN_MONITOR_OWNCLOUD'}{'off'} = '';
303 $checked{'GUARDIAN_MONITOR_OWNCLOUD'}{'on'} = '';
304 $checked{'GUARDIAN_MONITOR_OWNCLOUD'}{$settings{'GUARDIAN_MONITOR_OWNCLOUD'}} = "checked='checked'";
01dbccb1 305
52958991 306 $selected{'GUARDIAN_LOG_FACILITY'}{$settings{'GUARDIAN_LOG_FACILITY'}} = 'selected';
4a7fc9f6 307 $selected{'GUARDIAN_LOGLEVEL'}{$settings{'GUARDIAN_LOGLEVEL'}} = 'selected';
52958991 308 $selected{'GUARDIAN_SNORT_PRIORITY_LEVEL'}{$settings{'GUARDIAN_SNORT_PRIORITY_LEVEL'}} = 'selected';
7899718f 309
01dbccb1
SS
310 &Header::openpage($Lang::tr{'guardian configuration'}, 1, '');
311 &Header::openbigbox('100%', 'left', '', $errormessage);
312
313 # Print errormessage if there is one.
314 if ($errormessage) {
315 &Header::openbox('100%', 'left', $Lang::tr{'error messages'});
316 print "<font class='base'>$errormessage&nbsp;</font>\n";
317 &Header::closebox();
318 }
319
320
321 # Draw current guardian state.
322 &Header::openbox('100%', 'center', $Lang::tr{'guardian'});
323
f8c3bfe0 324 # Get current status of guardian.
01dbccb1 325 &daemonstats();
922ddf0e 326 $pid = $pid[0];
01dbccb1
SS
327
328 # Display some useful information related to guardian, if daemon is running.
f8c3bfe0 329 if ( ($memory != 0) && ($pid > 0) ){
01dbccb1
SS
330 print <<END;
331 <table width='95%' cellspacing='0' class='tbl'>
332 <tr>
333 <th bgcolor='$color{'color20'}' colspan='3' align='left'><strong>$Lang::tr{'guardian service'}</strong></th>
334 </tr>
335 <tr>
336 <td class='base'>$Lang::tr{'guardian daemon'}</td>
337 <td align='center' colspan='2' width='75%' bgcolor='${Header::colourgreen}'><font color='white'><strong>$Lang::tr{'running'}</strong></font></td>
338 </tr>
339 <tr>
340 <td class='base'></td>
341 <td bgcolor='$color{'color20'}' align='center'><strong>PID</strong></td>
342 <td bgcolor='$color{'color20'}' align='center'><strong>$Lang::tr{'memory'}</strong></td>
343 </tr>
344 <tr>
345 <td class='base'></td>
922ddf0e 346 <td bgcolor='$color{'color22'}' align='center'>$pid</td>
01dbccb1
SS
347 <td bgcolor='$color{'color22'}' align='center'>$memory KB</td>
348 </tr>
349 </table>
350END
351 } else {
352 # Otherwise display a hint that the service is not launched.
353 print <<END;
354 <table width='95%' cellspacing='0' class='tbl'>
355 <tr>
356 <th bgcolor='$color{'color20'}' colspan='3' align='left'><strong>$Lang::tr{'guardian service'}</strong></th>
357 </tr>
358 <tr>
359 <td class='base'>$Lang::tr{'guardian daemon'}</td>
360 <td align='center' width='75%' bgcolor='${Header::colourred}'><font color='white'><strong>$Lang::tr{'stopped'}</strong></font></td>
361 </tr>
362 </table>
363END
364 }
365
366 &Header::closebox();
367
368 # Draw elements for guardian configuration.
369 &Header::openbox('100%', 'center', $Lang::tr{'guardian configuration'});
370
371 print <<END;
372 <form method='post' action='$ENV{'SCRIPT_NAME'}'>
373
374 <table width='95%'>
375 <tr>
d2fea55e 376 <td colspan='2' class='base' bgcolor='$color{'color20'}'><b>$Lang::tr{'guardian common settings'}</b></td>
01dbccb1
SS
377 </tr>
378 <tr>
379 <td width='20%' class='base'>$Lang::tr{'guardian enabled'}:</td>
d2fea55e 380 <td><input type='checkbox' name='GUARDIAN_ENABLED' $checked{'GUARDIAN_ENABLED'}{'on'} /></td>
01dbccb1 381 </tr>
26fcd31e
SS
382 <tr>
383 <td colspan='2'><br></td>
384 </tr>
385 <tr>
06ff7e28 386 <td width='20%' class='base'>$Lang::tr{'guardian watch snort alertfile'}</td>
723648ac
SS
387 <td align='left'>on <input type='radio' name='GUARDIAN_MONITOR_SNORT' value='on' $checked{'GUARDIAN_MONITOR_SNORT'}{'on'} /> /
388 <input type='radio' name='GUARDIAN_MONITOR_SNORT' value='off' $checked{'GUARDIAN_MONITOR_SNORT'}{'off'} /> off</td>
26fcd31e
SS
389 </tr>
390 <tr>
06ff7e28 391 <td width='20%' class='base'>$Lang::tr{'guardian block ssh brute-force'}</td>
723648ac
SS
392 <td align='left'>on <input type='radio' name='GUARDIAN_MONITOR_SSH' value='on' $checked{'GUARDIAN_MONITOR_SSH'}{'on'} /> /
393 <input type='radio' name='GUARDIAN_MONITOR_SSH' value='off' $checked{'GUARDIAN_MONITOR_SSH'}{'off'} /> off</td>
26fcd31e
SS
394 </tr>
395 <tr>
06ff7e28 396 <td width='20%' class='base'>$Lang::tr{'guardian block httpd brute-force'}</td>
723648ac
SS
397 <td align='left'>on <input type='radio' name='GUARDIAN_MONITOR_HTTPD' value='on' $checked{'GUARDIAN_MONITOR_HTTPD'}{'on'} /> /
398 <input type='radio' name='GUARDIAN_MONITOR_HTTPD' value='off' $checked{'GUARDIAN_MONITOR_HTTPD'}{'off'} /> off</td>
26fcd31e 399 </tr>
28981fac
SS
400END
401 # Display owncloud checkbox when the addon is installed.
402 if ( -e "$owncloud_meta" ) {
403 print"<tr>\n";
404 print"<td width='20%' class='base'>$Lang::tr{'guardian block owncloud brute-force'}</td>\n";
723648ac
SS
405 print"<td align='left'>on <input type='radio' name='GUARDIAN_MONITOR_OWNCLOUD' value='on' $checked{'GUARDIAN_MONITOR_OWNCLOUD'}{'on'} /> /\n";
406 print"<input type='radio' name='GUARDIAN_MONITOR_OWNCLOUD' value='off' $checked{'GUARDIAN_MONITOR_OWNCLOUD'}{'off'} /> off</td>\n";
28981fac
SS
407 print"</tr>\n";
408 }
409 print <<END;
52958991
SS
410 <tr>
411 <td colspan='2'><br></td>
412 </tr>
413 <tr>
414 <td align='left' width='20%'>$Lang::tr{'guardian logfacility'}:</td>
415 <td><select name='GUARDIAN_LOG_FACILITY'>
416 <option value='syslog' $selected{'GUARDIAN_LOG_FACILITY'}{'syslog'}>syslog</option>
417 <option value='file' $selected{'GUARDIAN_LOG_FACILITY'}{'file'}>file</option>
418 <option value='console' $selected{'GUARDIAN_LOG_FACILITY'}{'console'}>console</option>
419 </select></td>
420 </tr>
26fcd31e
SS
421 <tr>
422 <td colspan='2'><br></td>
423 </tr>
7899718f 424 <tr>
a35a0668 425 <td align='left' width='20%'>$Lang::tr{'guardian loglevel'}:</td>
7899718f
SS
426 <td><select name='GUARDIAN_LOGLEVEL'>
427 <option value='off' $selected{'GUARDIAN_LOGLEVEL'}{'off'}>off</option>
428 <option value='info' $selected{'GUARDIAN_LOGLEVEL'}{'info'}>info</option>
429 <option value='debug' $selected{'GUARDIAN_LOGLEVEL'}{'debug'}>debug</option>
430 </select></td>
431 </tr>
a35a0668
SS
432 <tr>
433 <td colspan='2'><br></td>
434 </tr>
4a7fc9f6
SS
435 <tr>
436 <td align='left' width='20%'>$Lang::tr{'guardian priority level'}:</td>
52958991
SS
437 <td><select name='GUARDIAN_SNORT_PRIORITY_LEVEL'>
438 <option value='1' $selected{'GUARDIAN_SNORT_PRIORITY_LEVEL'}{'1'}>1</option>
439 <option value='2' $selected{'GUARDIAN_SNORT_PRIORITY_LEVEL'}{'2'}>2</option>
440 <option value='3' $selected{'GUARDIAN_SNORT_PRIORITY_LEVEL'}{'3'}>3</option>
441 <option value='4' $selected{'GUARDIAN_SNORT_PRIORITY_LEVEL'}{'4'}>4</option>
4a7fc9f6
SS
442 </select></td>
443 </tr>
444 <tr>
445 <td colspan='2'><br></td>
446 </tr>
a35a0668
SS
447 <tr>
448 <td width='20%' class='base'>$Lang::tr{'guardian blockcount'}:</td>
449 <td><input type='text' name='GUARDIAN_BLOCKCOUNT' value='$settings{'GUARDIAN_BLOCKCOUNT'}' size='5' /></td>
450 </tr>
01dbccb1
SS
451 <tr>
452 <td width='20%' class='base'>$Lang::tr{'guardian blocktime'}:</td>
d2fea55e 453 <td><input type='text' name='GUARDIAN_BLOCKTIME' value='$settings{'GUARDIAN_BLOCKTIME'}' size='10' /></td>
01dbccb1
SS
454 </tr>
455 <tr>
456 <td width='20%' class='base'>$Lang::tr{'guardian logfile'}:</td>
d2fea55e 457 <td><input type='text' name='GUARDIAN_LOGFILE' value='$settings{'GUARDIAN_LOGFILE'}' size='30' /></td>
01dbccb1 458 </tr>
01dbccb1
SS
459 </table>
460END
461
462 print <<END;
463 <hr>
464
465 <table width='95%'>
466 <tr>
467 <td>&nbsp;</td>
468 <td align='center'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' /></td>
469 <td>&nbsp;</td>
470 </tr>
471 </table>
472 </form>
473END
474
475 &Header::closebox();
476}
477
478# Function to show elements of the guardian ignorefile and allow to add or remove single members of it.
479sub showIgnoreBox() {
480 &Header::openbox('100%', 'center', $Lang::tr{'guardian ignored hosts'});
481
482 print <<END;
483 <table width='60%'>
484 <tr>
485 <td colspan='2' class='base' bgcolor='$color{'color20'}'><b>$Lang::tr{'guardian ignored hosts'}</b></td>
486 </tr>
487END
488 # Check if the guardian ignore file contains any content.
489 if (-s $ignorefile) {
490
491 # Open file and print contents.
492 open FILE, $ignorefile or die "Could not open $ignorefile";
493
494 my $id = 0;
495 my $col = "";
496
497 # Read file line by line and print out the elements.
498 while( my $ignored_element = <FILE> ) {
499
500 # Increase id number for each element in the ignore file.
501 $id++;
502
503 # Check if the id number is even or not.
504 if ($id % 2) {
505 $col="bgcolor='$color{'color22'}'";
506 } else {
507 $col="bgcolor='$color{'color20'}'";
508 }
509
510 print <<END;
511 <tr>
512 <td width='80%' class='base' $col>$ignored_element</td>
513 <td width='20%' align='center' $col>
a35a0668 514 <form method='post' name='$id' action='$ENV{'SCRIPT_NAME'}'>
01dbccb1
SS
515 <input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' title='$Lang::tr{'remove'}' alt='$Lang::tr{'remove'}'>
516 <input type='hidden' name='ID' value='$id'>
517 <input type='hidden' name='ACTION' value='$Lang::tr{'remove'}'>
518 </form>
519 </td>
520 </tr>
521END
522 }
523 close (FILE);
524 } else {
525 # Print notice that currently no elements are stored in the ignore file.
526 print "<tr>\n";
527 print "<td class='base' colspan='2'>$Lang::tr{'guardian no entries'}</td>\n";
528 print "</tr>\n";
529 }
530
531 print "</table>\n";
532
01dbccb1
SS
533 # Section to add new elements to the ignore list.
534 print <<END;
1d5702a7
SS
535 <br>
536 <div align='center'>
01dbccb1
SS
537 <table width='60%'>
538 <form method='post' action='$ENV{'SCRIPT_NAME'}'>
539 <tr>
540 <td width='30%'>$Lang::tr{'dnsforward add a new entry'}: </td>
541 <td width='50%'><input type='text' name='NEW_IGNORE_ENTRY' value='' size='24' /></td>
542 <td align='center' width='20%'><input type='submit' name='ACTION' value='$Lang::tr{'add'}' /></td>
543 </tr>
544 </form>
545 </table>
546 </div>
547END
1d5702a7
SS
548
549 &Header::closebox();
01dbccb1
SS
550}
551
552# Function to list currently bocked addresses from guardian and unblock them or add custom entries to block.
553sub showBlockedBox() {
554 &Header::openbox('100%', 'center', $Lang::tr{'guardian blocked hosts'});
555
01dbccb1
SS
556 print <<END;
557 <table width='60%'>
558 <tr>
559 <td colspan='2' class='base' bgcolor='$color{'color20'}'><b>$Lang::tr{'guardian blocked hosts'}</b></td>
560 </tr>
561END
562
5f462919
SS
563 # Lauch function to get the currently blocked hosts.
564 my @blocked_hosts = &GetBlockedHosts();
565
01dbccb1 566 my $id = 0;
01dbccb1 567 my $col = "";
01dbccb1 568
5f462919
SS
569 # Loop through our blocked hosts array.
570 foreach my $blocked_host (@blocked_hosts) {
01dbccb1
SS
571
572 # Increase id number for each element in the ignore file.
573 $id++;
574
575 # Check if the id number is even or not.
576 if ($id % 2) {
577 $col="bgcolor='$color{'color22'}'";
578 } else {
579 $col="bgcolor='$color{'color20'}'";
580 }
581
582 print <<END;
583 <tr>
8b8413e5 584 <td width='80%' class='base' $col><a href='/cgi-bin/ipinfo.cgi?ip=$blocked_host'>$blocked_host</a></td>
01dbccb1
SS
585 <td width='20%' align='center' $col>
586 <form method='post' name='frmb$id' action='$ENV{'SCRIPT_NAME'}'>
587 <input type='image' name='$Lang::tr{'unblock'}' src='/images/delete.gif' title='$Lang::tr{'unblock'}' alt='$Lang::tr{'unblock'}'>
588 <input type='hidden' name='ADDRESS_UNBLOCK' value='$blocked_host'>
589 <input type='hidden' name='ACTION' value='$Lang::tr{'unblock'}'>
590 </form>
591 </td>
592 </tr>
593END
594 }
595
01dbccb1
SS
596 # If the loop only has been runs once the id still is "0", which means there are no
597 # additional entries (blocked hosts) in the iptables chain.
598 if ($id == 0) {
599
600 # Print notice that currently no hosts are blocked.
601 print "<tr>\n";
602 print "<td class='base' colspan='2'>$Lang::tr{'guardian no entries'}</td>\n";
603 print "</tr>\n";
604 }
605
606 print "</table>\n";
607
01dbccb1
SS
608 # Section for a manual block of an IP-address.
609 print <<END;
1d5702a7
SS
610 <br>
611 <div align='center'>
612 <table width='60%' border='0'>
01dbccb1
SS
613 <form method='post' action='$ENV{'SCRIPT_NAME'}'>
614 <tr>
615 <td width='30%'>$Lang::tr{'guardian block a host'}: </td>
616 <td width='40%'><input type='text' name='ADDRESS_BLOCK' value='' size='24' /></td>
617 <td align='center' width='15%'><input type='submit' name='ACTION' value='$Lang::tr{'block'}'></td>
618 <td align='center' width='15%'><input type='submit' name='ACTION' value='$Lang::tr{'unblock all'}'></td>
619 </tr>
620 </form>
621 </table>
622 </div>
623END
1d5702a7
SS
624
625 &Header::closebox();
01dbccb1
SS
626}
627
628&Header::closebigbox();
629&Header::closepage();
630
631# Function to check if guardian has been started.
632# Grab process id and consumed memory if the daemon is running.
633sub daemonstats() {
634 $memory = 0;
635 # for pid and memory
636 open(FILE, '/usr/local/bin/addonctrl guardian status | ');
637 @guardian = <FILE>;
638 close(FILE);
639 $string = join("", @guardian);
640 $string =~ s/[a-z_]//gi;
641 $string =~ s/\[[0-1]\;[0-9]+//gi;
642 $string =~ s/[\(\)\.]//gi;
643 $string =~ s/ //gi;
644 $string =~ s/\e//gi;
645 @pid = split(/\s/,$string);
646 if (open(FILE, "/proc/$pid[0]/statm")){
647 my $temp = <FILE>;
648 @memory = split(/ /,$temp);
649 close(FILE);
650 }
651 $memory+=$memory[0];
652}
653
5f462919
SS
654sub GetBlockedHosts() {
655
656 # Create new, empty array.
657 my @hosts;
658
659 # Lauch helper to get chains from iptables.
660 open(FILE, "/usr/local/bin/guardianctrl get-chain |");
661
662 # Read file line by line and print out the elements.
663 foreach my $line (<FILE>) {
664
665 # Skip descriptive lines.
666 next if ($line =~ /^Chain/);
667 next if ($line =~ /^ pkts/);
668
669 # Generate array, based on the line content (seperator is a single or multiple space's)
670 my @comps = split(/\s{1,}/, $line);
671 my ($lead, $pkts, $bytes, $target, $prot, $opt, $in, $out, $source, $destination) = @comps;
672
673 # Assign different variable names.
674 my $blocked_host = $source;
675
676 # Add host to our hosts array.
677 push(@hosts, $blocked_host);
678 }
679
680 # Convert entries, sort them, write back and store the sorted entries into new array.
681 my @sorted = map { $_->[0] }
682 sort { $a->[1] <=> $b->[1] }
683 map { [$_, int sprintf("%03.f%03.f%03.f%03.f", split(/\./, $_))] }
684 @hosts;
685
686 # Return our sorted list.
687 return @sorted
688}
689
01dbccb1
SS
690sub BuildConfiguration() {
691 my %settings = ();
692 &General::readhash("${General::swroot}/guardian/settings", \%settings);
693
694 my $configfile = "${General::swroot}/guardian/guardian.conf";
695
7f728591 696 # Open configfile for writing.
01dbccb1
SS
697 open(FILE, ">$configfile");
698
52958991
SS
699 # Config file header.
700 print FILE "# Autogenerated configuration file.\n";
701 print FILE "# All user modifications will be overwritten.\n\n";
28981fac 702
52958991
SS
703 # Settings for the logging mechanism.
704 print FILE "# Log settings.\n";
705 print FILE "LogFacility = $settings{'GUARDIAN_LOG_FACILITY'}\n";
706
707 if ($settings{'GUARDIAN_LOG_FACILITY'} eq "file") {
708 print FILE "LogFile = $settings{'GUARDIAN_LOGFILE'}\n";
28981fac
SS
709 }
710
52958991
SS
711 print FILE "LogLevel = $settings{'GUARDIAN_LOGLEVEL'}\n\n";
712
713 # IPFire related static settings.
714 print FILE "# IPFire related settings.\n";
715 print FILE "FirewallEngine = IPtables\n";
716 print FILE "SocketOwner = nobody:nobody\n";
717 print FILE "IgnoreFile = $ignorefile\n\n";
718
719 # Configured block values.
720 print FILE "# Configured block values.\n";
721 print FILE "BlockCount = $settings{'GUARDIAN_BLOCKCOUNT'}\n";
722 print FILE "BlockTime = $settings{'GUARDIAN_BLOCKTIME'}\n\n";
723
724 # Enabled modules.
725 # Loop through whole settings hash.
726 print FILE "# Enabled modules.\n";
727 foreach my $option (keys %settings) {
728 # Search for enabled modules.
729 if ($option =~ /GUARDIAN_MONITOR_(.*)/) {
730 # Skip if module is not enabled.
731 next unless($settings{$option} eq "on");
732
733 # Skip module if no file location is available.
734 next unless(exists($module_file_locations{$1}));
735
736 # Add enabled module and defined path to the config file.
737 print FILE "Monitor_$1 = $module_file_locations{$1}\n";
738 }
739 }
740
741 # Module settings.
742 print FILE "\n# Module settings.\n";
743 # Check if SNORT is enabled and add snort priority.
744 if ($settings{'GUARDIAN_MONITOR_SNORT'} eq "on") {
745 print FILE "SnortPriorityLevel = $settings{'GUARDIAN_SNORT_PRIORITY_LEVEL'}\n";
746 }
01dbccb1
SS
747
748 close(FILE);
749
f8c3bfe0
SS
750 # Check if guardian should be started or stopped.
751 if($settings{'GUARDIAN_ENABLED'} eq 'on') {
752 if($pid > 0) {
af6856af
SS
753 # Send reload command through socket connection.
754 &Guardian::Socket::Client("reload");
f8c3bfe0
SS
755 } else {
756 # Launch guardian.
af6856af 757 system("/usr/local/bin/addonctrl guardian start &>/dev/null");
f8c3bfe0 758 }
01dbccb1 759 } else {
f8c3bfe0 760 # Stop the daemon.
af6856af 761 system("/usr/local/bin/addonctrl guardian stop &>/dev/null");
01dbccb1
SS
762 }
763}