diff --git a/html/cgi-bin/ipblacklist.cgi b/html/cgi-bin/ipblacklist.cgi
new file mode 100644
index 000000000..28b42edf2
--- /dev/null
+++ b/html/cgi-bin/ipblacklist.cgi
@@ -0,0 +1,463 @@
+#!/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 . #
+# #
+# Copyright (C) 2018 - 2020 The IPFire Team #
+# #
+###############################################################################
+
+use strict;
+use CGI qw/:standard/;
+# enable the following only for debugging purposes
+#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";
+
+###############################################################################
+# Configuration variables
+###############################################################################
+
+my $settings = "${General::swroot}/ipblacklist/settings";
+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 %cgiparams = ('ACTION' => '');
+
+###############################################################################
+# Variables
+###############################################################################
+
+my $errormessage = '';
+my $updating = 0;
+my %mainsettings;
+my %color;
+my %sources;
+my %stats;
+
+# Default settings - normally overwritten by settings file
+
+my %settings = ( 'DEBUG' => 0,
+ 'LOGGING' => 'on',
+ 'ENABLE' => 'off' );
+
+# Read all parameters
+
+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);
+eval qx|/bin/cat $sources| if (-r $sources);
+
+# Show Headers
+
+Header::showhttpheaders();
+
+# Process actions
+
+if ($cgiparams{'ACTION'} eq "$Lang::tr{'save'}")
+{
+ # Save Button
+
+ my %new_settings = ( 'ENABLE' => 'off',
+ 'LOGGING' => 'off',
+ 'DEBUG' => 0 );
+
+ 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 $new_settings{$list} and
+ $new_settings{$list} eq 'on' and
+ exists $sources{$list}{'disable'})
+ {
+ my @disable;
+
+ if ('ARRAY' eq ref $sources{$list}{'disable'})
+ {
+ @disable = @{ $sources{$list}{'disable'} };
+ }
+ else
+ {
+ @disable = ( $sources{$list}{'disable'} );
+ }
+
+ foreach my $disable (@disable)
+ {
+ if ($new_settings{$disable} eq 'on')
+ {
+ $new_settings{$disable} = 'off';
+
+ $updating = 1;
+ $errormessage .= "$Lang::tr{'ipblacklist disable pre'} $disable " .
+ "$Lang::tr{'ipblacklist disable mid'} $list $Lang::tr{'ipblacklist disable post'} \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
+ {
+ system( "$control disable" );
+ }
+
+ $updating = 1;
+ }
+
+ %settings = %new_settings;
+
+ if ($errormessage)
+ {
+ $updating = 0;
+ }
+ else
+ {
+ General::writehash($settings, \%new_settings);
+
+ if ($updating)
+ {
+ system( "$control update &" );
+ show_running();
+ exit 0;
+ }
+ }
+}
+
+if (is_running())
+{
+ show_running();
+ exit 0;
+}
+
+# Show site
+
+Header::openpage($Lang::tr{'ipblacklist'}, 1, '');
+Header::openbigbox('100%', 'left');
+
+error() if ($errormessage);
+
+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<
+ \$(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();
+ });
+ });
+
+END
+
+ ##### JAVA SCRIPT END ####
+
+ # Enable checkbox
+
+ $enable = ($settings{'ENABLE'} eq 'on') ? ' checked' : '';
+
+ print<
+
+
+
$Lang::tr{'ipblacklist use ipblacklists'}
+
+
+
+
+END
+
+ # The following are only displayed if the blacklists are enabled
+
+ $enable = ($settings{'LOGGING'} eq 'on') ? ' checked' : '';
+
+ print <
+
+
+
$Lang::tr{'ipblacklist log'}
+
+
+
+
+
$Lang::tr{'ipblacklist blacklist settings'}
+
+
+
$Lang::tr{'ipblacklist id'}
+
$Lang::tr{'ipblacklist name'}
+
$Lang::tr{'ipblacklist category'}
+
$Lang::tr{'ipblacklist enable'}
+
+END
+
+ # Iterate through the list of sources
+
+ my $lines = 0;
+
+ foreach my $list (sort keys %sources)
+ {
+ my $name = escapeHTML( $sources{$list}{'name'} );
+ my $category = $Lang::tr{"ipblacklist category $sources{$list}{'category'}"};
+ $enable = '';
+ my $col = ($lines++ % 2) ? "bgcolor='$color{'color20'}'" : "bgcolor='$color{'color22'}'";
+
+ $enable = ' checked' if (exists $settings{$list} and $settings{$list} eq 'on');
+
+ print <
+