@@ -21,6 +21,11 @@
'title' => "$Lang::tr{'intrusion detection system'}",
'enabled' => 1,
};
+ $subfirewall->{'45.ipblacklist'} = {'caption' => $Lang::tr{'ipblacklist'},
+ 'uri' => '/cgi-bin/ipblacklist.cgi',
+ 'title' => "$Lang::tr{'ipblacklist'}",
+ 'enabled' => 1,
+ };
$subfirewall->{'50.p2p'} = {
'caption' => $Lang::tr{'p2p block'},
'uri' => '/cgi-bin/p2p-block.cgi',
new file mode 100644
@@ -0,0 +1,725 @@
+#!/usr/bin/perl
+
+###############################################################################
+# #
+# IPFire.org - A linux based firewall #
+# #
+# 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 <http://www.gnu.org/licenses/>. #
+# #
+# Copyright (C) 2018 - 2019 The IPFire Team #
+# #
+###############################################################################
+
+use strict;
+use CGI qw/:standard/;
+#enable only the following on debugging purpose
+#use warnings;
+#use CGI::Carp 'fatalsToBrowser';
+use Sort::Naturally;
+use Socket;
+
+require '/var/ipfire/general-functions.pl';
+require "${General::swroot}/lang.pl";
+require "${General::swroot}/header.pl";
+
+###############################################################################
+# Initialize variables and hashes
+###############################################################################
+
+my $settings = "${General::swroot}/ipblacklist/settings";
+my $modified = "${General::swroot}/ipblacklist/modified";
+my $sources = "${General::swroot}/ipblacklist/sources";
+my $getipstat = '/usr/local/bin/getipstat';
+my $getipsetstat = '/usr/local/bin/getipsetstat';
+my $control = '/usr/local/bin/ipblacklistctrl';
+my $lockfile = '/var/run/ipblacklist.pid';
+my $autoblacklist = 'AUTOBLACKLIST';
+my %cgiparams = ('ACTION' => '', 'AUTOACTION' => '');
+my $errormessage = '';
+my $updating = 0;
+my %mainsettings;
+my %color;
+my %modified;
+my %sources;
+my %stats;
+my %autoblock_addresses;
+
+my %settings = ( 'DEBUG' => 0,
+ 'LOGGING' => 'on',
+ 'RATE' => 24,
+ 'ENABLE' => 'off',
+ 'BLOCK_THRESHOLD' => 10,
+ 'BLOCK_PERIOD' => 3600,
+ $autoblacklist => 'off' );
+
+# Read all parameters for site
+Header::getcgihash( \%cgiparams);
+General::readhash( "${General::swroot}/main/settings", \%mainsettings );
+General::readhash( "/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color );
+General::readhash( $settings, \%settings ) if (-r $settings);
+General::readhash( $modified, \%modified) if (-r $modified);
+eval qx|/bin/cat $sources| if (-r $sources);
+
+# Show Headers
+
+Header::showhttpheaders();
+
+# Process actions
+
+if ($cgiparams{'ACTION'} eq "$Lang::tr{'save'}")
+{
+ #Save Button on configsite
+
+ my %new_settings = ( 'ENABLE' => 'off',
+ 'RATE' => 24,
+ 'LOGGING' => 'off',
+ 'DEBUG' => 0,
+ 'BLOCK_THRESHOLD' => $settings{'BLOCK_THRESHOLD'} || 10,
+ 'BLOCK_PERIOD' => $settings{'BLOCK_PERIOD'} || 3600,
+ $autoblacklist => $settings{$autoblacklist} );
+
+ $errormessage .= "$Lang::tr{'ipblacklist invalid check rate'}<br>" if (($cgiparams{'RATE'} !~ m/^\d+$/) or
+ ($cgiparams{'RATE'} < 1) or
+ ($cgiparams{'RATE'} > 1000));
+
+ $new_settings{'RATE'} = $cgiparams{'RATE'};
+ delete $cgiparams{'RATE'};
+
+ foreach my $item ('LOGGING', 'ENABLE', keys %sources)
+ {
+ $new_settings{$item} = (exists $cgiparams{$item}) ? 'on' : 'off';
+
+ $updating = 1 if (not exists $settings{$item} or $new_settings{$item} ne $settings{$item});
+ }
+
+ # Check for redundant blacklists being enabled
+
+ foreach my $list (keys %sources)
+ {
+ if (exists $settings{$list} and
+ $settings{$list} eq 'on' and
+ exists $sources{$list}{'override'} and
+ $settings{$sources{$list}{'override'}} eq 'on')
+ {
+ $settings{$sources{$list}{'override'}} = 'off';
+
+ $updating = 1;
+ $errormessage .= "$Lang::tr{'ipblacklist disable pre'} $sources{$list}{'override'} " .
+ "$Lang::tr{'ipblacklist disable mid'} $list $Lang::tr{'ipblacklist disable post'}<br>\n";
+ }
+ }
+
+ if ($settings{'LOGGING'} ne $new_settings{'LOGGING'})
+ {
+ if ($new_settings{'LOGGING'} eq 'on')
+ {
+ system( "$control log-on" );
+ }
+ else
+ {
+ system( "$control log-off" );
+ }
+ }
+
+ if ($settings{'ENABLE'} ne $new_settings{'ENABLE'})
+ {
+ if ($new_settings{'ENABLE'} eq 'on')
+ {
+ system( "$control enable" );
+ }
+ else
+ {
+ $settings{$autoblacklist} = 'off';
+ system( "$control disable" );
+ }
+
+ $updating = 1;
+ }
+
+ %settings = %new_settings;
+
+ if ($errormessage)
+ {
+ $updating = 0;
+ }
+ else
+ {
+ General::writehash($settings, \%new_settings);
+
+ if ($updating)
+ {
+ system( "$control update &" );
+ get_ipset_stats();
+ show_running();
+ exit 0;
+ }
+ }
+}
+elsif ($cgiparams{'AUTOACTION'} eq "$Lang::tr{'save'}")
+{
+ $updating = 1 if ($settings{$autoblacklist} eq 'on' and not exists $cgiparams{$autoblacklist});
+ $updating = 1 if ($settings{$autoblacklist} eq 'off' and exists $cgiparams{$autoblacklist});
+
+ $settings{$autoblacklist} = (exists $cgiparams{$autoblacklist}) ? 'on' : 'off';
+ $settings{'BLOCK_THRESHOLD'} = $cgiparams{'BLOCK_THRESHOLD'};
+ $settings{'BLOCK_PERIOD'} = $cgiparams{'BLOCK_PERIOD'} ;
+
+ if (($cgiparams{'BLOCK_THRESHOLD'} !~ m/^\d+$/) or
+ ($cgiparams{'BLOCK_THRESHOLD'} < 1) or
+ ($cgiparams{'BLOCK_THRESHOLD'} > 1000000))
+ {
+ $errormessage .= "$Lang::tr{'ipblacklist invalid threshold'}: $cgiparams{'BLOCK_THRESHOLD'}<br>";
+ }
+
+ if (($cgiparams{'BLOCK_PERIOD'} !~ m/^\d+$/) or
+ ($cgiparams{'BLOCK_PERIOD'} < 1) or
+ ($cgiparams{'BLOCK_PERIOD'} > 86400))
+ {
+ $errormessage .= "$Lang::tr{'ipblacklist invalid block time'}: $cgiparams{'BLOCK_PERIOD'}<br>";
+ }
+
+ if ($errormessage)
+ {
+ $updating = 0;
+ }
+ else
+ {
+ General::writehash($settings, \%settings);
+ system( "$control autoblacklist-update" ) if ($updating);
+ }
+}
+elsif ($cgiparams{'AUTOACTION'} eq "$Lang::tr{'unblock all'}")
+{
+ system( "$control autoblacklist-clear" );
+}
+
+get_ipset_stats();
+
+if (is_running())
+{
+ show_running();
+ exit 0;
+}
+
+# Get blacklist statistics
+
+get_iptables_stats();
+
+# Show site
+
+Header::openpage($Lang::tr{'ipblacklist'}, 1, '');
+Header::openbigbox('100%', 'left');
+error();
+
+showstatus() if ($settings{ENABLE} eq 'on');
+
+configsite();
+
+# End of page
+
+Header::closebigbox();
+Header::closepage();
+
+exit 0;
+
+
+#------------------------------------------------------------------------------
+# sub configsite()
+#
+# Displays configuration
+#------------------------------------------------------------------------------
+
+sub configsite
+{
+ # Find preselections
+
+ my $enable = 'checked';
+ Header::openbox('100%', 'left', $Lang::tr{'settings'});
+
+ #### JAVA SCRIPT ####
+
+ print<<END;
+<script>
+ \$(document).ready(function()
+ {
+ // Show/Hide elements when ENABLE checkbox is checked.
+ if (\$("#ENABLE").attr("checked"))
+ {
+ \$(".sources").show();
+ }
+ else
+ {
+ \$(".sources").hide();
+ }
+
+ // Toggle Source list elements when "ENABLE" checkbox is clicked
+ \$("#ENABLE").change(function()
+ {
+ \$(".sources").toggle();
+ });
+ });
+</script>
+END
+
+ ##### JAVA SCRIPT END ####
+
+ # Enable checkbox
+
+ $enable = ($settings{'ENABLE'} eq 'on') ? ' checked' : '';
+
+ print<<END;
+ <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+ <table style='width:100%' border='0'>
+ <tr>
+ <td style='width:24em'>$Lang::tr{'ipblacklist use ipblacklists'}</td>
+ <td><input type='checkbox' name='ENABLE' id='ENABLE'$enable></td>
+ </tr>
+ </table><br>
+
+END
+
+ # The following are only displayed if the blacklists are enabled
+
+ $enable = ($settings{'LOGGING'} eq 'on') ? ' checked' : '';
+
+ print <<END;
+<div class='sources'>
+ <table style='width:100%' border='0'>
+ <tr>
+ <td style='width:24em'>$Lang::tr{'ipblacklist log'}</td>
+ <td><input type='checkbox' name="LOGGING" id="LOGGING"$enable></td>
+ <td style='width:24em'>$Lang::tr{'ipblacklist check rate'}</td>
+ <td>
+ <input type='number' name='RATE' min='1' max='1000' maxlength='7' pattern='\\d+' value='$settings{'RATE'}'>
+ </td>
+ </tr>
+ </table>
+ <br><br>
+ <h2>$Lang::tr{'ipblacklist blacklist settings'}</h2>
+ <table width='100%' cellspacing='1' class='tbl'>
+ <tr>
+ <th align='left'>$Lang::tr{'ipblacklist id'}</th>
+ <th align='left'>$Lang::tr{'ipblacklist name'}</th>
+ <th align='center'>$Lang::tr{'ipblacklist safe'}</th>
+ <th align='center'>$Lang::tr{'ipblacklist enable'}</th>
+ </tr>
+END
+
+ # Iterate through the list of sources
+
+ my $lines = 0;
+
+ foreach my $list (sort keys %sources)
+ {
+ my $name = escapeHTML( $sources{$list}{'name'} );
+ my $safe = $Lang::tr{$sources{$list}{safe}};
+ $enable = '';
+ my $col = ($lines++ % 2) ? "bgcolor='$color{'color20'}'" : "bgcolor='$color{'color22'}'";
+
+ $enable = ' checked' if (exists $settings{$list} and $settings{$list} eq 'on');
+
+ print <<END;
+ <tr $col>
+ <td>
+END
+
+ if ($sources{$list}{info})
+ {
+ print "<a href='$sources{$list}{info}' target='_blank'>$list</a>\n";
+ }
+ else
+ {
+ print "$list\n";
+ }
+
+ print <<END;
+ </td>
+ <td>$name</td>
+ <td align='center'>$safe</td>
+ <td align='center'><input type='checkbox' name="$list" id="$list"$enable></td>
+ </tr>\n
+END
+ }
+
+ # The save button at the bottom of the table
+
+ print <<END;
+ </table>
+ <p>$Lang::tr{'ipblacklist safe note'}</p>
+ </div>
+ <table style='width:100%;'>
+ <tr>
+ <td colspan='3' display:inline align='right'><input type='submit' name='ACTION' value='$Lang::tr{'save'}'></td>
+ </tr>
+ </table>
+ <div class='sources'>
+ <br>
+END
+
+ $enable = $settings{$autoblacklist} eq 'on' ? ' checked' : '';
+
+ print <<END;
+ <br><br>
+ <h2>$Lang::tr{'ipblacklist auto list'}</h2>
+ <table style='width:100%' border='0'>
+ <tr>
+ <td>
+ $Lang::tr{'ipblacklist autoblacklist enable'}
+ </td>
+ <td>
+ <input type='checkbox' name="$autoblacklist" id="$autoblacklist"$enable>
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ $Lang::tr{'ipblacklist autoblacklist threshold'}
+ </td>
+ <td>
+ <input type='number' name='BLOCK_THRESHOLD' min='1' max='1000000' maxlength='7' pattern='\\d+' value='$settings{BLOCK_THRESHOLD}'>
+ </input>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ $Lang::tr{'ipblacklist autoblacklist block time'}
+ </td>
+ <td>
+ <input type='number' name='BLOCK_PERIOD' min='1' max='86400' maxlength='7' pattern='\\d+' value='$settings{BLOCK_PERIOD}'>
+ </input>
+ </td>
+ </tr>
+ </table>
+ <table style='width:100%;'>
+ <tr>
+ <td colspan='3' display:inline align='right'><input type='submit' name='AUTOACTION' value='$Lang::tr{'save'}'></td>
+ </tr>
+ </table>
+ </form>
+ </div>
+END
+
+ Header::closebox();
+}
+
+
+#------------------------------------------------------------------------------
+# sub showstatus()
+#
+# Displays current blacklist status
+#------------------------------------------------------------------------------
+
+sub showstatus
+{
+ Header::openbox('100%', 'center', $Lang::tr{'status'});
+
+ print <<END;
+ <table width='100%' cellspacing='1'>
+ <tr>
+ <th align='left'>$Lang::tr{'ipblacklist id'}</th>
+ <th align='right'>$Lang::tr{'ipblacklist entries'}</th>
+ <th align='right'>$Lang::tr{'ipblacklist pkts in'}</th>
+ <th align='right'>$Lang::tr{'ipblacklist bytes in'}</th>
+ <th align='right'>$Lang::tr{'ipblacklist pkts out'}</th>
+ <th align='right'>$Lang::tr{'ipblacklist bytes out'}</th>
+ <th align='center'>$Lang::tr{'ipblacklist updated'}</th>
+ </tr>
+END
+
+ # Iterate through the list of sources
+
+ foreach my $list ($autoblacklist, sort keys %sources)
+ {
+ next unless ($settings{$list} eq 'on');
+
+ my $size = ' ';
+ my $pkts_in = ' ';
+ my $bytes_in = ' ';
+ my $pkts_out = ' ';
+ my $bytes_out = ' ';
+ my $updated = ' ';
+
+ if (exists $stats{$list})
+ {
+ ($pkts_in, $bytes_in) = @{ $stats{$list}{IPBLACKLISTREDIN} } if (exists $stats{$list}{IPBLACKLISTREDIN});
+ ($pkts_out, $bytes_out) = @{ $stats{$list}{IPBLACKLISTREDOUT} } if (exists $stats{$list}{IPBLACKLISTREDOUT});
+ $size = $stats{$list}{size} if (exists $stats{$list}{size});
+ }
+
+ if (exists $modified{$list} and $modified{$list} > 0)
+ {
+ $updated = localtime( $modified{$list} );
+ }
+
+ print <<END;
+ <tr>
+ <td>$list</td>
+ <td align='right'>$size</td>
+ <td align='right'>$pkts_in</td>
+ <td align='right'>$bytes_in</td>
+ <td align='right'>$pkts_out</td>
+ <td align='right'>$bytes_out</td>
+ <td align='center'>$updated</td>
+ </tr>\n
+END
+
+ }
+
+ print <<END;
+ </table>
+END
+
+ if ($settings{$autoblacklist} eq 'on')
+ {
+ print <<END;
+ <br><br>
+ <h2>$Lang::tr{'ipblacklist auto list'}</h2>
+ <table width='60%' cellspacing='1'>
+ <tr>
+ <th align='left'>$Lang::tr{'ip address'}</th>
+ <th align='center'>$Lang::tr{'ipblacklist block time remaining'}</th>
+ </tr>
+END
+
+ foreach my $address (nsort keys %autoblock_addresses )
+ {
+ print "<tr><td>$address</td><td align='center'>$autoblock_addresses{$address}</td></tr>\n";
+ }
+
+ print <<END;
+ </table>
+ <table width='60%' border='0'>
+ <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+ <tr>
+ <td align='right' width='15%'><input type='submit' name='ACTION' value='$Lang::tr{'unblock all'}'></td>
+ </tr>
+ </form>
+ </table>
+END
+ }
+
+ Header::closebox();
+}
+
+
+#------------------------------------------------------------------------------
+# sub get_ipset_stats()
+#
+# Gets the number of entries in each IPSet.
+#------------------------------------------------------------------------------
+
+sub get_ipset_stats
+{
+ my $name;
+
+ system( $getipsetstat );
+
+ # Get the number of entries in each IP set
+
+ if (-r '/var/tmp/ipsets.txt')
+ {
+ open STATS, '<', '/var/tmp/ipsets.txt' or die "Can't open IP Sets stats file: $!";
+
+ foreach my $line (<STATS>)
+ {
+ if ($line =~ m/Name: (\w+)/)
+ {
+ $name = $1;
+ next;
+ }
+
+ if ($line =~ m/Number of entries: (\d+)/)
+ {
+ $stats{$name}{'size'} = $1;
+ }
+ }
+
+ close STATS;
+
+ unlink( '/var/tmp/ipsets.txt' );
+ }
+
+ # Get the IP addresses in the autoblacklist
+
+ if (-r '/var/tmp/autoblacklist.txt')
+ {
+ open HASHTABLE, '<', '/var/tmp/autoblacklist.txt' or die "Can't open autoblacklist address file: $!";
+
+ # Iterate through the blocked addresses
+
+ foreach my $line (<HASHTABLE>)
+ {
+ next unless ($line =~ m/(\d+\.\d+\.\d+\.\d+) timeout (\d+)/);
+
+ $autoblock_addresses{$1} = format_time( $2 );
+ }
+
+ close HASHTABLE;
+
+ unlink( '/var/tmp/autoblacklist.txt' );
+ }
+
+}
+
+
+#------------------------------------------------------------------------------
+# sub get_iptables_stats()
+#
+# Gets information on the number of packets and bytes rejected by each
+# blacklist
+#------------------------------------------------------------------------------
+
+sub get_iptables_stats
+{
+ system( $getipstat );
+ unlink( '/var/tmp/iptablesmangle.txt' );
+ unlink( '/var/tmp/iptablesnat.txt' );
+
+ return unless (-r '/var/tmp/iptables.txt');
+
+ open STATS, '<', '/var/tmp/iptables.txt' or die "Can't open IP Tables stats file: $!";
+
+ my $table = 'Unknown';
+
+ foreach my $line (<STATS>)
+ {
+ if ($line =~ m/^Chain (\w+)/)
+ {
+ $table = $1;
+ next;
+ }
+
+ next unless ($line =~ m/_BLOCK/);
+
+ my ($pkts, $bytes, $chain) = $line =~ m/^\s*(\d+\w?)\s+(\d+\w?)\s+(\w+)_BLOCK/;
+ $stats{$chain}{$table} = [ $pkts, $bytes ];
+ }
+
+ close STATS;
+
+ unlink( '/var/tmp/iptables.txt' );
+}
+
+
+#------------------------------------------------------------------------------
+# sub is_running()
+#
+# Checks to see if the main script is running
+#------------------------------------------------------------------------------
+
+sub is_running
+{
+ return 0 unless (-r $lockfile);
+
+ open LOCKFILE, '<', $lockfile or die "Can't open lockfile";
+ my $pid = <LOCKFILE>;
+ close LOCKFILE;
+
+ chomp $pid;
+
+ return (-e "/proc/$pid");
+}
+
+
+#------------------------------------------------------------------------------
+# sub show_running
+#
+# Displayed when update is running
+#------------------------------------------------------------------------------
+
+sub show_running
+{
+ # Open site
+
+ Header::openpage( $Lang::tr{'ipblacklist'}, 1, '<meta http-equiv="refresh" content="1;url=/cgi-bin/ipblacklist.cgi">' );
+ Header::openbigbox( '100%', 'center' );
+ error();
+ Header::openbox( 'Working', 'center', "$Lang::tr{'ipblacklist working'}" );
+
+ print <<END;
+ <table width='100%'>
+ <tr>
+ <td align='center'>
+ <img src='/images/indicator.gif' alt='$Lang::tr{'aktiv'}'>
+ <td>
+ </tr>
+ </table>
+ <br>
+ <table cellspacing='1' align='center'>
+ <tr><th>$Lang::tr{'ipblacklist id'}</th><th>$Lang::tr{'ipblacklist entries'}</th></tr>
+END
+
+ foreach my $name (keys %sources)
+ {
+ $stats{$name}{'size'} = ' ' if (not exists ($stats{$name}) and
+ exists $settings{$name} and
+ $settings{$name} eq 'on');
+ }
+
+ foreach my $name (sort keys %stats)
+ {
+ print "<tr><td>$name</td><td align='right'>$stats{$name}{'size'}</td></tr>\n" if (exists $stats{$name}{'size'});
+ }
+
+ print <<END;
+ </table>
+END
+
+ Header::closebox();
+
+ Header::closebigbox();
+ Header::closepage();
+}
+
+
+#------------------------------------------------------------------------------
+# sub error()
+#
+# Shows error messages
+#------------------------------------------------------------------------------
+
+sub error
+{
+ if ($errormessage)
+ {
+ Header::openbox('100%', 'left', $Lang::tr{'error messages'});
+ print "<class name='base'>$errormessage\n";
+ print " </class>\n";
+ Header::closebox();
+ }
+}
+
+
+#------------------------------------------------------------------------------
+# sub format_time( seconds )
+#
+# Converts time in seconds to HH:MM:SS
+#------------------------------------------------------------------------------
+
+sub format_time($) {
+ my $time = shift;
+
+ my $seconds = $time % 60;
+ my $minutes = $time / 60;
+
+ my $hours = 0;
+ if ($minutes >= 60) {
+ $hours = $minutes / 60;
+ $minutes %= 60;
+ }
+
+ return sprintf("%3d:%02d:%02d", $hours, $minutes, $seconds);
+}
@@ -59,6 +59,7 @@ my %sections = (
'dhcp' => '(dhcpd: )',
'dma' => '(dma: |dma\[.*\]: |postfix/\w*\[\d*\]: )',
'guardian' => '(guardian\[.*\]: )',
+ 'ipblacklist' => '(ipblacklist: )',
'ipfire' => '(ipfire: )',
'ipsec' => '(ipsec_[\w_]+: |pluto\[.*\]: |charon: |vpnwatch: )',
'kernel' => '(kernel: (?!DROP_))',
@@ -87,6 +88,7 @@ my %trsections = (
'dhcp' => "$Lang::tr{'dhcp server'}",
'dma' => 'Mail',
'guardian' => "$Lang::tr{'guardian'}",
+ 'ipblacklist' => "$Lang::tr{'ipblacklist'}",
'ipfire' => 'IPFire',
'ipsec' => 'IPSec',
'kernel' => "$Lang::tr{'kernel'}",
@@ -1518,6 +1518,37 @@
'ip alias changed' => 'External IP alias changed',
'ip alias removed' => 'External IP alias removed',
'ip info' => 'IP Information',
+'ipblacklist auto list' => 'Automatic blacklist',
+'ipblacklist autoblacklist enable' => 'Enable automatically updating local blacklist',
+'ipblacklist autoblacklist threshold' => 'Threshold (packets/hour)',
+'ipblacklist autoblacklist block time' => 'Block time (seconds)',
+'ipblacklist blacklist settings' => 'Blacklist settings',
+'ipblacklist bytes in' => 'bytes in',
+'ipblacklist bytes out' => 'bytes out',
+'ipblacklist check rate' => 'Update check rate (hours)',
+'ipblacklist day' => 'day',
+'ipblacklist disable pre' => 'Disabling',
+'ipblacklist disable mid' => 'because it is included in',
+'ipblacklist disable port' => '',
+'ipblacklist enable' => 'Enable',
+'ipblacklist entries' => 'Entries',
+'ipblacklist hour' => 'hour',
+'ipblacklist id' => 'Blacklist',
+'ipblacklist invalid block time' => 'Invalid automatic blacklist block time',
+'ipblacklist invalid check rate' => 'Invalid update check rate',
+'ipblacklist invalid threshold' => 'Invalid automatic blacklist threshold',
+'ipblacklist log' => 'Log dropped packets',
+'ipblacklist name' => 'Name',
+'ipblacklist pkts in' => 'pkts in',
+'ipblacklist pkts out' => 'pkts out',
+'ipblacklist safe note' => 'Note: safe blacklists block addresses that only generate malicious traffic and therefore will not block any wanted sites.',
+'ipblacklist safe' => 'Safe',
+'ipblacklist sixhour' => 'six hours',
+'ipblacklist updated' => 'Last updated',
+'ipblacklist use ipblacklists' => 'Enable IP Blacklists',
+'ipblacklist week' => 'week',
+'ipblacklist working' => 'Updating IP address blacklists...',
+'ipblacklist' => 'IP Address Blacklists',
'ipfire has now rebooted' => 'IPFire is rebooting now.',
'ipfire has now shutdown' => 'IPFire is shutting down now.',
'ipfire side' => 'IPFire side:',