#!/usr/bin/perl ############################################################################### # # # IPFire.org - A linux based firewall # # Copyright (C) 2016 IPFire Team # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation, either version 3 of the License, or # # (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program. If not, see . # # # ############################################################################### use strict; use Locale::Codes::Country; use Guardian::Socket; # enable only the following on debugging purpose #use warnings; #use CGI::Carp 'fatalsToBrowser'; require '/var/ipfire/general-functions.pl'; require "${General::swroot}/lang.pl"; require "${General::swroot}/header.pl"; #workaround to suppress a warning when a variable is used only once my @dummy = ( ${Header::colourred}, ${Header::colourgreen} ); undef (@dummy); my $string=(); my $memory=(); my @memory=(); my @pid=(); my @guardian=(); # Path to the guardian.ignore file. my $ignorefile ='/var/ipfire/guardian/guardian.ignore'; # Hash which contains the supported modules and the # file locations on IPFire systems. my %module_file_locations = ( "HTTPD" => "/var/log/httpd/error_log", "SNORT" => "/var/log/snort/alert", "SSH" => "/var/log/messages", ); our %netsettings = (); &General::readhash("${General::swroot}/ethernet/settings", \%netsettings); our %color = (); our %mainsettings = (); &General::readhash("${General::swroot}/main/settings", \%mainsettings); &General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color); # File declarations. my $settingsfile = "${General::swroot}/guardian/settings"; my $ignoredfile = "${General::swroot}/guardian/ignored"; # Create empty settings and ignoredfile if they do not exist yet. unless (-e "$settingsfile") { system("touch $settingsfile"); } unless (-e "$ignoredfile") { system("touch $ignoredfile"); } our %settings = (); our %ignored = (); $settings{'ACTION'} = ''; $settings{'GUARDIAN_ENABLED'} = 'off'; $settings{'GUARDIAN_MONITOR_SNORT'} = 'on'; $settings{'GUARDIAN_MONITOR_SSH'} = 'on'; $settings{'GUARDIAN_MONITOR_HTTPD'} = 'on'; $settings{'GUARDIAN_MONITOR_OWNCLOUD'} = ''; $settings{'GUARDIAN_LOG_FACILITY'} = 'syslog'; $settings{'GUARDIAN_LOGLEVEL'} = 'info'; $settings{'GUARDIAN_BLOCKCOUNT'} = '3'; $settings{'GUARDIAN_BLOCKTIME'} = '86400'; $settings{'GUARDIAN_FIREWALL_ACTION'} = 'DROP'; $settings{'GUARDIAN_LOGFILE'} = '/var/log/guardian/guardian.log'; $settings{'GUARDIAN_SNORT_PRIORITY_LEVEL'} = '3'; my $errormessage = ''; &Header::showhttpheaders(); # Get GUI values. &Header::getcgihash(\%settings); # Check if guardian is running and grab some stats. &daemonstats(); my $pid = $pid[0]; ## Perform input checks and save settings. # if ($settings{'ACTION'} eq $Lang::tr{'save'}) { # Check for valid blocktime. unless(($settings{'GUARDIAN_BLOCKTIME'} =~ /^\d+$/) && ($settings{'GUARDIAN_BLOCKTIME'} ne "0")) { $errormessage = "$Lang::tr{'guardian invalid blocktime'}"; } # Check if the blockcount is valid. unless(($settings{'GUARDIAN_BLOCKCOUNT'} =~ /^\d+$/) && ($settings{'GUARDIAN_BLOCKCOUNT'} ne "0")) { $errormessage = "$Lang::tr{'guardian invalid blockcount'}"; } # Check Logfile. unless($settings{'GUARDIAN_LOGFILE'} =~ /^[a-zA-Z0-9\.\/]+$/) { $errormessage = "$Lang::tr{'guardian invalid logfile'}"; } # Only continue if no error message has been set. if($errormessage eq '') { # Write configuration settings to file. &General::writehash("${General::swroot}/guardian/settings", \%settings); # Update configuration files. &BuildConfiguration(); } ## Add/edit an entry to the ignore file. # } elsif (($settings{'ACTION'} eq $Lang::tr{'add'}) || ($settings{'ACTION'} eq $Lang::tr{'update'})) { # Check if any input has been performed. if ($settings{'IGNORE_ENTRY_ADDRESS'} ne '') { # Check if the given input is no valid IP-address or IP-address with subnet, display an error message. if ((!&General::validip($settings{'IGNORE_ENTRY_ADDRESS'})) && (!&General::validipandmask($settings{'IGNORE_ENTRY_ADDRESS'}))) { $errormessage = "$Lang::tr{'guardian invalid address or subnet'}"; } } else { $errormessage = "$Lang::tr{'guardian empty input'}"; } # Go further if there was no error. if ($errormessage eq '') { my %ignored = (); my $id; my $status; # Assign hash values. my $new_entry_address = $settings{'IGNORE_ENTRY_ADDRESS'}; my $new_entry_remark = $settings{'IGNORE_ENTRY_REMARK'}; # Read-in ignoredfile. &General::readhasharray($ignoredfile, \%ignored); # Check if we should edit an existing entry and got an ID. if (($settings{'ACTION'} eq $Lang::tr{'update'}) && ($settings{'ID'})) { # Assin the provided id. $id = $settings{'ID'}; # Undef the given ID. undef($settings{'ID'}); # Grab the configured status of the corresponding entry. $status = $ignored{$id}[2]; } else { # Each newly added entry automatically should be enabled. $status = "enabled"; # Generate the ID for the new entry. # # Sort the keys by their ID and store them in an array. my @keys = sort { $a <=> $b } keys %ignored; # Reverse the key array. my @reversed = reverse(@keys); # Obtain the last used id. my $last_id = @reversed[0]; # Increase the last id by one and use it as id for the new entry. $id = ++$last_id; } # Add/Modify the entry to/in the ignored hash. $ignored{$id} = ["$new_entry_address", "$new_entry_remark", "$status"]; # Write the changed ignored hash to the ignored file. &General::writehasharray($ignoredfile, \%ignored); # Regenerate the ignore file. &GenerateIgnoreFile(); } # Check if guardian is running. if ($pid > 0) { # Send reload command through socket connection. &Guardian::Socket::Client("reload-ignore-list"); } ## Toggle Enabled/Disabled for an existing entry on the ignore list. # } elsif ($settings{'ACTION'} eq $Lang::tr{'toggle enable disable'}) { my %ignored = (); # Only go further, if an ID has been passed. if ($settings{'ID'}) { # Assign the given ID. my $id = $settings{'ID'}; # Undef the given ID. undef($settings{'ID'}); # Read-in ignoredfile. &General::readhasharray($ignoredfile, \%ignored); # Grab the configured status of the corresponding entry. my $status = $ignored{$id}[2]; # Switch the status. if ($status eq "disabled") { $status = "enabled"; } else { $status = "disabled"; } # Modify the status of the existing entry. $ignored{$id} = ["$ignored{$id}[0]", "$ignored{$id}[1]", "$status"]; # Write the changed ignored hash to the ignored file. &General::writehasharray($ignoredfile, \%ignored); # Regenerate the ignore file. &GenerateIgnoreFile(); # Check if guardian is running. if ($pid > 0) { # Send reload command through socket connection. &Guardian::Socket::Client("reload-ignore-list"); } } ## Remove entry from ignore list. # } elsif ($settings{'ACTION'} eq $Lang::tr{'remove'}) { my %ignored = (); # Read-in ignoredfile. &General::readhasharray($ignoredfile, \%ignored); # Drop entry from the hash. delete($ignored{$settings{'ID'}}); # Undef the given ID. undef($settings{'ID'}); # Write the changed ignored hash to the ignored file. &General::writehasharray($ignoredfile, \%ignored); # Regenerate the ignore file. &GenerateIgnoreFile(); # Check if guardian is running. if ($pid > 0) { # Send reload command through socket connection. &Guardian::Socket::Client("reload-ignore-list"); } ## Block a user given address or subnet. # } elsif ($settings{'ACTION'} eq $Lang::tr{'block'}) { # Assign some temporary variables used for input validation. my $input = $settings{'ADDRESS_BLOCK'}; my $green = $netsettings{'GREEN_ADDRESS'}; my $blue = $netsettings{'BLUE_ADDRESS'}; my $orange = $netsettings{'ORANGE_ADDRESS'}; my $red = $netsettings{'RED_ADDRESS'}; # File declarations. my $gatewayfile = "${General::swroot}/red/remote-ipaddress"; my $dns1file = "${General::swroot}/red/dns1"; my $dns2file = "${General::swroot}/red/dns2"; # Get gateway address. my $gateway = &_get_address_from_file($gatewayfile); # Get addresses from the used dns servers. my $dns1 = &_get_address_from_file($dns1file); my $dns2 = &_get_address_from_file($dns2file); # Check if any input has been performed. if ($input eq '') { $errormessage = "$Lang::tr{'guardian empty input'}"; } # Check if the given input is localhost (127.0.0.1). elsif ($input eq "127.0.0.1") { $errormessage = "$Lang::tr{'guardian blocking of this address is not allowed'}"; } # Check if the given input is anywhere (0.0.0.0). elsif ($input eq "0.0.0.0") { $errormessage = "$Lang::tr{'guardian blocking of this address is not allowed'}"; } # Check if the given input is one of the interface addresses or our gateway. elsif ($input eq "$green" || $input eq "$blue" || $input eq "$orange" || $input eq "$red" || $input eq "$gateway" || $input eq "$dns1" || $input eq "$dns2") { $errormessage = "$Lang::tr{'guardian blocking of this address is not allowed'}"; } # Check if the given input is a valid IP address. elsif (!&General::validip($input)) { $errormessage = "$Lang::tr{'guardian invalid address or subnet'}"; } # Go further if there was no error. if ($errormessage eq '') { my $block = $settings{'ADDRESS_BLOCK'}; # Send command to block the specified address through socket connection. &Guardian::Socket::Client("block $block"); } ## Unblock address or subnet. # } elsif ($settings{'ACTION'} eq $Lang::tr{'unblock'}) { # Check if no empty input has been performed. if ($settings{'ADDRESS_UNBLOCK'} ne '') { # Check if the given input is no valid IP-address or IP-address with subnet, display an error message. if ((!&General::validip($settings{'ADDRESS_UNBLOCK'})) && (!&General::validipandmask($settings{'ADDRESS_UNBLOCK'}))) { $errormessage = "$Lang::tr{'guardian invalid address or subnet'}"; } } else { $errormessage = "$Lang::tr{'guardian empty input'}"; } # Go further if there was no error. if ($errormessage eq '') { my $unblock = $settings{'ADDRESS_UNBLOCK'}; # Send command to unblock the given address through socket connection. &Guardian::Socket::Client("unblock $unblock"); } ## Unblock all. # } elsif ($settings{'ACTION'} eq $Lang::tr{'unblock all'}) { # Send flush command through socket connection. &Guardian::Socket::Client("flush"); } # Load settings from files. &General::readhash("${General::swroot}/guardian/settings", \%settings); &General::readhasharray("${General::swroot}/guardian/ignored", \%ignored); # Call functions to generate whole page. &showMainBox(); &showIgnoreBox(); # Display area only if guardian is running. if ( ($memory != 0) && ($pid > 0) ) { &showBlockedBox(); } # Function to display the status of guardian and allow base configuration. sub showMainBox() { my %checked = (); my %selected = (); $checked{'GUARDIAN_ENABLED'}{'on'} = ''; $checked{'GUARDIAN_ENABLED'}{'off'} = ''; $checked{'GUARDIAN_ENABLED'}{$settings{'GUARDIAN_ENABLED'}} = 'checked'; $checked{'GUARDIAN_MONITOR_SNORT'}{'off'} = ''; $checked{'GUARDIAN_MONITOR_SNORT'}{'on'} = ''; $checked{'GUARDIAN_MONITOR_SNORT'}{$settings{'GUARDIAN_MONITOR_SNORT'}} = "checked='checked'"; $checked{'GUARDIAN_MONITOR_SSH'}{'off'} = ''; $checked{'GUARDIAN_MONITOR_SSH'}{'on'} = ''; $checked{'GUARDIAN_MONITOR_SSH'}{$settings{'GUARDIAN_MONITOR_SSH'}} = "checked='checked'"; $checked{'GUARDIAN_MONITOR_HTTPD'}{'off'} = ''; $checked{'GUARDIAN_MONITOR_HTTPD'}{'on'} = ''; $checked{'GUARDIAN_MONITOR_HTTPD'}{$settings{'GUARDIAN_MONITOR_HTTPD'}} = "checked='checked'"; $checked{'GUARDIAN_MONITOR_OWNCLOUD'}{'off'} = ''; $checked{'GUARDIAN_MONITOR_OWNCLOUD'}{'on'} = ''; $checked{'GUARDIAN_MONITOR_OWNCLOUD'}{$settings{'GUARDIAN_MONITOR_OWNCLOUD'}} = "checked='checked'"; $selected{'GUARDIAN_LOG_FACILITY'}{$settings{'GUARDIAN_LOG_FACILITY'}} = 'selected'; $selected{'GUARDIAN_LOGLEVEL'}{$settings{'GUARDIAN_LOGLEVEL'}} = 'selected'; $selected{'GUARDIAN_SNORT_PRIORITY_LEVEL'}{$settings{'GUARDIAN_SNORT_PRIORITY_LEVEL'}} = 'selected'; $selected{'GUARDIAN_FIREWALL_ACTION'}{$settings{'GUARDIAN_FIREWALL_ACTION'}} = 'selected'; &Header::openpage($Lang::tr{'guardian configuration'}, 1, ''); &Header::openbigbox('100%', 'left', '', $errormessage); # Print errormessage if there is one. if ($errormessage) { &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); print "$errormessage \n"; &Header::closebox(); } ### Java Script ### print< var update_options = function() { var logfacility = \$("#GUARDIAN_LOG_FACILITY").val(); var loglevel = \$("#GUARDIAN_LOGLEVEL").val(); if (logfacility === undefined) return; if (loglevel === undefined) return; // Show / Hide input for specifying the path to the logfile. if (logfacility === "file") { \$(".GUARDIAN_LOGFILE").show(); } else { \$(".GUARDIAN_LOGFILE").hide(); } // Show / Hide loglevel debug if the facility is set to syslog. if (logfacility === "syslog") { \$("#loglevel_debug").hide(); } else { \$("#loglevel_debug").show(); } // Show / Hide logfacility syslog if the loglevel is set to debug. if (loglevel === "debug") { \$("#logfacility_syslog").hide(); } else { \$("#logfacility_syslog").show(); } }; \$(document).ready(function() { \$("#GUARDIAN_LOG_FACILITY").change(update_options); \$("#GUARDIAN_LOGLEVEL").change(update_options); update_options(); // Show / Hide snort priority level option, based if // snort is enabled / disabled. if (\$('input[name=GUARDIAN_MONITOR_SNORT]:checked').val() == 'on') { \$('.GUARDIAN_SNORT_PRIORITY_LEVEL').show(); } else { \$('.GUARDIAN_SNORT_PRIORITY_LEVEL').hide(); } // Show/Hide snort priority level when GUARDIAN_MONITOR_SNORT get changed. \$('input[name=GUARDIAN_MONITOR_SNORT]').change(function() { \$('.GUARDIAN_SNORT_PRIORITY_LEVEL').toggle(); }); }); END # Draw current guardian state. &Header::openbox('100%', 'center', $Lang::tr{'guardian'}); # Get current status of guardian. &daemonstats(); $pid = $pid[0]; # Display some useful information related to guardian, if daemon is running. if ( ($memory != 0) && ($pid > 0) ){ print < $Lang::tr{'guardian service'} $Lang::tr{'guardian daemon'} $Lang::tr{'running'} PID $Lang::tr{'memory'} $pid $memory KB END } else { # Otherwise display a hint that the service is not launched. print < $Lang::tr{'guardian service'} $Lang::tr{'guardian daemon'} $Lang::tr{'stopped'} END } &Header::closebox(); # Draw elements for guardian configuration. &Header::openbox('100%', 'center', $Lang::tr{'guardian configuration'}); print <
$Lang::tr{'guardian common settings'}
$Lang::tr{'guardian enabled'}:

