X-Git-Url: http://git.ipfire.org/?p=ipfire-2.x.git;a=blobdiff_plain;f=config%2Fcfgroot%2Fids-functions.pl;h=afccf43263d813289e663bda433675f9f2e2b03d;hp=c35bed7e5ffc92d8159d8dec0e7c512024f291a5;hb=81592314ebe93ae942f28a1bc9037185f155ccda;hpb=6994f00174d222a6e7dd9b812c5bebaad1e3fa3e diff --git a/config/cfgroot/ids-functions.pl b/config/cfgroot/ids-functions.pl index c35bed7e5f..afccf43263 100644 --- a/config/cfgroot/ids-functions.pl +++ b/config/cfgroot/ids-functions.pl @@ -130,21 +130,21 @@ sub checkdiskspace () { } # -## This function is responsible for downloading the configured snort ruleset. +## This function is responsible for downloading the configured IDS ruleset. ## -## * At first it obtains from the stored snortsettings which ruleset should be downloaded. +## * At first it obtains from the stored rules settings which ruleset should be downloaded. ## * The next step is to get the download locations for all available rulesets. ## * After that, the function will check if an upstream proxy should be used and grab the settings. ## * The last step will be to generate the final download url, by obtaining the URL for the desired ## ruleset, add the settings for the upstream proxy and final grab the rules tarball from the server. # sub downloadruleset { - # Get snort settings. - my %snortsettings=(); - &General::readhash("$settingsdir/settings", \%snortsettings); + # Get rules settings. + my %rulessettings=(); + &General::readhash("$rules_settings_file", \%rulessettings); # Check if a ruleset has been configured. - unless($snortsettings{'RULES'}) { + unless($rulessettings{'RULES'}) { # Log that no ruleset has been configured and abort. &_log_to_syslog("No ruleset source has been configured."); @@ -198,10 +198,10 @@ sub downloadruleset { } # Grab the right url based on the configured vendor. - my $url = $rulesetsources{$snortsettings{'RULES'}}; + my $url = $rulesetsources{$rulessettings{'RULES'}}; # Check if the vendor requires an oinkcode and add it if needed. - $url =~ s/\/$snortsettings{'OINKCODE'}/g; + $url =~ s/\/$rulessettings{'OINKCODE'}/g; # Abort if no url could be determined for the vendor. unless ($url) { @@ -211,7 +211,7 @@ sub downloadruleset { } # Pass the requrested url to the downloader. - my $request = HTTP::Request->new(HEAD => $url); + my $request = HTTP::Request->new(GET => $url); # Accept the html header. $request->header('Accept' => 'text/html'); @@ -222,7 +222,7 @@ sub downloadruleset { # Check if there was any error. unless ($response->is_success) { # Obtain error. - my $error = $response->content; + my $error = $response->status_line(); # Log error message. &_log_to_syslog("Unable to download the ruleset. \($error\)"); @@ -232,7 +232,7 @@ sub downloadruleset { } # Assign the fetched header object. - my $header = $response->headers; + my $header = $response->headers(); # Grab the remote file size from the object and store it in the # variable. @@ -387,6 +387,9 @@ sub _store_error_message ($) { # Close file. close (ERRORFILE); + + # Set correct ownership for the file. + &set_ownership("$storederrorfile"); } # @@ -594,30 +597,58 @@ sub generate_home_net_file() { # Loop through the array of available network zones. foreach my $zone (@network_zones) { - # Skip the red network - It never can be part to the home_net! - next if($zone eq "red"); + # Check if the current processed zone is red. + if($zone eq "red") { + # Grab the IP-address of the red interface. + my $red_address = &get_red_address(); + + # Check if an address has been obtained. + if ($red_address) { + # Generate full network string. + my $red_network = join("/", $red_address, "32"); + + # Add the red network to the array of networks. + push(@networks, $red_network); + } + + # Check if the configured RED_TYPE is static. + if ($netsettings{'RED_TYPE'} eq "STATIC") { + # Get configured and enabled aliases. + my @aliases = &get_aliases(); - # Convert current zone name into upper case. - $zone = uc($zone); + # Loop through the array. + foreach my $alias (@aliases) { + # Add "/32" prefix. + my $network = join("/", $alias, "32"); + + # Add the generated network to the array of networks. + push(@networks, $network); + } + } + # Process remaining network zones. + } else { + # Convert current zone name into upper case. + $zone = uc($zone); - # Generate key to access the required data from the netsettings hash. - my $zone_netaddress = $zone . "_NETADDRESS"; - my $zone_netmask = $zone . "_NETMASK"; + # Generate key to access the required data from the netsettings hash. + my $zone_netaddress = $zone . "_NETADDRESS"; + my $zone_netmask = $zone . "_NETMASK"; - # Obtain the settings from the netsettings hash. - my $netaddress = $netsettings{$zone_netaddress}; - my $netmask = $netsettings{$zone_netmask}; + # Obtain the settings from the netsettings hash. + my $netaddress = $netsettings{$zone_netaddress}; + my $netmask = $netsettings{$zone_netmask}; - # Convert the subnetmask into prefix notation. - my $prefix = &Network::convert_netmask2prefix($netmask); + # Convert the subnetmask into prefix notation. + my $prefix = &Network::convert_netmask2prefix($netmask); - # Generate full network string. - my $network = join("/", $netaddress,$prefix); + # Generate full network string. + my $network = join("/", $netaddress,$prefix); - # Check if the network is valid. - if(&Network::check_subnet($network)) { - # Add the generated network to the array of networks. - push(@networks, $network); + # Check if the network is valid. + if(&Network::check_subnet($network)) { + # Add the generated network to the array of networks. + push(@networks, $network); + } } } @@ -746,4 +777,173 @@ sub get_suricata_version($) { } } +# +## Function to generate the rules file with whitelisted addresses. +# +sub generate_ignore_file() { + my %ignored = (); + + # SID range 1000000-1999999 Reserved for Local Use + # Put your custom rules in this range to avoid conflicts + my $sid = 1500000; + + # Read-in ignoredfile. + &General::readhasharray($IDS::ignored_file, \%ignored); + + # Open ignorefile for writing. + open(FILE, ">$IDS::whitelist_file") or die "Could not write to $IDS::whitelist_file. $!\n"; + + # Config file header. + print FILE "# Autogenerated file.\n"; + print FILE "# All user modifications will be overwritten.\n\n"; + + # Add all user defined addresses to the whitelist. + # + # Check if the hash contains any elements. + if (keys (%ignored)) { + # 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 rule line to the file to pass any traffic from this IP + print FILE "pass ip $address any -> any any (msg:\"pass all traffic from/to $address\"\; sid:$sid\;)\n"; + + # Increment sid. + $sid++; + } + } + } + } + + close(FILE); +} + +# +## Function to set correct ownership for single files and directories. +# + +sub set_ownership($) { + my ($target) = @_; + + # User and group of the WUI. + my $uname = "nobody"; + my $grname = "nobody"; + + # The chown function implemented in perl requies the user and group as nummeric id's. + my $uid = getpwnam($uname); + my $gid = getgrnam($grname); + + # Check if the given target exists. + unless ($target) { + # Stop the script and print error message. + die "The $target does not exist. Cannot change the ownership!\n"; + } + + # Check weather the target is a file or directory. + if (-f $target) { + # Change ownership ot the single file. + chown($uid, $gid, "$target"); + } elsif (-d $target) { + # Do a directory listing. + opendir(DIR, $target) or die $!; + # Loop through the direcory. + while (my $file = readdir(DIR)) { + + # We only want files. + next unless (-f "$target/$file"); + + # Set correct ownership for the files. + chown($uid, $gid, "$target/$file"); + } + + closedir(DIR); + + # Change ownership of the directory. + chown($uid, $gid, "$target"); + } +} + +# +## Function to read-in the aliases file and returns all configured and enabled aliases. +# +sub get_aliases() { + # Location of the aliases file. + my $aliases_file = "${General::swroot}/ethernet/aliases"; + + # Array to store the aliases. + my @aliases; + + # Check if the file is empty. + if (-z $aliases_file) { + # Abort nothing to do. + return; + } + + # Open the aliases file. + open(ALIASES, $aliases_file) or die "Could not open $aliases_file. $!\n"; + + # Loop through the file content. + while (my $line = ) { + # Remove newlines. + chomp($line); + + # Splitt line content into single chunks. + my ($address, $state, $remark) = split(/\,/, $line); + + # Check if the state of the current processed alias is "on". + if ($state eq "on") { + # Check if the address is valid. + if(&Network::check_ip_address($address)) { + # Add the alias to the array of aliases. + push(@aliases, $address); + } + } + } + + # Close file handle. + close(ALIASES); + + # Return the array. + return @aliases; +} + +# +## Function to grab the current assigned IP-address on red. +# +sub get_red_address() { + # File, which contains the current IP-address of the red interface. + my $file = "${General::swroot}/red/local-ipaddress"; + + # 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; +} + 1;