$Lang::tr{'guardian watch snort alertfile'} on / off
$Lang::tr{'guardian block ssh brute-force'} on / off
$Lang::tr{'guardian block httpd brute-force'} on / off

$Lang::tr{'guardian logfacility'}: $Lang::tr{'guardian loglevel'}:

$Lang::tr{'guardian logfile'}:

$Lang::tr{'guardian priority level'}: $Lang::tr{'guardian blockcount'}:

$Lang::tr{'guardian firewallaction'}: $Lang::tr{'guardian blocktime'}:
END print <
   
END &Header::closebox(); } # Function to show elements of the guardian ignorefile and allow to add or remove single members of it. sub showIgnoreBox() { &Header::openbox('100%', 'center', $Lang::tr{'guardian ignored hosts'}); print < $Lang::tr{'ip address'} $Lang::tr{'remark'} END # Check if some hosts have been added to be ignored. if (keys (%ignored)) { my $col = ""; # Loop through all entries of the hash. while( (my $key) = each %ignored) { # Assign data array positions to some nice variable names. my $address = $ignored{$key}[0]; my $remark = $ignored{$key}[1]; my $status = $ignored{$key}[2]; # Check if the key (id) number is even or not. if ($settings{'ID'} eq $key) { $col="bgcolor='${Header::colouryellow}'"; } elsif ($key % 2) { $col="bgcolor='$color{'color22'}'"; } else { $col="bgcolor='$color{'color20'}'"; } # Choose icon for the checkbox. my $gif; my $gdesc; # Check if the status is enabled and select the correct image and description. if ($status eq 'enabled' ) { $gif = 'on.gif'; $gdesc = $Lang::tr{'click to disable'}; } else { $gif = 'off.gif'; $gdesc = $Lang::tr{'click to enable'}; } print < $address $remark
END } } else { # Print notice that currently no hosts are ignored. print "\n"; print "$Lang::tr{'guardian no entries'}\n"; print "\n"; } print "\n"; # Section to add new elements or edit existing ones. print <

END # Assign correct headline and button text. my $buttontext; my $entry_address; my $entry_remark; # Check if an ID (key) has been given, in this case an existing entry should be edited. if ($settings{'ID'} ne '') { $buttontext = $Lang::tr{'update'}; print "\n"; # Grab address and remark for the given key. $entry_address = $ignored{$settings{'ID'}}[0]; $entry_remark = $ignored{$settings{'ID'}}[1]; } else { $buttontext = $Lang::tr{'add'}; print "\n"; } print <
$Lang::tr{'update'}
$Lang::tr{'dnsforward add a new entry'}
$Lang::tr{'ip address'}: $Lang::tr{'remark'}:
END &Header::closebox(); } # Function to list currently blocked addresses from guardian and unblock them or add custom entries to block. sub showBlockedBox() { &Header::openbox('100%', 'center', $Lang::tr{'guardian blocked hosts'}); print < $Lang::tr{'guardian blocked hosts'} END # Launch function to get the currently blocked hosts. my @blocked_hosts = &GetBlockedHosts(); my $id = 0; my $col = ""; # Loop through our blocked hosts array. foreach my $blocked_host (@blocked_hosts) { # Increase id number for each element in the ignore file. $id++; # Check if the id number is even or not. if ($id % 2) { $col="bgcolor='$color{'color22'}'"; } else { $col="bgcolor='$color{'color20'}'"; } print < $blocked_host
END } # If the loop only has been run once the id still is "0", which means there are no # additional entries (blocked hosts) in the iptables chain. if ($id == 0) { # Print notice that currently no hosts are blocked. print "\n"; print "$Lang::tr{'guardian no entries'}\n"; print "\n"; } print "\n"; # Section for a manual block of an IP-address. print <
$Lang::tr{'guardian block a host'}:
END &Header::closebox(); } &Header::closebigbox(); &Header::closepage(); # Function to check if guardian has been started. # Grab process id and consumed memory if the daemon is running. sub daemonstats() { $memory = 0; # for pid and memory open(FILE, '/usr/local/bin/addonctrl guardian status | '); @guardian = ; close(FILE); $string = join("", @guardian); $string =~ s/[a-z_]//gi; $string =~ s/\[[0-1]\;[0-9]+//gi; $string =~ s/[\(\)\.]//gi; $string =~ s/ //gi; $string =~ s/\e//gi; @pid = split(/\s/,$string); if (open(FILE, "/proc/$pid[0]/statm")){ my $temp = ; @memory = split(/ /,$temp); close(FILE); } $memory+=$memory[0]; } sub GetBlockedHosts() { # Create new, empty array. my @hosts; # Launch helper to get chains from iptables. system('/usr/local/bin/getipstat'); # Open temporary file which contains the chains and rules. open (FILE, '/var/tmp/iptables.txt'); # Loop through the entire file. while () { my $line = $_; # Search for the guardian chain and extract # the lines between it and the next empty line # which is placed before the next firewall # chain starts. if ($line =~ /^Chain GUARDIAN/ .. /^\s*$/) { # Skip descriptive lines. next if ($line =~ /^Chain/); next if ($line =~ /^ pkts/); # Generate array, based on the line content (separator is a single or multiple space) my @comps = split(/\s{1,}/, $line); my ($lead, $pkts, $bytes, $target, $prot, $opt, $in, $out, $source, $destination) = @comps; # Assign different variable names. my $blocked_host = $source; # Add host to our hosts array. if ($blocked_host) { push(@hosts, $blocked_host); } } } # Close filehandle. close(FILE); # Remove recently created temporary files of the "getipstat" binary. system("rm -f /var/tmp/iptables.txt"); system("rm -f /var/tmp/iptablesmangle.txt"); system("rm -f /var/tmp/iptablesnat.txt"); # Convert entries, sort them, write back and store the sorted entries into new array. my @sorted = map { $_->[0] } sort { $a->[1] <=> $b->[1] } map { [$_, int sprintf("%03.f%03.f%03.f%03.f", split(/\./, $_))] } @hosts; # Return our sorted list. return @sorted } sub BuildConfiguration() { my %settings = (); &General::readhash("${General::swroot}/guardian/settings", \%settings); my $configfile = "${General::swroot}/guardian/guardian.conf"; # Create the configfile if none exists yet. unless (-e "$configfile") { system("touch $configfile"); } # Open configfile for writing. open(FILE, ">$configfile"); # Config file header. print FILE "# Autogenerated configuration file.\n"; print FILE "# All user modifications will be overwritten.\n\n"; # Settings for the logging mechanism. print FILE "# Log settings.\n"; print FILE "LogFacility = $settings{'GUARDIAN_LOG_FACILITY'}\n"; if ($settings{'GUARDIAN_LOG_FACILITY'} eq "file") { print FILE "LogFile = $settings{'GUARDIAN_LOGFILE'}\n"; } print FILE "LogLevel = $settings{'GUARDIAN_LOGLEVEL'}\n\n"; # IPFire related static settings. print FILE "# IPFire related settings.\n"; print FILE "FirewallEngine = IPtables\n"; print FILE "SocketOwner = nobody:nobody\n"; print FILE "IgnoreFile = $ignorefile\n\n"; # Configured block values. print FILE "# Configured block settings.\n"; print FILE "BlockCount = $settings{'GUARDIAN_BLOCKCOUNT'}\n"; print FILE "BlockTime = $settings{'GUARDIAN_BLOCKTIME'}\n"; print FILE "FirewallAction = $settings{'GUARDIAN_FIREWALL_ACTION'}\n\n"; # Enabled modules. # Loop through whole settings hash. print FILE "# Enabled modules.\n"; foreach my $option (keys %settings) { # Search for enabled modules. if ($option =~ /GUARDIAN_MONITOR_(.*)/) { # Skip if module is not enabled. next unless($settings{$option} eq "on"); # Skip module if no file location is available. next unless(exists($module_file_locations{$1})); # Add enabled module and defined path to the config file. print FILE "Monitor_$1 = $module_file_locations{$1}\n"; } } # Module settings. print FILE "\n# Module settings.\n"; # Check if SNORT is enabled and add snort priority. if ($settings{'GUARDIAN_MONITOR_SNORT'} eq "on") { print FILE "SnortPriorityLevel = $settings{'GUARDIAN_SNORT_PRIORITY_LEVEL'}\n"; } close(FILE); # Generate ignore file. &GenerateIgnoreFile(); # Check if guardian should be started or stopped. if($settings{'GUARDIAN_ENABLED'} eq 'on') { if($pid > 0) { # Send reload command through socket connection. &Guardian::Socket::Client("reload"); } else { # Launch guardian. system("/usr/local/bin/addonctrl guardian start &>/dev/null"); } } else { # Stop the daemon. system("/usr/local/bin/addonctrl guardian stop &>/dev/null"); } } sub GenerateIgnoreFile() { my %ignored = (); # Read-in ignoredfile. &General::readhasharray($ignoredfile, \%ignored); # Create the guardian.ignore file if not exist yet. unless (-e "$ignorefile") { system("touch $ignorefile"); } # Open ignorefile for writing. open(FILE, ">$ignorefile"); # Config file header. print FILE "# Autogenerated configuration file.\n"; print FILE "# All user modifications will be overwritten.\n\n"; # Add IFPire interfaces and gateway to the ignore file. # # Assign some temporary variables for the IPFire interfaces. my $green = $netsettings{'GREEN_ADDRESS'}; my $blue = $netsettings{'BLUE_ADDRESS'}; my $orange = $netsettings{'ORANGE_ADDRESS'}; # File declarations. my $public_address_file = "${General::swroot}/red/local-ipaddress"; my $gatewayfile = "${General::swroot}/red/remote-ipaddress"; my $dns1file = "${General::swroot}/red/dns1"; my $dns2file = "${General::swroot}/red/dns2"; # Write the obtained addresses to the ignore file. print FILE "# IPFire local interfaces.\n"; print FILE "$green\n"; # Check if a blue interface exists. if ($blue) { # Add blue address. print FILE "$blue\n"; } # Check if an orange interface exists. if ($orange) { # Add orange address. print FILE "$orange\n"; } print FILE "\n# IPFire red interface, gateway and used DNS-servers.\n"; print FILE "# Include the corresponding files to obtain the addresses.\n"; print FILE "Include_File = $public_address_file\n"; print FILE "Include_File = $gatewayfile\n"; print FILE "Include_File = $dns1file\n"; print FILE "Include_File = $dns2file\n"; # Add all user defined hosts and networks to the ignore file. # # Check if the hash contains any elements. if (keys (%ignored)) { # Write headline. print FILE "\n# User defined hosts/networks.\n"; # Loop through the entire hash and write the host/network # and remark to the ignore file. while ( (my $key) = each %ignored) { my $address = $ignored{$key}[0]; my $remark = $ignored{$key}[1]; my $status = $ignored{$key}[2]; # Check if the status of the entry is "enabled". if ($status eq "enabled") { # Check if the address/network is valid. if ((&General::validip($address)) || (&General::validipandmask($address))) { # Write the remark to the file. print FILE "# $remark\n"; # Write the address/network to the ignore file. print FILE "$address\n\n"; } } } } close(FILE); } # Private subfunction to obtain IP-addresses from given file names. # sub _get_address_from_file ($) { my $file = shift; # Check if the file exists. if (-e $file) { # Open the given file. open(FILE, "$file") or die "Could not open $file."; # Obtain the address from the first line of the file. my $address = ; # Close filehandle close(FILE); # Remove newlines. chomp $address; # Check if the grabbed address is valid. if (&General::validip($address)) { # Return the address. return $address; } } # Return nothing. return; }