From 67716b19bb5ab806fdd63f630e53c158dabedf2d Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sat, 20 Dec 2014 16:02:29 +0100 Subject: [PATCH 01/40] perl-Text-CSV_XS: New package. This is a dependency for the xtables-geoip module to convert the only in the cvs provided geoip list into a compatible binary format. --- lfs/perl-Text-CSV_XS | 83 ++++++++++++++++++++++++++++++++++++++++++++ make.sh | 1 + 2 files changed, 84 insertions(+) create mode 100644 lfs/perl-Text-CSV_XS diff --git a/lfs/perl-Text-CSV_XS b/lfs/perl-Text-CSV_XS new file mode 100644 index 000000000..0f948e6c2 --- /dev/null +++ b/lfs/perl-Text-CSV_XS @@ -0,0 +1,83 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2014 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 . # +# # +############################################################################### + + +############################################################################### +# Definitions +############################################################################### + +include Config +VER = 1.12 + +THISAPP = Text-CSV_XS-$(VER) +DL_FILE = ${THISAPP}.tgz +DL_FROM = $(URL_IPFIRE) +DIR_APP = $(DIR_SRC)/$(THISAPP) +TARGET = $(DIR_INFO)/$(THISAPP) +PROG = perl-Text-CSV_XS +DEPS = "" +PAK_VER = 1 + +############################################################################### +# Top-level Rules +############################################################################### + +objects = $(DL_FILE) + +$(DL_FILE) = $(DL_FROM)/$(DL_FILE) + +$(DL_FILE)_MD5 = b91f2d806054b68c2a29d3da5821fe87 + +install : $(TARGET) + +check : $(patsubst %,$(DIR_CHK)/%,$(objects)) + +download :$(patsubst %,$(DIR_DL)/%,$(objects)) + +md5 : $(subst %,%_MD5,$(objects)) + +dist: + @$(PAK) + +############################################################################### +# Downloading, checking, md5sum +############################################################################### + +$(patsubst %,$(DIR_CHK)/%,$(objects)) : + @$(CHECK) + +$(patsubst %,$(DIR_DL)/%,$(objects)) : + @$(LOAD) + +$(subst %,%_MD5,$(objects)) : + @$(MD5) + +############################################################################### +# Installation Details +############################################################################### + +$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) + @$(PREBUILD) + @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE) + cd $(DIR_APP) && perl Makefile.PL + cd $(DIR_APP) && make $(MAKETUNING) $(EXTRA_MAKE) + cd $(DIR_APP) && make install + @rm -rf $(DIR_APP) + @$(POSTBUILD) diff --git a/make.sh b/make.sh index 40075916e..a5e847ebb 100755 --- a/make.sh +++ b/make.sh @@ -804,6 +804,7 @@ buildipfire() { ipfiremake squid-accounting ipfiremake pigz ipfiremake tmux + ipfiremake perl-Text-CSV_XS } buildinstaller() { From bf235e962cdd2d0d95d9a6ccfef0b449d181bb04 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sat, 3 Jan 2015 14:01:43 +0100 Subject: [PATCH 02/40] perl-Locale-Country: Update country codes to version 3.33. --- lfs/Locale-Country | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lfs/Locale-Country b/lfs/Locale-Country index b2c1455ef..02bf7a026 100644 --- a/lfs/Locale-Country +++ b/lfs/Locale-Country @@ -24,7 +24,7 @@ include Config -VER = 2.07 +VER = 3.33 THISAPP = Locale-Codes-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -40,7 +40,7 @@ objects = $(DL_FILE) $(DL_FILE) = $(DL_FROM)/$(DL_FILE) -$(DL_FILE)_MD5 = af0537cc4a882096d0320612c440df6d +$(DL_FILE)_MD5 = bc7496f97889de8504e80addaa0ee40c install : $(TARGET) From 72074fcdd2169a4698d5a5dec288e2adeca9af67 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sat, 3 Jan 2015 14:03:20 +0100 Subject: [PATCH 03/40] perl-Text-CSV_XS: New package. This perl module is required to convert the provided geoip databases in CSV format into a useable binary format for the geoip module. --- config/rootfiles/common/perl-Text-CSV_XS | 8 ++++++++ lfs/perl-Text-CSV_XS | 6 ------ 2 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 config/rootfiles/common/perl-Text-CSV_XS diff --git a/config/rootfiles/common/perl-Text-CSV_XS b/config/rootfiles/common/perl-Text-CSV_XS new file mode 100644 index 000000000..ca2f64228 --- /dev/null +++ b/config/rootfiles/common/perl-Text-CSV_XS @@ -0,0 +1,8 @@ +#usr/lib/perl5/site_perl/5.12.3/i586-linux-thread-multi/Text +usr/lib/perl5/site_perl/5.12.3/i586-linux-thread-multi/Text/CSV_XS.pm +#usr/lib/perl5/site_perl/5.12.3/i586-linux-thread-multi/auto/Text +#usr/lib/perl5/site_perl/5.12.3/i586-linux-thread-multi/auto/Text/CSV_XS +#usr/lib/perl5/site_perl/5.12.3/i586-linux-thread-multi/auto/Text/CSV_XS/.packlist +#usr/lib/perl5/site_perl/5.12.3/i586-linux-thread-multi/auto/Text/CSV_XS/CSV_XS.bs +usr/lib/perl5/site_perl/5.12.3/i586-linux-thread-multi/auto/Text/CSV_XS/CSV_XS.so +#usr/share/man/man3/Text::CSV_XS.3 diff --git a/lfs/perl-Text-CSV_XS b/lfs/perl-Text-CSV_XS index 0f948e6c2..f94593f98 100644 --- a/lfs/perl-Text-CSV_XS +++ b/lfs/perl-Text-CSV_XS @@ -31,9 +31,6 @@ DL_FILE = ${THISAPP}.tgz DL_FROM = $(URL_IPFIRE) DIR_APP = $(DIR_SRC)/$(THISAPP) TARGET = $(DIR_INFO)/$(THISAPP) -PROG = perl-Text-CSV_XS -DEPS = "" -PAK_VER = 1 ############################################################################### # Top-level Rules @@ -53,9 +50,6 @@ download :$(patsubst %,$(DIR_DL)/%,$(objects)) md5 : $(subst %,%_MD5,$(objects)) -dist: - @$(PAK) - ############################################################################### # Downloading, checking, md5sum ############################################################################### From b8e0573b5c698df6ba5587da9c4fc9595288ae79 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sat, 3 Jan 2015 14:07:49 +0100 Subject: [PATCH 04/40] xtables-addons: New package. The xtables-addons package provides many additional filter modules for iptables. Currently we are only building the "geoip" module which can be used to create firewall rules which will do actions based on the country membership of the senders/targets address. In order to build the required kernel modules I had to change build order for several packages as well. --- config/rootfiles/common/xtables-addons | 7 ++ config/xtables-addons/mconfig | 24 ++++++ lfs/xtables-addons | 110 +++++++++++++++++++++++++ make.sh | 12 ++- 4 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 config/rootfiles/common/xtables-addons create mode 100644 config/xtables-addons/mconfig create mode 100644 lfs/xtables-addons diff --git a/config/rootfiles/common/xtables-addons b/config/rootfiles/common/xtables-addons new file mode 100644 index 000000000..9053c280c --- /dev/null +++ b/config/rootfiles/common/xtables-addons @@ -0,0 +1,7 @@ +lib/xtables/libxt_geoip.so +#usr/libexec/xtables-addons +usr/libexec/xtables-addons/xt_geoip_build +usr/libexec/xtables-addons/xt_geoip_dl +#usr/share/man/man1/xt_geoip_build.1 +#usr/share/man/man1/xt_geoip_dl.1 +#usr/share/man/man8/xtables-addons.8 diff --git a/config/xtables-addons/mconfig b/config/xtables-addons/mconfig new file mode 100644 index 000000000..92e47f0ad --- /dev/null +++ b/config/xtables-addons/mconfig @@ -0,0 +1,24 @@ +# -*- Makefile -*- +# +build_ACCOUNT=n +build_CHAOS=n +build_DELUDE=n +build_DHCPMAC=n +build_DNETMAP=n +build_ECHO=n +build_IPMARK=n +build_LOGMARK=n +build_SYSRQ=n +build_TARPIT=n +build_condition=n +build_fuzzy=n +build_geoip=m +build_gradm=n +build_iface=n +build_ipp2p=n +build_ipv4options=n +build_length2=n +build_lscan=n +build_pknock=n +build_psd=n +build_quota2=n diff --git a/lfs/xtables-addons b/lfs/xtables-addons new file mode 100644 index 000000000..1848dc908 --- /dev/null +++ b/lfs/xtables-addons @@ -0,0 +1,110 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007-2014 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 . # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include Config + +VERSUFIX = ipfire$(KCFG) +MODPATH = /lib/modules/$(KVER)-$(VERSUFIX)/extra/ + +VER = 2.6 + +THISAPP = xtables-addons-$(VER) +DL_FILE = $(THISAPP).tar.xz +DL_FROM = $(URL_IPFIRE) +DIR_APP = $(DIR_SRC)/$(THISAPP) + +ifeq "$(USPACE)" "1" + TARGET = $(DIR_INFO)/$(THISAPP) +else + TARGET = $(DIR_INFO)/$(THISAPP)-kmod-$(KVER)-$(VERSUFIX) +endif + +############################################################################### +# Top-level Rules +############################################################################### + +objects = $(DL_FILE) + +$(DL_FILE) = $(DL_FROM)/$(DL_FILE) + +$(DL_FILE)_MD5 = 087835ba7e564481b6fd398692268340 + +install : $(TARGET) + +check : $(patsubst %,$(DIR_CHK)/%,$(objects)) + +download :$(patsubst %,$(DIR_DL)/%,$(objects)) + +md5 : $(subst %,%_MD5,$(objects)) + +dist: + $(PAK) + +############################################################################### +# Downloading, checking, md5sum +############################################################################### + +$(patsubst %,$(DIR_CHK)/%,$(objects)) : + @$(CHECK) + +$(patsubst %,$(DIR_DL)/%,$(objects)) : + @$(LOAD) + +$(subst %,%_MD5,$(objects)) : + @$(MD5) + +############################################################################### +# Installation Details +############################################################################### + +$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) + @$(PREBUILD) + @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar axf $(DIR_DL)/$(DL_FILE) + + # Only build the specified modules. + cp -avf $(DIR_SRC)/config/xtables-addons/mconfig \ + $(DIR_APP)/mconfig + +# Check if we build the modules for a kernel or the userspace parts. +ifeq "$(USPACE)" "1" + cd $(DIR_APP) && ./configure \ + --prefix=/usr \ + --without-kbuild + + cd $(DIR_APP) && make $(MAKETUNING) + cd $(DIR_APP) && make install +else + cd $(DIR_APP) && ./configure \ + --with-kbuild=/usr/src/linux-$(KVER)/ + + cd $(DIR_APP) && make $(MAKETUNING) + + # Install the built kernel modules. + cd $(DIR_APP) && for f in $$(ls extensions/*.ko); do \ + install -m 644 $$f $(MODPATH); \ + done +endif + + @rm -rf $(DIR_APP) + @$(POSTBUILD) diff --git a/make.sh b/make.sh index a5e847ebb..d4899f9a3 100755 --- a/make.sh +++ b/make.sh @@ -383,6 +383,7 @@ buildipfire() { export LOGFILE ipfiremake configroot ipfiremake backup + ipfiremake pkg-config ipfiremake libusb ipfiremake libusbx ipfiremake libpcap @@ -403,6 +404,8 @@ buildipfire() { ipfiremake multipath-tools ipfiremake freetype ipfiremake grub + ipfiremake libmnl + ipfiremake iptables case "${TARGET_ARCH}" in i586) @@ -412,6 +415,7 @@ buildipfire() { ipfiremake e1000e KCFG="-pae" ipfiremake igb KCFG="-pae" ipfiremake ixgbe KCFG="-pae" + ipfiremake xtables-addons KCFG="-pae" ipfiremake linux-initrd KCFG="-pae" # x86 kernel build @@ -420,6 +424,7 @@ buildipfire() { ipfiremake e1000e KCFG="" ipfiremake igb KCFG="" ipfiremake ixgbe KCFG="" + ipfiremake xtables-addons KCFG="" ipfiremake linux-initrd KCFG="" ;; @@ -427,6 +432,7 @@ buildipfire() { # arm-rpi (Raspberry Pi) kernel build ipfiremake linux KCFG="-rpi" ipfiremake cryptodev KCFG="-rpi" + ipfiremake xtables-addons KCFG="-rpi" ipfiremake linux-initrd KCFG="-rpi" # arm multi platform (Panda, Wandboard ...) kernel build @@ -435,6 +441,7 @@ buildipfire() { ipfiremake e1000e KCFG="-multi" ipfiremake igb KCFG="-multi" ipfiremake ixgbe KCFG="-multi" + ipfiremake xtables-addons KCFG="-multi" ipfiremake linux-initrd KCFG="-multi" # arm-kirkwood (Dreamplug, ICY-Box ...) kernel build @@ -443,10 +450,11 @@ buildipfire() { ipfiremake e1000e KCFG="-kirkwood" ipfiremake igb KCFG="-kirkwood" ipfiremake ixgbe KCFG="-kirkwood" + ipfiremake xtables-addons KCFG="-kirkwood" ipfiremake linux-initrd KCFG="-kirkwood" ;; esac - ipfiremake pkg-config + ipfiremake xtables-addons USPACE="1" ipfiremake openssl ipfiremake openssl-compat ipfiremake libgpg-error @@ -521,8 +529,6 @@ buildipfire() { ipfiremake mtools ipfiremake initscripts ipfiremake whatmask - ipfiremake libmnl - ipfiremake iptables ipfiremake conntrack-tools ipfiremake libupnp ipfiremake ipaddr From cebb1b7cb1327b87e3fa6932eee151a26a9f85c2 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sat, 3 Jan 2015 20:15:28 +0100 Subject: [PATCH 05/40] general-functions.pl: Add function to get full country name. This function will return the full name a country specified by it's country shortcut. It also will provide some additional names which are not handled by the perl locale module but are parts of ISO 3166. --- config/cfgroot/general-functions.pl | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/config/cfgroot/general-functions.pl b/config/cfgroot/general-functions.pl index 35ae7c093..bd5ad0ac8 100644 --- a/config/cfgroot/general-functions.pl +++ b/config/cfgroot/general-functions.pl @@ -17,6 +17,7 @@ package General; use strict; use Socket; use IO::Socket; +use Locale::Country; use Net::SSLeay; use Net::IPv4Addr qw(:all); $|=1; # line buffering @@ -1123,4 +1124,30 @@ sub get_red_interface() { return $interface; } +# Function to get the county name by a given country code. +sub get_full_country_name($) { + my ($input) = @_; + my $name; + + # Remove whitespaces. + chomp($input); + + # Convert input into lower case format. + my $code = lc($input); + + # Handle country codes which are not in the list. + if ($code eq "a1") { $name = "Anonymous Proxy" } + elsif ($code eq "a2") { $name = "Satellite Provider" } + elsif ($code eq "o1") { $name = "Other Country" } + elsif ($code eq "ap") { $name = "Asia/Pacific Region" } + elsif ($code eq "eu") { $name = "Europe" } + elsif ($code eq "yu") { $name = "Yugoslavia" } + else { + # Use perl built-in module to get the country code. + $name = &Locale::Country::code2country($code); + } + + return $name; +} + 1; From 91634dbe88cc85a77b1b30246e527d3dac908f24 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sat, 3 Jan 2015 20:20:10 +0100 Subject: [PATCH 06/40] geoip-block.cgi: New CGI for managing geoip blocking. --- html/cgi-bin/geoip-block.cgi | 292 +++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 html/cgi-bin/geoip-block.cgi diff --git a/html/cgi-bin/geoip-block.cgi b/html/cgi-bin/geoip-block.cgi new file mode 100644 index 000000000..eb1871919 --- /dev/null +++ b/html/cgi-bin/geoip-block.cgi @@ -0,0 +1,292 @@ +#!/usr/bin/perl +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2014 IPFire Developemnt 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; +# 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"; + +# Directory which contains flag icons. +my $flagdir = "/srv/web/ipfire/html/images/flags"; +# File extension of the country flags. +my $extension = "png"; + +my $settingsfile = "${General::swroot}/firewall/geoipblock"; + +my %color = (); +my %mainsettings = (); +my %settings = (); +my %cgiparams = (); + +# Read configuration file. +&General::readhash("$settingsfile", \%settings); + +&General::readhash("${General::swroot}/main/settings", \%mainsettings); +&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color); + +&Header::showhttpheaders(); + +#Get GUI values +&Header::getcgihash(\%cgiparams); + +# Call subfunction to get all available locations. +my @locations = &get_geoip_locations(); + +if ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) { + # Check if we want to disable geoipblock. + if (exists $cgiparams{'GEOIPBLOCK_ENABLED'}) { + $settings{'GEOIPBLOCK_ENABLED'} = "on"; + } else { + $settings{'GEOIPBLOCK_ENABLED'} = "off"; + } + + # Loop through our locations array to prevent from + # non existing countries or code. + foreach my $cn (@locations) { + # Check if blocking for this country should be enabled/disabled. + if (exists $cgiparams{$cn}) { + $settings{$cn} = "on"; + } else { + $settings{$cn} = "off"; + } + } + + &General::writehash("$settingsfile", \%settings); + +# &General::firewall_config_changed(); +# +# $notice = $Lang::tr{'p2p block save notice'}; +} + +&Header::openpage($Lang::tr{'geoipblock configuration'}, 1, ''); + +# Checkbox pre-selection. +my $checked; +if ($settings{'GEOIPBLOCK_ENABLED'} eq "on") { + $checked = "checked='checked'"; +} + +# Print box to enable/disable geoipblock. +print"
\n"; + +&Header::openbox('100%', 'center', $Lang::tr{'geoipblock'}); +print < + + $Lang::tr{'geoipblock enable feature'} + + + +
+ + + +
+ + + + + +
+END + +&Header::closebox(); + +&Header::openbox('100%', 'center', $Lang::tr{'geoipblock block countries'}); +### JAVA SCRIPT ### +print < + // Function to allow checking all checkboxes at once. + function check_all() { + \$("#countries").find(":checkbox").prop("checked", true); + } + + function uncheck_all() { + \$("#countries").find(":checkbox").prop("checked", false); + } + + + + + + + + + + + + + + + + +END + +my $lines; +my $lines2; +my $col; +foreach my $location (@locations) { + # Country code in upper case. (DE) + my $ccode_uc = $location; + + # County code in lower case. (de) + my $ccode_lc = lc($location); + + # Full name of the country based on the country code. + my $cname = &General::get_full_country_name($ccode_lc); + + # Generate flag filename, based on the lower case written contry code + # and the defined file extension of the image files. (de.png) + my $flagfile = join('.', $ccode_lc,$extension); + + # Generate the full path to the flagfile, based on the given path and + # the previously generated filename. + my $flagpath = join('/', $flagdir,$flagfile); + + my $flag; + # Check if a flag for the country is available. + if (-e "$flagpath") { + $flag="$ccode_uc"; + } else { + $flag="N/A"; + } + + # Checkbox pre-selection. + my $checked; + if ($settings{$ccode_uc} eq "on") { + $checked = "checked='checked'"; + } + + # Colour lines. + if ($lines % 2) { + $col="bgcolor='$color{'color20'}'"; + } else { + $col="bgcolor='$color{'color22'}'"; + } + + # Grouping elements. + my $line_start; + my $line_end; + if ($lines2 % 2) { + # Increase lines (background color by once. + $lines++; + + # Add empty column in front. + $line_start=""; + + # When the line number can be diveded by "2", + # we are going to close the line. + $line_end=""; + } else { + # When the line number is not divideable by "2", + # we are starting a new line. + $line_start=""; + $line_end; + } + + print "$line_start\n"; + print "\n"; + print "\n"; + print "$line_end\n"; + +$lines2++; +} + +print < + +
+ $Lang::tr{'flag'} + + $Lang::tr{'countrycode'} + + $Lang::tr{'country'} +   + $Lang::tr{'flag'} + + $Lang::tr{'countrycode'} + + $Lang::tr{'country'} +
 
$flag$ccode_uc$cname
+ + + + + + +
+ $Lang::tr{'check all'} / + $Lang::tr{'uncheck all'} +
+ +
+ + + + + + + + +
$Lang::tr{'geoipblock country is blocked'}$Lang::tr{'geoipblock country is allowed'}
+END + +&Header::closebox(); +print"\n"; + +&Header::closebigbox(); +&Header::closepage(); + +sub get_geoip_locations() { + # Path to the directory which contains the binary geoip + # databases. + my $directory="/usr/share/xt_geoip/BE"; + + # Array with the final contry codes list. + my @contry_codes; + + # Open location and do a directory listing. + opendir(DIR, "$directory"); + my @locations = readdir(DIR); + closedir(DIR); + + # Loop through the directory listing, and cut of the file extensions. + foreach my $location (sort @locations) { + # skip . and .. + next if($location =~ /^\.$/); + next if($location =~ /^\.\.$/); + + # Remove whitespaces. + chomp($location); + + # Cut-off file extension. + my ($contry_code, $extension) = split(/\./, $location); + + # Add country code to array. + push(@contry_codes, $contry_code); + } + + return @contry_codes; +} From 11ad82532e54fedd2a9b55f5c4a7b2f7a62a2002 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sat, 3 Jan 2015 20:20:45 +0100 Subject: [PATCH 07/40] Language file update for geoip blocking. --- langs/en/cgi-bin/en.pl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index 198640934..3e972ffc0 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -550,6 +550,7 @@ 'chain' => 'Chain', 'change passwords' => 'Change passwords', 'change share' => 'edit share options', +'check all' =>'Check all', 'check for net traffic update' => 'Check for Net-Traffic updates', 'check vpn lr' => 'Check', 'choose config' => 'Choose config', @@ -1191,6 +1192,15 @@ 'generating the root and host certificates may take a long time. it can take up to several minutes on older hardware. please be patient' => 'Generating the root and host certificates may take a long time. It can take up to several minutes on older hardware. Please be patient.', 'genkey' => 'Generate PSK', 'genre' => 'Genre', +'geoipblock' => 'GeoIP based blocking', +'geoipblock block countries' => 'Block countries', +'geoipblock configuration' => 'GeoIP Configuration', +'geoipblock country code' => 'Country Code', +'geoipblock country is allowed' => 'Traffic from this country is allowed', +'geoipblock country is blocked' => 'Traffic from this country will be blocked', +'geoipblock country name' => 'Country Name', +'geoipblock enable feature' => 'Enable GeoIP based blocking:', +'geoipblock flag' => 'Flag', 'global settings' => 'Global Settings', 'gpl i accept these terms and conditions' => 'I accept these terms and conditions', 'gpl license agreement' => 'License Agreement', @@ -2245,6 +2255,7 @@ 'tripwirewarningpolicy' => 'WARNING - Your policy will be rebuild, after that your database will be reinitalised. Therefor the site-key and the local-key are neeeded.', 'tuesday' => 'Tuesday', 'type' => 'Type', +'uncheck all' => 'Uncheck all', 'umount' => 'Umount', 'umount removable media before to unplug' => 'Umount removable media before unplugging the device', 'unable to alter profiles while red is active' => 'Unable to alter profiles while RED is active.', From cc26ba71a193700177d8bc118e79b050964562f7 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sat, 3 Jan 2015 20:22:05 +0100 Subject: [PATCH 08/40] header.pl: Increase maximum allowed size of hashes. The "getcgihash" function only allowed hashes with a maximum size of 512kb, which was to small for the new geoip-block.cgi. As a result of this some form data were cut-off and couldn't be processed correctly. --- config/cfgroot/header.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/cfgroot/header.pl b/config/cfgroot/header.pl index cf895bf24..974c4d8b2 100644 --- a/config/cfgroot/header.pl +++ b/config/cfgroot/header.pl @@ -263,7 +263,7 @@ sub getcgihash { return if ($ENV{'REQUEST_METHOD'} ne 'POST'); if (!$params->{'wantfile'}) { $CGI::DISABLE_UPLOADS = 1; - $CGI::POST_MAX = 512 * 1024; + $CGI::POST_MAX = 1024 * 1024; } else { $CGI::POST_MAX = 10 * 1024 * 1024; } From ca842e182227d69ea70e90e18f5a81d458cf06d3 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 4 Jan 2015 00:54:46 +0100 Subject: [PATCH 09/40] xt_geoip_build: Script to convert GeoIP CSV into compatible binary databases. This is a cleaned up version of the original build script shipped by the xtables-addons source code. The following abilities have been removed: * IPv6 support * Big Endian --- src/scripts/xt_geoip_build | 89 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/scripts/xt_geoip_build diff --git a/src/scripts/xt_geoip_build b/src/scripts/xt_geoip_build new file mode 100644 index 000000000..202156f13 --- /dev/null +++ b/src/scripts/xt_geoip_build @@ -0,0 +1,89 @@ +#!/usr/bin/perl +# +# Converter for MaxMind CSV database to binary, for xt_geoip +# Copyright © Jan Engelhardt, 2008-2011 +# +use Getopt::Long; +use IO::Handle; +use Text::CSV_XS; # or trade for Text::CSV +use strict; + +my $csv = Text::CSV_XS->new({ + allow_whitespace => 1, + binary => 1, + eol => $/, +}); # or Text::CSV +my $target_dir = "."; + +&Getopt::Long::Configure(qw(bundling)); +&GetOptions( + "D=s" => \$target_dir, +); + +if (!-d $target_dir) { + print STDERR "Target directory $target_dir does not exist.\n"; + exit 1; +} + +my $dir = "$target_dir/LE"; +if (!-e $dir && !mkdir($dir)) { + print STDERR "Could not mkdir $dir: $!\n"; + exit 1; +} + +&dump(&collect()); + +sub collect +{ + my %country; + + while (my $row = $csv->getline(*ARGV)) { + if (!defined($country{$row->[4]})) { + $country{$row->[4]} = { + name => $row->[5], + pool_v4 => [], + pool_v6 => [], + }; + } + my $c = $country{$row->[4]}; + + push(@{$c->{pool_v4}}, [$row->[2], $row->[3]]); + + if ($. % 4096 == 0) { + print STDERR "\r\e[2K$. entries"; + } + } + + print STDERR "\r\e[2K$. entries total\n"; + return \%country; +} + +sub dump +{ + my $country = shift @_; + + foreach my $iso_code (sort keys %$country) { + &dump_one($iso_code, $country->{$iso_code}); + } +} + +sub dump_one +{ + my($iso_code, $country) = @_; + my($file, $fh_le, $fh_be); + + printf "%5u IPv4 ranges for %s %s\n", + scalar(@{$country->{pool_v4}}), + $iso_code, $country->{name}; + + $file = "$target_dir/LE/".uc($iso_code).".iv4"; + if (!open($fh_le, "> $file")) { + print STDERR "Error opening $file: $!\n"; + exit 1; + } + foreach my $range (@{$country->{pool_v4}}) { + print $fh_le pack("VV", $range->[0], $range->[1]); + #print $fh_be pack("NN", $range->[0], $range->[1]); + } + close $fh_le; +} From 2285f9da225d245dda6653ce05de9665bd9a792d Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 4 Jan 2015 00:55:17 +0100 Subject: [PATCH 10/40] Add xt_geoip_update script. This script will download the latest available geoip database, convert it into a compatible binary format and move it to the correct destination. --- src/scripts/xt_geoip_update | 118 ++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/scripts/xt_geoip_update diff --git a/src/scripts/xt_geoip_update b/src/scripts/xt_geoip_update new file mode 100644 index 000000000..3ad34d0c6 --- /dev/null +++ b/src/scripts/xt_geoip_update @@ -0,0 +1,118 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2014 IPFire Development 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 . # +# # +############################################################################### + +TMP_PATH=$(mktemp -d) +TMP_FILE=$(mktemp) + +SCRIPT_PATH=/usr/libexec/xtables-addons +DEST_PATH=/usr/share/xt_geoip + +DL_URL=http://geolite.maxmind.com/download/geoip/database +DL_FILE=GeoIPCountryCSV.zip + +CSV_FILE=GeoIPCountryWhois.csv + +ARCH=LE + +function download() { + echo "Downloading latest GeoIP ruleset..." + + # Get the latest GeoIP database from server. + wget $DL_URL/$DL_FILE -O $TMP_PATH/$TMP_FILE + + # Extract files. + unzip $TMP_PATH/$TMP_FILE -d $TMP_PATH + + return 0 +} + +function build() { + echo "Convert database..." + + # Check if the csv file exists. + if [ ! -e $TMP_PATH/$CSV_FILE ]; then + echo "$TMP_PATH/$CSV_FILE not found. Exiting." + return 1 + fi + + # Run script to convert the CSV file into several xtables + # compatible binary files. + if ! $SCRIPT_PATH/xt_geoip_build $TMP_DIR/$CSV_FILE -D $TMP_DIR; then + echo "Could not convert ruleset. Aborting." >&2 + return 1 + fi + + return 0 +} + +function install() { + echo "Install databases..." + + # Check if our destination exist. + if [ ! -e "$DEST_PATH" ]; then + mkdir -p $DEST_PATH &>/dev/null + fi + + # Install databases. + if ! cp -af $TMP_PATH/$ARCH $DEST_PATH &>/dev/null; then + echo "Could not copy files. Aborting." >&2 + return 1 + fi + + return 0 +} + +function cleanup() { + echo "Cleaning up temporary files..." + if ! rm -rf $TMP_PATH &>/dev/null; then + echo "Could not remove files. Aborting." >&2 + return 1 + fi + + return 0 +} + +function main() { + # Download ruleset. + download || exit $? + + # Convert the ruleset. + if ! build; then + # Do cleanup. + cleanup || exit $? + exit 1 + fi + + # Install the converted ruleset. + if ! install; then + # Do cleanup. + cleanup || exit $? + exit 1 + fi + + # Finaly remove temporary files. + cleanup || exit $? + + return 0 +} + +# Run the main function. +main From 484e01fc3791c7cce818c4d578b5e883846b4c51 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 4 Jan 2015 00:56:00 +0100 Subject: [PATCH 11/40] Add default config file for geoipblock. --- config/firewall/geoipblock | 1 + 1 file changed, 1 insertion(+) create mode 100644 config/firewall/geoipblock diff --git a/config/firewall/geoipblock b/config/firewall/geoipblock new file mode 100644 index 000000000..4d483d3b8 --- /dev/null +++ b/config/firewall/geoipblock @@ -0,0 +1 @@ +GEOIPBLOCK_ENABLED=off From cab02e2a5f77eaf0bc12f7c115348baf2a04b699 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 4 Jan 2015 00:57:23 +0100 Subject: [PATCH 12/40] Add "GEOIPBLOCK" chains to firewall initscript. --- src/initscripts/init.d/firewall | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/initscripts/init.d/firewall b/src/initscripts/init.d/firewall index c383652e0..8ca02bc9d 100644 --- a/src/initscripts/init.d/firewall +++ b/src/initscripts/init.d/firewall @@ -179,6 +179,11 @@ iptables_init() { iptables -A OUTPUT -o "${BLUE_DEV}" -j DHCPBLUEOUTPUT fi + # GeoIP block + iptables -N GEOIPBLOCK + iptables -A INPUT -j GEOIPBLOCK + iptables -A FORWARD -j GEOIPBLOCK + # trafic from ipsecX/TUN/TAP interfaces, before "-i GREEN_DEV" accept everything iptables -N IPSECINPUT iptables -N IPSECFORWARD From 593c32275adf2b5bc7a887ad1d14350863ee57e4 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 4 Jan 2015 01:03:21 +0100 Subject: [PATCH 13/40] Move "sub get_geoip_locations" to firewall-lib. --- config/firewall/firewall-lib.pl | 33 +++++++++++++++++++++ html/cgi-bin/geoip-block.cgi | 51 ++++++++++----------------------- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/config/firewall/firewall-lib.pl b/config/firewall/firewall-lib.pl index f3cd67fb0..3fa702f35 100755 --- a/config/firewall/firewall-lib.pl +++ b/config/firewall/firewall-lib.pl @@ -552,4 +552,37 @@ sub get_internal_firewall_ip_address return 0; } +sub get_geoip_locations() { + # Path to the directory which contains the binary geoip + # databases. + my $directory="/usr/share/xt_geoip/LE"; + + # Array to store the final country list. + my @country_codes = (); + + # Open location and do a directory listing. + opendir(DIR, "$directory"); + my @locations = readdir(DIR); + closedir(DIR); + + # Loop through the directory listing, and cut of the file extensions. + foreach my $location (sort @locations) { + # skip . and .. + next if($location =~ /^\.$/); + next if($location =~ /^\.\.$/); + + # Remove whitespaces. + chomp($location); + + # Cut-off file extension. + my ($contry_code, $extension) = split(/\./, $location); + + # Add country code to array. + push(@contry_codes, $contry_code); + } + + # Return final array. + return @country_codes; +} + return 1; diff --git a/html/cgi-bin/geoip-block.cgi b/html/cgi-bin/geoip-block.cgi index eb1871919..f973351cb 100644 --- a/html/cgi-bin/geoip-block.cgi +++ b/html/cgi-bin/geoip-block.cgi @@ -33,6 +33,7 @@ my $flagdir = "/srv/web/ipfire/html/images/flags"; # File extension of the country flags. my $extension = "png"; +my $notice; my $settingsfile = "${General::swroot}/firewall/geoipblock"; my %color = (); @@ -52,7 +53,7 @@ my %cgiparams = (); &Header::getcgihash(\%cgiparams); # Call subfunction to get all available locations. -my @locations = &get_geoip_locations(); +my @locations = &fwlib::get_geoip_locations(); if ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) { # Check if we want to disable geoipblock. @@ -75,13 +76,23 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) { &General::writehash("$settingsfile", \%settings); -# &General::firewall_config_changed(); -# -# $notice = $Lang::tr{'p2p block save notice'}; + # Mark the firewall config as changed. + &General::firewall_config_changed(); + + # Assign reload notice. We directly can use + # the notice from p2p block. + $notice = $Lang::tr{'p2p block save notice'}; } &Header::openpage($Lang::tr{'geoipblock configuration'}, 1, ''); +# Print notice that a firewall reload is required. +if ($notice) { + &Header::openbox('100%', 'left', $Lang::tr{'notice'}); + print "$notice"; + &Header::closebox(); +} + # Checkbox pre-selection. my $checked; if ($settings{'GEOIPBLOCK_ENABLED'} eq "on") { @@ -258,35 +269,3 @@ print"\n"; &Header::closebigbox(); &Header::closepage(); - -sub get_geoip_locations() { - # Path to the directory which contains the binary geoip - # databases. - my $directory="/usr/share/xt_geoip/BE"; - - # Array with the final contry codes list. - my @contry_codes; - - # Open location and do a directory listing. - opendir(DIR, "$directory"); - my @locations = readdir(DIR); - closedir(DIR); - - # Loop through the directory listing, and cut of the file extensions. - foreach my $location (sort @locations) { - # skip . and .. - next if($location =~ /^\.$/); - next if($location =~ /^\.\.$/); - - # Remove whitespaces. - chomp($location); - - # Cut-off file extension. - my ($contry_code, $extension) = split(/\./, $location); - - # Add country code to array. - push(@contry_codes, $contry_code); - } - - return @contry_codes; -} From 211694e588cf65dba21b6f9eb32f1ca7fd4520eb Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 4 Jan 2015 01:05:45 +0100 Subject: [PATCH 14/40] firewall: Add support for geoipblock to rules.pl. --- config/firewall/rules.pl | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) mode change 100755 => 100644 config/firewall/rules.pl diff --git a/config/firewall/rules.pl b/config/firewall/rules.pl old mode 100755 new mode 100644 index 75a9357f6..834e24871 --- a/config/firewall/rules.pl +++ b/config/firewall/rules.pl @@ -60,6 +60,7 @@ my $configfwdfw = "${General::swroot}/firewall/config"; my $configinput = "${General::swroot}/firewall/input"; my $configoutgoing = "${General::swroot}/firewall/outgoing"; my $p2pfile = "${General::swroot}/firewall/p2protocols"; +my $geoipfile = "${General::swroot}/firewall/geoipblock"; my $configgrp = "${General::swroot}/fwhosts/customgroups"; my $netsettings = "${General::swroot}/ethernet/settings"; @@ -94,6 +95,9 @@ sub main { # Load P2P block rules. &p2pblock(); + # Load GeoIP block rules. + &geoipblock(); + # Reload firewall policy. run("/usr/sbin/firewall-policy"); } @@ -570,6 +574,40 @@ sub p2pblock { } } +sub geoipblock { + my %geoipsettings = (); + + # Check if the geoip settings file exists + if (-e "$geoipfile") { + # Read settings file + &General::readhash("$geoipfile", \%geoipsettings); + } else { + # Exit submodule, go on processing the remaining script + return; + } + + # If geoip blocking is not enabled, we are finished here. + if ($geoipsettings{'GEOIPBLOCK_ENABLED'} ne "on") { + # Exit submodule. Process remaining script. + return; + } + + # Get supported locations. + my @locations = &fwlib::get_geoip_locations(); + + # Create iptables chain. + run("$IPTABLES -F GEOIPBLOCK"); + + # Loop through all supported geoip locations and + # create iptables rules, if blocking this country + # is enabled. + foreach my $location (@locations) { + if($geoipsettings{$location} eq "on") { + run("$IPTABLES -A GEOIPBLOCK -m geoip --src-cc $location -j DROP"); + } + } +} + sub get_protocols { my $hash = shift; my $key = shift; From f2d941436b9721cdbfc37f0c7769088d14621d13 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 4 Jan 2015 08:23:53 +0100 Subject: [PATCH 15/40] Rootfile update. --- config/rootfiles/common/Locale-Country | 63 ++++++++++++++++++++------ 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/config/rootfiles/common/Locale-Country b/config/rootfiles/common/Locale-Country index bbe51eee7..0ed312f43 100644 --- a/config/rootfiles/common/Locale-Country +++ b/config/rootfiles/common/Locale-Country @@ -1,13 +1,50 @@ -#usr/lib/perl5/site_perl/5.12.3/Locale -usr/lib/perl5/site_perl/5.12.3/Locale/Constants.pm -usr/lib/perl5/site_perl/5.12.3/Locale/Constants.pod -usr/lib/perl5/site_perl/5.12.3/Locale/Country.pm -usr/lib/perl5/site_perl/5.12.3/Locale/Country.pod -usr/lib/perl5/site_perl/5.12.3/Locale/Currency.pm -usr/lib/perl5/site_perl/5.12.3/Locale/Currency.pod -usr/lib/perl5/site_perl/5.12.3/Locale/Language.pm -usr/lib/perl5/site_perl/5.12.3/Locale/Language.pod -usr/lib/perl5/site_perl/5.12.3/Locale/Script.pm -usr/lib/perl5/site_perl/5.12.3/Locale/Script.pod -#usr/lib/perl5/site_perl/5.12.3/MACHINE-linux-thread-multi/auto/Locale-Codes -#usr/lib/perl5/site_perl/5.12.3/MACHINE-linux-thread-multi/auto/Locale-Codes/.packlist +#usr/lib/perl5/5.12.3/Locale/Codes +usr/lib/perl5/5.12.3/Locale/Codes.pm +usr/lib/perl5/5.12.3/Locale/Codes.pod +usr/lib/perl5/5.12.3/Locale/Codes/API.pod +usr/lib/perl5/5.12.3/Locale/Codes/Changes.pod +usr/lib/perl5/5.12.3/Locale/Codes/Constants.pm +usr/lib/perl5/5.12.3/Locale/Codes/Constants.pod +usr/lib/perl5/5.12.3/Locale/Codes/Country.pm +usr/lib/perl5/5.12.3/Locale/Codes/Country.pod +usr/lib/perl5/5.12.3/Locale/Codes/Country_Codes.pm +usr/lib/perl5/5.12.3/Locale/Codes/Country_Retired.pm +usr/lib/perl5/5.12.3/Locale/Codes/Currency.pm +usr/lib/perl5/5.12.3/Locale/Codes/Currency.pod +usr/lib/perl5/5.12.3/Locale/Codes/Currency_Codes.pm +usr/lib/perl5/5.12.3/Locale/Codes/Currency_Retired.pm +usr/lib/perl5/5.12.3/Locale/Codes/LangExt.pm +usr/lib/perl5/5.12.3/Locale/Codes/LangExt.pod +usr/lib/perl5/5.12.3/Locale/Codes/LangExt_Codes.pm +usr/lib/perl5/5.12.3/Locale/Codes/LangExt_Retired.pm +usr/lib/perl5/5.12.3/Locale/Codes/LangFam.pm +usr/lib/perl5/5.12.3/Locale/Codes/LangFam.pod +usr/lib/perl5/5.12.3/Locale/Codes/LangFam_Codes.pm +usr/lib/perl5/5.12.3/Locale/Codes/LangFam_Retired.pm +usr/lib/perl5/5.12.3/Locale/Codes/LangVar.pm +usr/lib/perl5/5.12.3/Locale/Codes/LangVar.pod +usr/lib/perl5/5.12.3/Locale/Codes/LangVar_Codes.pm +usr/lib/perl5/5.12.3/Locale/Codes/LangVar_Retired.pm +usr/lib/perl5/5.12.3/Locale/Codes/Language.pm +usr/lib/perl5/5.12.3/Locale/Codes/Language.pod +usr/lib/perl5/5.12.3/Locale/Codes/Language_Codes.pm +usr/lib/perl5/5.12.3/Locale/Codes/Language_Retired.pm +usr/lib/perl5/5.12.3/Locale/Codes/Script.pm +usr/lib/perl5/5.12.3/Locale/Codes/Script.pod +usr/lib/perl5/5.12.3/Locale/Codes/Script_Codes.pm +usr/lib/perl5/5.12.3/Locale/Codes/Script_Retired.pm +#usr/lib/perl5/5.12.3/i586-linux-thread-multi/auto/Locale +#usr/lib/perl5/5.12.3/i586-linux-thread-multi/auto/Locale/Codes +#usr/lib/perl5/5.12.3/i586-linux-thread-multi/auto/Locale/Codes/.packlist +#usr/share/man/man3/Locale::Codes.3 +#usr/share/man/man3/Locale::Codes::API.3 +#usr/share/man/man3/Locale::Codes::Changes.3 +#usr/share/man/man3/Locale::Codes::Constants.3 +#usr/share/man/man3/Locale::Codes::Country.3 +#usr/share/man/man3/Locale::Codes::Currency.3 +#usr/share/man/man3/Locale::Codes::LangExt.3 +#usr/share/man/man3/Locale::Codes::LangFam.3 +#usr/share/man/man3/Locale::Codes::LangFam_Retired.3 +#usr/share/man/man3/Locale::Codes::LangVar.3 +#usr/share/man/man3/Locale::Codes::Language.3 +#usr/share/man/man3/Locale::Codes::Script.3 From 58c74d078780b88bf060fa179bd55dd483164b87 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 4 Jan 2015 13:36:06 +0100 Subject: [PATCH 16/40] lfs/stage2: Add directory for geoip databases. --- config/rootfiles/common/stage2 | 1 + lfs/stage2 | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/config/rootfiles/common/stage2 b/config/rootfiles/common/stage2 index eb9704076..cbfde185c 100644 --- a/config/rootfiles/common/stage2 +++ b/config/rootfiles/common/stage2 @@ -136,6 +136,7 @@ usr/share/doc/licenses/GPLv3 #usr/share/man/man8 #usr/share/misc #usr/share/terminfo +#usr/share/xt_geoip #usr/share/zoneinfo run #var diff --git a/lfs/stage2 b/lfs/stage2 index 19d955379..ede9d2bdd 100644 --- a/lfs/stage2 +++ b/lfs/stage2 @@ -55,7 +55,7 @@ $(TARGET) : -install -dv -m 1777 /tmp /var/tmp -mkdir -pv /usr/{,local/}{bin,include,lib{,/sse2},sbin,src} -mkdir -pv /usr/{,local/}share/{doc,info,locale,man} - -mkdir -v /usr/{,local/}share/{misc,terminfo,zoneinfo} + -mkdir -v /usr/{,local/}share/{misc,terminfo,xt_geoip,zoneinfo} -mkdir -pv /usr/{,local/}share/man/man{1..8} #-for dir in /usr /usr/local; do \ # ln -sv share/{man,doc,info} $$dir; \ From 0909c0d15058ddf023369afefab634781cc2702d Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 4 Jan 2015 13:40:34 +0100 Subject: [PATCH 17/40] Automatically download and update GeoIP Databases. --- config/cron/crontab | 3 +++ .../networking/red.up/99-geoip-database | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 src/initscripts/init.d/networking/red.up/99-geoip-database diff --git a/config/cron/crontab b/config/cron/crontab index d78d08f59..54e9b5fee 100644 --- a/config/cron/crontab +++ b/config/cron/crontab @@ -57,3 +57,6 @@ HOME=/ # Re-read firewall rules every Sunday in March, October and November to take care of daylight saving time 00 3 * 3 0 /usr/local/bin/timezone-transition /usr/local/bin/firewallctrl 00 2 * 10-11 0 /usr/local/bin/timezone-transition /usr/local/bin/firewallctrl + +# Update GeoIP database once a month. +3 2 1 * * * [ -f "/var/ipfire/red/active" ] && /usr/local/bin/xt_geoip_update >/dev/null 2>&1 diff --git a/src/initscripts/init.d/networking/red.up/99-geoip-database b/src/initscripts/init.d/networking/red.up/99-geoip-database new file mode 100644 index 000000000..020f2fa2d --- /dev/null +++ b/src/initscripts/init.d/networking/red.up/99-geoip-database @@ -0,0 +1,20 @@ +#!/bin/bash + +# Get the GeoIP database if no one exists yet. + +DIR=/usr/share/xt_geoip + +found=false + +# Check if the directory contains any data. +for i in $DIR/*; do + found=true + break +done + +# Download ruleset if none has been found. +if ! ${found}; then + /us/local/bin/xt_geoip_update >/dev/null 2>&1 +fi + +exit 0 From e497310ee02c7b6f2071bf021f26bc254d97f439 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 4 Jan 2015 13:51:28 +0100 Subject: [PATCH 18/40] Add "GeoIP Block" to firewall menu. --- config/menu/50-firewall.menu | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/menu/50-firewall.menu b/config/menu/50-firewall.menu index e872e6428..7271b3212 100644 --- a/config/menu/50-firewall.menu +++ b/config/menu/50-firewall.menu @@ -22,6 +22,12 @@ 'title' => "P2P-Block", 'enabled' => 1, }; + $subfirewall->{'50.geoipblock'} = { + 'caption' => $Lang::tr{'geoipblock'}, + 'uri' => '/cgi-bin/geoip-block.cgi', + 'title' => $Lang::tr{'geoipblock'}, + 'enabled' => 1, + }; $subfirewall->{'60.wireless'} = { 'caption' => $Lang::tr{'blue access'}, 'uri' => '/cgi-bin/wireless.cgi', From a2b7328a265fb414929d8194b509580054f5c753 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 4 Jan 2015 13:52:29 +0100 Subject: [PATCH 19/40] Language file update. --- langs/en/cgi-bin/en.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index 3e972ffc0..0374c60f9 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -1192,7 +1192,7 @@ 'generating the root and host certificates may take a long time. it can take up to several minutes on older hardware. please be patient' => 'Generating the root and host certificates may take a long time. It can take up to several minutes on older hardware. Please be patient.', 'genkey' => 'Generate PSK', 'genre' => 'Genre', -'geoipblock' => 'GeoIP based blocking', +'geoipblock' => 'GeoIP Block', 'geoipblock block countries' => 'Block countries', 'geoipblock configuration' => 'GeoIP Configuration', 'geoipblock country code' => 'Country Code', From 192a8266e2571a324a793fa512a9c852661ae25b Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 4 Jan 2015 14:07:06 +0100 Subject: [PATCH 20/40] geoip-block.cgi: Requires firewall-lib.pl. --- config/firewall/firewall-lib.pl | 4 ++-- html/cgi-bin/geoip-block.cgi | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/config/firewall/firewall-lib.pl b/config/firewall/firewall-lib.pl index 3fa702f35..f73d84f29 100755 --- a/config/firewall/firewall-lib.pl +++ b/config/firewall/firewall-lib.pl @@ -575,10 +575,10 @@ sub get_geoip_locations() { chomp($location); # Cut-off file extension. - my ($contry_code, $extension) = split(/\./, $location); + my ($country_code, $extension) = split(/\./, $location); # Add country code to array. - push(@contry_codes, $contry_code); + push(@country_codes, $country_code); } # Return final array. diff --git a/html/cgi-bin/geoip-block.cgi b/html/cgi-bin/geoip-block.cgi index f973351cb..6a7d1d96e 100644 --- a/html/cgi-bin/geoip-block.cgi +++ b/html/cgi-bin/geoip-block.cgi @@ -27,6 +27,7 @@ use strict; require '/var/ipfire/general-functions.pl'; require "${General::swroot}/lang.pl"; require "${General::swroot}/header.pl"; +require "/usr/lib/firewall/firewall-lib.pl"; # Directory which contains flag icons. my $flagdir = "/srv/web/ipfire/html/images/flags"; From 4313aa18e9e3b3f6717946b88c8a67f79dea40be Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 8 Feb 2015 13:37:06 +0100 Subject: [PATCH 21/40] fwhosts.cgi: Add support for GeoIP groups. --- html/cgi-bin/fwhosts.cgi | 531 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 530 insertions(+), 1 deletion(-) diff --git a/html/cgi-bin/fwhosts.cgi b/html/cgi-bin/fwhosts.cgi index c3642f0f0..395dca83c 100644 --- a/html/cgi-bin/fwhosts.cgi +++ b/html/cgi-bin/fwhosts.cgi @@ -27,6 +27,8 @@ use Sort::Naturally; use CGI::Carp 'fatalsToBrowser'; no warnings 'uninitialized'; require '/var/ipfire/general-functions.pl'; +require "/var/ipfire/geoip-functions.pl"; +require "/usr/lib/firewall/firewall-lib.pl"; require "${General::swroot}/lang.pl"; require "${General::swroot}/header.pl"; @@ -36,6 +38,7 @@ my %customhost=(); my %customgrp=(); my %customservice=(); my %customservicegrp=(); +my %customgeoipgrp=(); my %ccdnet=(); my %ccdhost=(); my %ipsecconf=(); @@ -62,6 +65,7 @@ my $configccdhost = "${General::swroot}/ovpn/ovpnconfig"; my $configipsec = "${General::swroot}/vpn/config"; my $configsrv = "${General::swroot}/fwhosts/customservices"; my $configsrvgrp = "${General::swroot}/fwhosts/customservicegrp"; +my $configgeoipgrp = "${General::swroot}/fwhosts/customgeoipgrp"; my $fwconfigfwd = "${General::swroot}/firewall/config"; my $fwconfiginp = "${General::swroot}/firewall/input"; my $fwconfigout = "${General::swroot}/firewall/outgoing"; @@ -73,6 +77,7 @@ unless (-e $confighost) { system("touch $confighost"); } unless (-e $configgrp) { system("touch $configgrp"); } unless (-e $configsrv) { system("touch $configsrv"); } unless (-e $configsrvgrp) { system("touch $configsrvgrp"); } +unless (-e $configgeoipgrp) { system("touch $configgeoipgrp"); } &General::readhash("${General::swroot}/main/settings", \%mainsettings); &General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color); @@ -671,6 +676,84 @@ if ($fwhostsettings{'ACTION'} eq 'savegrp') &addgrp; &viewtablegrp; } +if ($fwhostsettings{'ACTION'} eq 'savegeoipgrp') +{ + my $grp=$fwhostsettings{'grp_name'}; + my $rem=$fwhostsettings{'remark'}; + my $count; + my $type; + my @target; + my @newgrp; + &General::readhasharray("$configgeoipgrp", \%customgeoipgrp); + + # Check for existing group name. + if (!&checkgroup($grp) && $fwhostsettings{'update'} ne 'on'){ + $errormessage = $Lang::tr{'fwhost err grpexist'}; + } + + # Check remark. + if ($rem ne '' && !&validremark($rem) && $fwhostsettings{'update'} ne 'on'){ + $errormessage = $Lang::tr{'fwhost err remark'}; + } + + if ($fwhostsettings{'update'} eq 'on'){ + @target=$fwhostsettings{'COUNTRY_CODE'}; + $type='GeoIP Group'; + + #check if host/net exists in grp + my $test="$grp,$fwhostsettings{'oldremark'},@target"; + foreach my $key (keys %customgeoipgrp) { + my $test1="$customgeoipgrp{$key}[0],$customgeoipgrp{$key}[1],$customgeoipgrp{$key}[2]"; + if ($test1 eq $test){ + $errormessage=$Lang::tr{'fwhost err isingrp'}; + $fwhostsettings{'update'} = 'on'; + } + } + } + + if (!$errormessage){ + #on first save, we have an empty @target, so fill it with nothing + my $targetvalues=@target; + if ($targetvalues == '0'){ + @target="none"; + } + #on update, we have to delete the dummy entry + foreach my $key (keys %customgeoipgrp){ + if ($customgeoipgrp{$key}[0] eq $grp && $customgeoipgrp{$key}[2] eq "none"){ + delete $customgeoipgrp{$key}; + last; + } + } + &General::writehasharray("$configgeoipgrp", \%customgeoipgrp); + &General::readhasharray("$configgeoipgrp", \%customgeoipgrp); + #create array with new lines + foreach my $line (@target){ + push (@newgrp,"$grp,$rem,$line"); + } + #append new entries + my $key = &General::findhasharraykey (\%customgeoipgrp); + foreach my $line (@newgrp){ + foreach my $i (0 .. 3) { $customgeoipgrp{$key}[$i] = "";} + my ($a,$b,$c,$d) = split (",",$line); + $customgeoipgrp{$key}[0] = $a; + $customgeoipgrp{$key}[1] = $b; + $customgeoipgrp{$key}[2] = $c; + $customgeoipgrp{$key}[3] = $type; + } + &General::writehasharray("$configgeoipgrp", \%customgeoipgrp); + #update counter in Host/Net + $fwhostsettings{'update'}='on'; + } + #check if ruleupdate is needed + my $geoipgrpcount=0; + $geoipgrpcount=&getgeoipcount($grp); + if($geoipgrpcount > 0 ) + { + &General::firewall_config_changed(); + } + &addgeoipgrp; + &viewtablegeoipgrp; +} if ($fwhostsettings{'ACTION'} eq 'saveservice') { my $ICMP; @@ -798,6 +881,12 @@ if ($fwhostsettings{'ACTION'} eq 'editgrp') &addgrp; &viewtablegrp; } +if ($fwhostsettings{'ACTION'} eq 'editgeoipgrp') +{ + $fwhostsettings{'update'}='on'; + &addgeoipgrp; + &viewtablegeoipgrp; +} if ($fwhostsettings{'ACTION'} eq 'editservice') { $fwhostsettings{'updatesrv'}='on'; @@ -830,6 +919,12 @@ if ($fwhostsettings{'ACTION'} eq 'resetgrp') $fwhostsettings{'remark'} =""; &showmenu; } +if ($fwhostsettings{'ACTION'} eq 'resetgeoipgrp') +{ + $fwhostsettings{'grp_name'} =""; + $fwhostsettings{'remark'} =""; + &showmenu; +} # delete if ($fwhostsettings{'ACTION'} eq 'delnet') { @@ -887,6 +982,37 @@ if ($fwhostsettings{'ACTION'} eq 'deletegrphost') &addgrp; &viewtablegrp; } +if ($fwhostsettings{'ACTION'} eq 'deletegeoipgrpentry') +{ + my $grpremark; + my $grpname; + &General::readhasharray("$configgeoipgrp", \%customgeoipgrp); + foreach my $key (keys %customgeoipgrp){ + if($customgeoipgrp{$key}[0].",".$customgeoipgrp{$key}[1].",".$customgeoipgrp{$key}[2].",".$customgeoipgrp{$key}[3] eq $fwhostsettings{'delentry'}){ + $grpname=$customgeoipgrp{$key}[0]; + $grpremark=$customgeoipgrp{$key}[1]; + #check if we delete the last entry, then generate dummy + if ($fwhostsettings{'last'} eq 'on'){ + $customgeoipgrp{$key}[1] = ''; + $customgeoipgrp{$key}[2] = 'none'; + $customgeoipgrp{$key}[3] = ''; + $fwhostsettings{'last'}=''; + last; + }else{ + delete $customgeoipgrp{$key}; + } + } + } + &General::writehasharray("$configgeoipgrp", \%customgeoipgrp); + &General::firewall_config_changed(); + if ($fwhostsettings{'update'} eq 'on'){ + $fwhostsettings{'remark'}= $grpremark; + $fwhostsettings{'grp_name'}=$grpname; + } + &addgeoipgrp; + &viewtablegeoipgrp; +} + if ($fwhostsettings{'ACTION'} eq 'delgrp') { &General::readhasharray("$configgrp", \%customgrp); @@ -903,6 +1029,22 @@ if ($fwhostsettings{'ACTION'} eq 'delgrp') &addgrp; &viewtablegrp; } +if ($fwhostsettings{'ACTION'} eq 'delgeoipgrp') +{ + &General::readhasharray("$configgeoipgrp", \%customgeoipgrp); + &decrease($fwhostsettings{'grp_name'}); + foreach my $key (sort keys %customgeoipgrp) + { + if($customgeoipgrp{$key}[0] eq $fwhostsettings{'grp_name'}) + { + delete $customgeoipgrp{$key}; + } + } + &General::writehasharray("$configgeoipgrp", \%customgeoipgrp); + $fwhostsettings{'grp_name'}=''; + &addgeoipgrp; + &viewtablegeoipgrp; +} if ($fwhostsettings{'ACTION'} eq 'delservice') { &General::readhasharray("$configsrv", \%customservice); @@ -977,6 +1119,11 @@ if ($fwhostsettings{'ACTION'} eq $Lang::tr{'fwhost newgrp'}) &addgrp; &viewtablegrp; } +if ($fwhostsettings{'ACTION'} eq $Lang::tr{'fwhost newgeoipgrp'}) +{ + &addgeoipgrp; + &viewtablegeoipgrp; +} if ($fwhostsettings{'ACTION'} eq $Lang::tr{'fwhost newservice'}) { &addservice; @@ -1011,6 +1158,31 @@ if ($fwhostsettings{'ACTION'} eq 'changegrpremark') &addgrp; &viewtablegrp; } +if ($fwhostsettings{'ACTION'} eq 'changegeoipgrpremark') +{ + &General::readhasharray("$configgeoipgrp", \%customgeoipgrp); + if ($fwhostsettings{'oldrem'} ne $fwhostsettings{'newrem'} && (&validremark($fwhostsettings{'newrem'}) || $fwhostsettings{'newrem'} eq '')){ + foreach my $key (sort keys %customgeoipgrp) + { + if($customgeoipgrp{$key}[0] eq $fwhostsettings{'grp'} && $customgeoipgrp{$key}[1] eq $fwhostsettings{'oldrem'}) + { + $customgeoipgrp{$key}[1]=''; + $customgeoipgrp{$key}[1]=$fwhostsettings{'newrem'}; + } + } + &General::writehasharray("$configgeoipgrp", \%customgeoipgrp); + $fwhostsettings{'update'}='on'; + $fwhostsettings{'remark'}=$fwhostsettings{'newrem'}; + }else{ + $errormessage=$Lang::tr{'fwhost err remark'}; + $fwhostsettings{'remark'}=$fwhostsettings{'oldrem'}; + $fwhostsettings{'grp_name'}=$fwhostsettings{'grp'}; + $fwhostsettings{'update'} = 'on'; + } + $fwhostsettings{'grp_name'}=$fwhostsettings{'grp'}; + &addgeoipgrp; + &viewtablegeoipgrp; +} if ($fwhostsettings{'ACTION'} eq 'changesrvgrpremark') { &General::readhasharray("$configsrvgrp", \%customservicegrp ); @@ -1085,6 +1257,29 @@ if ($fwhostsettings{'ACTION'} eq 'changegrpname') &addgrp; &viewtablegrp; } +if ($fwhostsettings{'ACTION'} eq 'changegeoipgrpname') +{ + &General::readhasharray("$configgeoipgrp", \%customgeoipgrp ); + if ($fwhostsettings{'oldgrpname'} ne $fwhostsettings{'grp'}){ + #Check new groupname + if (!&validhostname($fwhostsettings{'grp'})){ + $errormessage.=$Lang::tr{'fwhost err name'}."
"; + } + if (!$errormessage){ + # Rename group. + foreach my $key (keys %customgeoipgrp) { + if($customgeoipgrp{$key}[0] eq $fwhostsettings{'oldgrpname'}){ + $customgeoipgrp{$key}[0]=$fwhostsettings{'grp'}; + } + } + &General::writehasharray("$configgeoipgrp", \%customgeoipgrp ); + #change name in FW Rules + &changenameinfw($fwhostsettings{'oldgrpname'},$fwhostsettings{'grp'},6); + } + } + &addgeoipgrp; + &viewtablegeoipgrp; +} ### VIEW ### if($fwhostsettings{'ACTION'} eq '') { @@ -1096,7 +1291,7 @@ sub showmenu { print "$Lang::tr{'fwhost welcome'}"; print<
- +
END @@ -1381,6 +1576,113 @@ END print"
"; &Header::closebox(); } +sub addgeoipgrp +{ + &hint; + &error; + &showmenu; + &Header::openbox('100%', 'left', $Lang::tr{'fwhost addgeoipgrp'}); + + my %checked=(); + my $show=''; + $checked{'check1'}{'off'} = ''; + $checked{'check1'}{'on'} = ''; + $checked{'grp2'}{$fwhostsettings{'grp2'}} = 'CHECKED'; + $fwhostsettings{'oldremark'}=$fwhostsettings{'remark'}; + $fwhostsettings{'oldgrpname'}=$fwhostsettings{'grp_name'}; + my $grp=$fwhostsettings{'grp_name'}; + my $rem=$fwhostsettings{'remark'}; + if ($fwhostsettings{'update'} eq ''){ + print< + + $Lang::tr{'fwhost addgrpname'} +
+ + + $Lang::tr{'remark'}: + + + +
+ + +END + } else { + print< + + $Lang::tr{'fwhost addgrpname'} + + + + + + + + +
+ $Lang::tr{'remark'}: + + + + + + + + + +
+ +

+END + } + if ($fwhostsettings{'update'} eq 'on') { + my @geoip_locations = &fwlib::get_geoip_locations(); + + print< + + + + + + + +
+
+

+END + } + print < + + + + + + + +
+ + + + +
+ +END + &Header::closebox(); +} sub addservice { &error; @@ -1838,6 +2140,195 @@ sub viewtablegrp &Header::closebox(); } +} +sub viewtablegeoipgrp +{ + # If our filesize is "zero" there is nothing to read-in. + if (-z "$configgeoipgrp") { + return; + } + + &Header::openbox('100%', 'left', $Lang::tr{'fwhost cust geoipgrp'}); + &General::readhasharray("$configgeoipgrp", \%customgeoipgrp); + &General::readhasharray("$fwconfigfwd", \%fwfwd); + &General::readhasharray("$fwconfiginp", \%fwinp); + &General::readhasharray("$fwconfigout", \%fwout); + my @grp=(); + my $helper=''; + my $count=1; + my $country_code; + my $grpname; + my $remark; + my $number; + my $delflag; + my @counter; + my %hash; + + # If there are no groups we are finished here. + if (!keys %customgeoipgrp) { + print "
$Lang::tr{'fwhost err emptytable'}"; + return; + } + + # Put all groups in a hash. + foreach my $key (sort { ncmp($customgeoipgrp{$a}[0],$customgeoipgrp{$b}[0]) } + sort { ncmp($customgeoipgrp{$a}[2],$customgeoipgrp{$b}[2]) } keys %customgeoipgrp) { + push (@counter,$customgeoipgrp{$key}[0]); + } + + # Increase current used key. + foreach my $key1 (@counter) { + $hash{$key1}++ ; + } + + # Sort hash. + foreach my $key (sort { ncmp($customgeoipgrp{$a}[0],$customgeoipgrp{$b}[0]) } + sort { ncmp($customgeoipgrp{$a}[2],$customgeoipgrp{$b}[2]) } keys %customgeoipgrp) { + $count++; + if ($helper ne $customgeoipgrp{$key}[0]) { + $delflag='0'; + + foreach my $key1 (sort { ncmp($customgeoipgrp{$a}[0],$customgeoipgrp{$b}[0]) } + sort { ncmp($customgeoipgrp{$a}[2],$customgeoipgrp{$b}[2]) } keys %customgeoipgrp) { + + if ($customgeoipgrp{$key}[0] eq $customgeoipgrp{$key1}[0]) + { + $delflag++; + } + if($delflag > 1){ + last; + } + } + + $number=1; + + # Groupname. + $grpname=$customgeoipgrp{$key}[0]; + + # Group remark. + $remark="$customgeoipgrp{$key}[1]"; + + # Country code. + $country_code="$customgeoipgrp{$key}[2]"; + + if ($count gt 1){ + print""; + $count=1; + } + + # Display groups header. + print "
$grpname   \n"; + print "$Lang::tr{'remark'}:  $remark  \n" if ($remark ne ''); + + # Get group count. + my $geoipgrpcount=&getgeoipcount($grpname); + print "$Lang::tr{'used'}: $geoipgrpcount x"; + + # Only display delete icon, if the group is not used by a firewall rule. + if($geoipgrpcount == '0') { + print"
\n"; + print"\n"; + print"\n"; + print"\n"; + print"
"; + } + + # Icon for group editing. +print < + + + + + + + +END + # Display headlines if the group contains any entries. + if ($country_code ne "none") { +print < + + + + + + + + +END + } + } + + # Check if our group contains any entries. + if ($country_code eq "none") { + print "\n"; + } else { + # Check if we are currently editing a group and assign column backgound colors. + my $col=''; + if ( ($fwhostsettings{'ACTION'} eq 'editgeoipgrp' || $fwhostsettings{'update'} ne '') + && $fwhostsettings{'grp_name'} eq $customgeoipgrp{$key}[0]) { + $col="bgcolor='${Header::colouryellow}'"; + } elsif ($count %2 == 0){ + $col="bgcolor='$color{'color20'}'"; + } else { + $col="bgcolor='$color{'color22'}'"; + } + + # Get country flag. + my $icon = &GeoIP::get_flag_icon($customgeoipgrp{$key}[2]); + + # Print column with flag icon. + my $col_content; + if ($icon) { + $col_content = "$customgeoipgrp{$key}[2]"; + } else { + $col_content = "N/A"; + } + + print "\n"; + + # Print column with country code. + print "\n"; + + # Print column with full country name. + my $country_name = &GeoIP::get_full_country_name($customgeoipgrp{$key}[2]); + print "\n"; + + # Generate from for removing entries from a group. + print "\n"; + print "\n"; + } + + $helper=$customgeoipgrp{$key}[0]; + $number++; + } + + print"
+ $Lang::tr{'flag'} + + $Lang::tr{'countrycode'} + + $Lang::tr{'country'} +
$Lang::tr{'fwhost err emptytable'}
$col_content$customgeoipgrp{$key}[2]$country_name
\n"; + + if ($delflag > 0){ + print"\n"; + + # Check if this group only has a single entry. + foreach my $key2 (keys %hash) { + if ($hash{$key2}<2 && $key2 eq $customgeoipgrp{$key}[0]){ + print "" ; + } + } + } + + print "\n"; + print "\n"; + print "\n"; + print "
\n"; + print "
\n"; + &Header::closebox(); } sub viewtableservice { @@ -2196,6 +2687,44 @@ sub gethostcount } return $srvcounter; } +sub getgeoipcount +{ + my $groupname=shift; + my $counter=0; + + # GeoIP groups are stored as "group:groupname" in the + # firewall settings files. + my $searchstring = join(':', "group",$groupname); + + # Count services used in firewall - forward + foreach my $key1 (keys %fwfwd) { + if($fwfwd{$key1}[4] eq $searchstring){ + $counter++; + } + if($fwfwd{$key1}[6] eq $searchstring){ + $counter++; + } + } + #Count services used in firewall - input + foreach my $key2 (keys %fwinp) { + if($fwinp{$key2}[4] eq $searchstring){ + $counter++; + } + if($fwinp{$key2}[6] eq $searchstring){ + $counter++; + } + } + #Count services used in firewall - outgoing + foreach my $key3 (keys %fwout) { + if($fwout{$key3}[4] eq $searchstring){ + $counter++; + } + if($fwout{$key3}[6] eq $searchstring){ + $counter++; + } + } + return $counter; +} sub getnetcount { my $searchstring=shift; From 1dcd87157d4b52ee304094a586674dcb4919c3ba Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 8 Feb 2015 18:23:01 +0100 Subject: [PATCH 22/40] geoip-functions.pl: A collection of functions dealing with GeoIP. --- config/cfgroot/general-functions.pl | 26 --------- config/cfgroot/geoip-functions.pl | 90 +++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 26 deletions(-) create mode 100644 config/cfgroot/geoip-functions.pl diff --git a/config/cfgroot/general-functions.pl b/config/cfgroot/general-functions.pl index bd5ad0ac8..29f7e8c6b 100644 --- a/config/cfgroot/general-functions.pl +++ b/config/cfgroot/general-functions.pl @@ -1124,30 +1124,4 @@ sub get_red_interface() { return $interface; } -# Function to get the county name by a given country code. -sub get_full_country_name($) { - my ($input) = @_; - my $name; - - # Remove whitespaces. - chomp($input); - - # Convert input into lower case format. - my $code = lc($input); - - # Handle country codes which are not in the list. - if ($code eq "a1") { $name = "Anonymous Proxy" } - elsif ($code eq "a2") { $name = "Satellite Provider" } - elsif ($code eq "o1") { $name = "Other Country" } - elsif ($code eq "ap") { $name = "Asia/Pacific Region" } - elsif ($code eq "eu") { $name = "Europe" } - elsif ($code eq "yu") { $name = "Yugoslavia" } - else { - # Use perl built-in module to get the country code. - $name = &Locale::Country::code2country($code); - } - - return $name; -} - 1; diff --git a/config/cfgroot/geoip-functions.pl b/config/cfgroot/geoip-functions.pl new file mode 100644 index 000000000..68b6f503d --- /dev/null +++ b/config/cfgroot/geoip-functions.pl @@ -0,0 +1,90 @@ +#!/usr/bin/perl -w +############################################################################ +# # +# This file is part of the IPFire Firewall. # +# # +# IPFire 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 2 of the License, or # +# (at your option) any later version. # +# # +# IPFire 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 IPFire; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +# # +# Copyright (C) 2015 IPFire Team . # +# # +############################################################################ + +package GeoIP; + +use Locale::Country; + +# Function to get the flag icon for a specified country code. +sub get_flag_icon($) { + my ($input) = @_; + + # Webserver's root dir. (Required for generating full path) + my $webroot = "/srv/web/ipfire/html"; + + # Directory which contains the flag icons. + my $flagdir = "/images/flags"; + + # File extension of the country flags. + my $ext = "png"; + + # Remove whitespaces. + chomp($input); + + # Convert given country code to lower case. + my $ccode = lc($input); + + # Generate filename, based on the contry code in lower case + # and the defined file extension. + my $file = join('.', $ccode,$ext); + + # Generate path inside webroot to the previously generated file. + my $flag_icon = join('/', $flagdir,$file); + + # Generate absolute path to the icon file. + my $absolute_path = join('', $webroot,$flag_icon); + + # Check if the a icon file exists. + if (-e "$absolute_path") { + # Return content of flag_icon. + return $flag_icon; + } +} + +# Function to get the county name by a given country code. +sub get_full_country_name($) { + my ($input) = @_; + my $name; + + # Remove whitespaces. + chomp($input); + + # Convert input into lower case format. + my $code = lc($input); + + # Handle country codes which are not in the list. + if ($code eq "a1") { $name = "Anonymous Proxy" } + elsif ($code eq "a2") { $name = "Satellite Provider" } + elsif ($code eq "o1") { $name = "Other Country" } + elsif ($code eq "ap") { $name = "Asia/Pacific Region" } + elsif ($code eq "eu") { $name = "Europe" } + elsif ($code eq "yu") { $name = "Yugoslavia" } + else { + # Use perl built-in module to get the country code. + $name = &Locale::Country::code2country($code); + } + + return $name; +} + +1; From e472a10de91406b6440add5245de388cb4ab34f5 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 8 Feb 2015 18:24:51 +0100 Subject: [PATCH 23/40] geoip-block.cgi: Use geoip-functions.pl. --- html/cgi-bin/geoip-block.cgi | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/html/cgi-bin/geoip-block.cgi b/html/cgi-bin/geoip-block.cgi index 6a7d1d96e..ccbfa926a 100644 --- a/html/cgi-bin/geoip-block.cgi +++ b/html/cgi-bin/geoip-block.cgi @@ -25,15 +25,11 @@ use strict; #use CGI::Carp 'fatalsToBrowser'; require '/var/ipfire/general-functions.pl'; +require "${General::swroot}/geoip-functions.pl"; require "${General::swroot}/lang.pl"; require "${General::swroot}/header.pl"; require "/usr/lib/firewall/firewall-lib.pl"; -# Directory which contains flag icons. -my $flagdir = "/srv/web/ipfire/html/images/flags"; -# File extension of the country flags. -my $extension = "png"; - my $notice; my $settingsfile = "${General::swroot}/firewall/geoipblock"; @@ -179,20 +175,15 @@ foreach my $location (@locations) { my $ccode_lc = lc($location); # Full name of the country based on the country code. - my $cname = &General::get_full_country_name($ccode_lc); + my $cname = &GeoIP::get_full_country_name($ccode_lc); - # Generate flag filename, based on the lower case written contry code - # and the defined file extension of the image files. (de.png) - my $flagfile = join('.', $ccode_lc,$extension); - - # Generate the full path to the flagfile, based on the given path and - # the previously generated filename. - my $flagpath = join('/', $flagdir,$flagfile); + # Get flag icon for of the country. + my $flag_icon = &GeoIP::get_flag_icon($ccode_uc); my $flag; # Check if a flag for the country is available. - if (-e "$flagpath") { - $flag="$ccode_uc"; + if ($flag_icon) { + $flag="$ccode_uc"; } else { $flag="N/A"; } From c0a97a0f4a9c7787801015301a34a01da39596f5 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 8 Feb 2015 18:41:44 +0100 Subject: [PATCH 24/40] firewall.cgi: Add support for GeoIP locations / GeoIP groups. --- html/cgi-bin/firewall.cgi | 67 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/html/cgi-bin/firewall.cgi b/html/cgi-bin/firewall.cgi index badee6b3c..12152700f 100644 --- a/html/cgi-bin/firewall.cgi +++ b/html/cgi-bin/firewall.cgi @@ -33,6 +33,7 @@ no warnings 'uninitialized'; require '/var/ipfire/general-functions.pl'; require "${General::swroot}/lang.pl"; require "${General::swroot}/header.pl"; +require "${General::swroot}/geoip-functions.pl"; require "/usr/lib/firewall/firewall-lib.pl"; unless (-d "${General::swroot}/firewall") { system("mkdir ${General::swroot}/firewall"); } @@ -47,6 +48,7 @@ my %defaultNetworks=(); my %netsettings=(); my %customhost=(); my %customgrp=(); +my %customgeoipgrp=(); my %customnetworks=(); my %customservice=(); my %customservicegrp=(); @@ -73,6 +75,7 @@ my $color; my $confignet = "${General::swroot}/fwhosts/customnetworks"; my $confighost = "${General::swroot}/fwhosts/customhosts"; my $configgrp = "${General::swroot}/fwhosts/customgroups"; +my $configgeoipgrp = "${General::swroot}/fwhosts/customgeoipgrp"; my $configsrv = "${General::swroot}/fwhosts/customservices"; my $configsrvgrp = "${General::swroot}/fwhosts/customservicegrp"; my $configccdnet = "${General::swroot}/ovpn/ccd.conf"; @@ -1135,6 +1138,54 @@ END } print""; } + # geoip locations / groups. + my @geoip_locations = &fwlib::get_geoip_locations(); + + print "\n"; + print "\n"; + print "$Lang::tr{'geoip'}\n"; + print "\n"; + #End left table. start right table (vpn) print""; # CCD networks @@ -1472,6 +1523,7 @@ sub newrule &General::readhasharray("$confighost", \%customhost); &General::readhasharray("$configccdhost", \%ccdhost); &General::readhasharray("$configgrp", \%customgrp); + &General::readhasharray("$configgeoipgrp", \%customgeoipgrp); &General::readhasharray("$configipsec", \%ipsecconf); &General::get_aliases(\%aliases); my %checked=(); @@ -2600,6 +2652,13 @@ END }else{ print $$hash{$key}[4]; } + }elsif ($$hash{$key}[3] eq 'cust_geoip_src') { + my ($split1,$split2) = split(":", $$hash{$key}[4]); + if ($split2) { + print "$split2\n"; + }else{ + print "$Lang::tr{'geoip'}: $$hash{$key}[4]\n"; + } }elsif ($$hash{$key}[4] eq 'RED1'){ print "$ipfireiface $Lang::tr{'fwdfw red'}"; }elsif ($$hash{$key}[4] eq 'ALL'){ @@ -2676,6 +2735,13 @@ END }else{ print $$hash{$key}[6]; } + }elsif ($$hash{$key}[5] eq 'cust_geoip_tgt') { + my ($split1,$split2) = split(":", $$hash{$key}[6]); + if ($split2) { + print "$split2\n"; + }else{ + print "$Lang::tr{'geoip'}: $$hash{$key}[6]\n"; + } }elsif ($$hash{$key}[5] eq 'tgt_addr'){ my ($split1,$split2) = split("/",$$hash{$key}[6]); if ($split2 eq '32'){ @@ -2693,7 +2759,6 @@ END #RULE ACTIVE if($$hash{$key}[2] eq 'ON'){ $gif="/images/on.gif" - }else{ $gif="/images/off.gif" } From d9bf6d8b2f195e8d1f0287af19cf9fed331e9377 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Thu, 12 Feb 2015 20:10:05 +0100 Subject: [PATCH 25/40] Language file update. --- langs/en/cgi-bin/en.pl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index 0374c60f9..fa014a92f 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -435,6 +435,7 @@ 'bit' => 'bit', 'bitrate' => 'Bitrate', 'bleeding rules' => 'Bleeding Edge Snort Rules', +'block' => 'Block', 'blue' => 'BLUE', 'blue access' => 'Blue Access', 'blue access use hint' => 'You have to enter the MAC or the IP Address for a device. To enter both is also possible', @@ -1095,6 +1096,7 @@ 'fwhost OpenVPN static host' => 'OpenVPN static host', 'fwhost OpenVPN static network' => 'OpenVPN static network', 'fwhost Standard Network' => 'Standard network', +'fwhost addgeoipgrp' => 'Add new GeoIP group', 'fwhost addgrp' => 'Add new network/host group', 'fwhost addgrpname' => 'Group name:', 'fwhost addhost' => 'Add new host', @@ -1110,6 +1112,9 @@ 'fwhost change' => 'Modify', 'fwhost changeremark' => 'You modified just the remark', 'fwhost cust addr' => 'Hosts', +'fwhost cust geoip' => 'GeoIP Groups', +'fwhost cust geoipgroup' => 'GeoIP Groups', +'fwhost cust geoiplocation' => 'GeoIP Locations', 'fwhost cust grp' => 'Network/Host Groups', 'fwhost cust net' => 'Networks', 'fwhost cust service' => 'Services', @@ -1156,6 +1161,7 @@ 'fwhost ipsec net' => 'IPsec networks:', 'fwhost menu' => 'Firewall Groups', 'fwhost netaddress' => 'Network address', +'fwhost newgeoipgrp' => 'GeoIP Groups', 'fwhost newgrp' => 'Network/Host Groups', 'fwhost newhost' => 'Hosts', 'fwhost newnet' => 'Networks', @@ -1192,6 +1198,7 @@ 'generating the root and host certificates may take a long time. it can take up to several minutes on older hardware. please be patient' => 'Generating the root and host certificates may take a long time. It can take up to several minutes on older hardware. Please be patient.', 'genkey' => 'Generate PSK', 'genre' => 'Genre', +'geoip' => 'GeoIP', 'geoipblock' => 'GeoIP Block', 'geoipblock block countries' => 'Block countries', 'geoipblock configuration' => 'GeoIP Configuration', @@ -2255,11 +2262,13 @@ 'tripwirewarningpolicy' => 'WARNING - Your policy will be rebuild, after that your database will be reinitalised. Therefor the site-key and the local-key are neeeded.', 'tuesday' => 'Tuesday', 'type' => 'Type', -'uncheck all' => 'Uncheck all', 'umount' => 'Umount', 'umount removable media before to unplug' => 'Umount removable media before unplugging the device', +'uncheck all' => 'Uncheck all', 'unable to alter profiles while red is active' => 'Unable to alter profiles while RED is active.', 'unable to contact' => 'Unable to contact', +'unblock' => 'Unblock', +'unblock all' => 'Unblock all', 'unencrypted' => 'Unencrypted', 'uninstall' => 'Uninstall', 'unix charset' => 'UNIX Charset', From 2e3cb8edbc9f203adf6d702cfddf465ccaf2e2d7 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sat, 14 Feb 2015 19:18:27 +0100 Subject: [PATCH 26/40] stage2: Rootfile update. --- config/rootfiles/common/stage2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/rootfiles/common/stage2 b/config/rootfiles/common/stage2 index 4e8b750c8..6c9325fd1 100644 --- a/config/rootfiles/common/stage2 +++ b/config/rootfiles/common/stage2 @@ -103,6 +103,8 @@ usr/local/bin/timecheck usr/local/bin/timezone-transition usr/local/bin/update-bootloader usr/local/bin/update-lang-cache +usr/local/bin/xt_geoip_build +usr/local/bin/xt_geoip_update #usr/local/include #usr/local/lib #usr/local/lib/sse2 @@ -122,6 +124,7 @@ usr/local/bin/update-lang-cache #usr/local/share/man/man8 #usr/local/share/misc #usr/local/share/terminfo +#usr/local/share/xt_geoip #usr/local/share/zoneinfo #usr/local/src #usr/sbin From 6897c329b5b323567267d364fefdf01a9bff5688 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Tue, 17 Feb 2015 08:41:16 +0100 Subject: [PATCH 27/40] xt_geoip_update: Fix mktemp calls. --- src/scripts/xt_geoip_update | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/scripts/xt_geoip_update b/src/scripts/xt_geoip_update index 3ad34d0c6..294af58e0 100644 --- a/src/scripts/xt_geoip_update +++ b/src/scripts/xt_geoip_update @@ -20,7 +20,7 @@ ############################################################################### TMP_PATH=$(mktemp -d) -TMP_FILE=$(mktemp) +TMP_FILE=$(mktemp -p $TMP_PATH) SCRIPT_PATH=/usr/libexec/xtables-addons DEST_PATH=/usr/share/xt_geoip @@ -35,11 +35,14 @@ ARCH=LE function download() { echo "Downloading latest GeoIP ruleset..." + # Create temporary directory. + mkdir -pv $TMP_PATH + # Get the latest GeoIP database from server. - wget $DL_URL/$DL_FILE -O $TMP_PATH/$TMP_FILE + wget $DL_URL/$DL_FILE -O $TMP_FILE # Extract files. - unzip $TMP_PATH/$TMP_FILE -d $TMP_PATH + unzip $TMP_FILE -d $TMP_PATH return 0 } @@ -55,7 +58,7 @@ function build() { # Run script to convert the CSV file into several xtables # compatible binary files. - if ! $SCRIPT_PATH/xt_geoip_build $TMP_DIR/$CSV_FILE -D $TMP_DIR; then + if ! $SCRIPT_PATH/xt_geoip_build $TMP_PATH/$CSV_FILE -D $TMP_PATH; then echo "Could not convert ruleset. Aborting." >&2 return 1 fi From b9ca2fa60f1ac0127d0bbddb016d0acb578e660d Mon Sep 17 00:00:00 2001 From: Alexander Marx Date: Tue, 17 Feb 2015 17:01:42 +0100 Subject: [PATCH 28/40] Add support for generating GeoIP-based firewall rules. This commit adds support to the rules.pl and firewall-lib.pl to generate correct iptables commands for inserting GeoIP-based firewall rules into the kernel. --- config/firewall/firewall-lib.pl | 28 ++++++++++++++++++++++++++++ config/firewall/rules.pl | 8 ++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) mode change 100755 => 100644 config/firewall/firewall-lib.pl diff --git a/config/firewall/firewall-lib.pl b/config/firewall/firewall-lib.pl old mode 100755 new mode 100644 index f73d84f29..b389fac3c --- a/config/firewall/firewall-lib.pl +++ b/config/firewall/firewall-lib.pl @@ -27,6 +27,7 @@ package fwlib; my %customnetwork=(); my %customhost=(); my %customgrp=(); +my %customgeoipgrp=(); my %customservice=(); my %customservicegrp=(); my %ccdnet=(); @@ -42,6 +43,7 @@ require '/var/ipfire/general-functions.pl'; my $confignet = "${General::swroot}/fwhosts/customnetworks"; my $confighost = "${General::swroot}/fwhosts/customhosts"; my $configgrp = "${General::swroot}/fwhosts/customgroups"; +my $configgeoipgrp = "${General::swroot}/fwhosts/customgeoipgrp"; my $configsrv = "${General::swroot}/fwhosts/customservices"; my $configsrvgrp = "${General::swroot}/fwhosts/customservicegrp"; my $configccdnet = "${General::swroot}/ovpn/ccd.conf"; @@ -59,6 +61,7 @@ my $netsettings = "${General::swroot}/ethernet/settings"; &General::readhasharray("$confignet", \%customnetwork); &General::readhasharray("$confighost", \%customhost); &General::readhasharray("$configgrp", \%customgrp); +&General::readhasharray("$configgeoipgrp", \%customgeoipgrp); &General::readhasharray("$configccdnet", \%ccdnet); &General::readhasharray("$configccdhost", \%ccdhost); &General::readhasharray("$configipsec", \%ipsecconf); @@ -295,6 +298,17 @@ sub get_addresses if ($customgrp{$grp}[0] eq $value) { my @address = &get_address($customgrp{$grp}[3], $customgrp{$grp}[2], $type); + if (@address) { + push(@addresses, @address); + } + } + } + }elsif ($addr_type ~~ ["cust_geoip_src", "cust_geoip_tgt"] && $value =~ "group:") { + $value=substr($value,6); + foreach my $grp (sort {$a <=> $b} keys %customgeoipgrp) { + if ($customgeoipgrp{$grp}[0] eq $value) { + my @address = &get_address($addr_type, $customgeoipgrp{$grp}[2], $type); + if (@address) { push(@addresses, @address); } @@ -414,6 +428,20 @@ sub get_address } } + # Handle rule options with GeoIP as source. + } elsif ($key eq "cust_geoip_src") { + # Get external interface. + my $external_interface = &get_external_interface(); + + push(@ret, ["-m geoip --src-cc $value", "$external_interface"]); + + # Handle rule options with GeoIP as target. + } elsif ($key eq "cust_geoip_tgt") { + # Get external interface. + my $external_interface = &get_external_interface(); + + push(@ret, ["-m geoip --dst-cc $value", "$external_interface"]); + # If nothing was selected, we assume "any". } else { push(@ret, ["0/0", ""]); diff --git a/config/firewall/rules.pl b/config/firewall/rules.pl index cd2f3a635..a12ab5667 100644 --- a/config/firewall/rules.pl +++ b/config/firewall/rules.pl @@ -368,13 +368,17 @@ sub buildrules { my @source_options = (); if ($source =~ /mac/) { push(@source_options, $source); - } elsif ($source) { + } elsif ($source =~ /-m geoip/) { + push(@source_options, $source); + } elsif($source) { push(@source_options, ("-s", $source)); } # Prepare destination options. my @destination_options = (); - if ($destination) { + if ($destination =~ /-m geoip/) { + push(@destination_options, $destination); + } elsif ($destination) { push(@destination_options, ("-d", $destination)); } From 16bbdeb988cec0e4af25a0be334e23842ad9414a Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sat, 7 Mar 2015 21:30:19 +0100 Subject: [PATCH 29/40] networking/red.up/99-geoip-database: Fix typo. --- src/initscripts/init.d/networking/red.up/99-geoip-database | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/initscripts/init.d/networking/red.up/99-geoip-database b/src/initscripts/init.d/networking/red.up/99-geoip-database index 020f2fa2d..c79eda15d 100644 --- a/src/initscripts/init.d/networking/red.up/99-geoip-database +++ b/src/initscripts/init.d/networking/red.up/99-geoip-database @@ -14,7 +14,7 @@ done # Download ruleset if none has been found. if ! ${found}; then - /us/local/bin/xt_geoip_update >/dev/null 2>&1 + /usr/local/bin/xt_geoip_update >/dev/null 2>&1 fi exit 0 From 663221a256af64d3bfe8c9bc0fe534059eb7dcee Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sat, 7 Mar 2015 21:31:27 +0100 Subject: [PATCH 30/40] xt_geoip_update: Fix script path. --- src/scripts/xt_geoip_update | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scripts/xt_geoip_update b/src/scripts/xt_geoip_update index 294af58e0..42e214366 100644 --- a/src/scripts/xt_geoip_update +++ b/src/scripts/xt_geoip_update @@ -22,7 +22,7 @@ TMP_PATH=$(mktemp -d) TMP_FILE=$(mktemp -p $TMP_PATH) -SCRIPT_PATH=/usr/libexec/xtables-addons +SCRIPT_PATH=/usr/local/bin DEST_PATH=/usr/share/xt_geoip DL_URL=http://geolite.maxmind.com/download/geoip/database From e24668f99a053d2073de80fe2d0dc8c5d73d2cbc Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sat, 7 Mar 2015 22:39:32 +0100 Subject: [PATCH 31/40] networking/red.up/99-geoip-database: Fix empty folder check. --- .../init.d/networking/red.up/99-geoip-database | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/initscripts/init.d/networking/red.up/99-geoip-database b/src/initscripts/init.d/networking/red.up/99-geoip-database index c79eda15d..4bd3ee2ab 100644 --- a/src/initscripts/init.d/networking/red.up/99-geoip-database +++ b/src/initscripts/init.d/networking/red.up/99-geoip-database @@ -2,14 +2,17 @@ # Get the GeoIP database if no one exists yet. -DIR=/usr/share/xt_geoip +DIR="/usr/share/xt_geoip/*" found=false # Check if the directory contains any data. -for i in $DIR/*; do - found=true - break +for i in $DIR; do + # Ignore "." and ".." + if [ -d "$i" ]; then + found=true + break + fi done # Download ruleset if none has been found. From 0bb4b135d121cec8efbae6c63b3ea6cf85eacb97 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 8 Mar 2015 10:09:16 +0100 Subject: [PATCH 32/40] rules.pl: Flush GEOIPBLOCK chain when the feature will be switched off. Otherwise existing rules still remain in the chain and will be processed even geoipblock has been disabled. --- config/firewall/rules.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/config/firewall/rules.pl b/config/firewall/rules.pl index fa7edee1b..535899611 100644 --- a/config/firewall/rules.pl +++ b/config/firewall/rules.pl @@ -586,6 +586,9 @@ sub geoipblock { # Read settings file &General::readhash("$geoipfile", \%geoipsettings); } else { + # Drop active rules. + run("$IPTABLES -F GEOIPBLOCK"); + # Exit submodule, go on processing the remaining script return; } @@ -599,7 +602,7 @@ sub geoipblock { # Get supported locations. my @locations = &fwlib::get_geoip_locations(); - # Create iptables chain. + # Flush iptables chain. run("$IPTABLES -F GEOIPBLOCK"); # Loop through all supported geoip locations and From 1ed8aedfdb9af8deaafac797b85b68c407feb6d7 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 15 Mar 2015 11:41:50 +0100 Subject: [PATCH 33/40] fwhosts.cgi: Fix fw-reload detection when adding new entries to a geoip group. Read-in firewall config files for detection if the current group is used by at least one firewall rule and mark the firewall to need a reload if neccessary. Fixes #10771. --- html/cgi-bin/fwhosts.cgi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/html/cgi-bin/fwhosts.cgi b/html/cgi-bin/fwhosts.cgi index 8aedd8a22..994a50a10 100644 --- a/html/cgi-bin/fwhosts.cgi +++ b/html/cgi-bin/fwhosts.cgi @@ -685,6 +685,9 @@ if ($fwhostsettings{'ACTION'} eq 'savegeoipgrp') my @target; my @newgrp; &General::readhasharray("$configgeoipgrp", \%customgeoipgrp); + &General::readhasharray("$fwconfigfwd", \%fwfwd); + &General::readhasharray("$fwconfiginp", \%fwinp); + &General::readhasharray("$fwconfigout", \%fwout); # Check for existing group name. if (!&checkgroup($grp) && $fwhostsettings{'update'} ne 'on'){ From d9f47d9b9e5041ee9b9d5fc40471cffe67d2a35e Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Thu, 19 Mar 2015 22:09:24 +0100 Subject: [PATCH 34/40] xt_geoip_update: Add support for upstream proxy. --- src/scripts/xt_geoip_update | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/scripts/xt_geoip_update b/src/scripts/xt_geoip_update index 42e214366..0ee774470 100644 --- a/src/scripts/xt_geoip_update +++ b/src/scripts/xt_geoip_update @@ -32,14 +32,30 @@ CSV_FILE=GeoIPCountryWhois.csv ARCH=LE +eval $(/usr/local/bin/readhash /var/ipfire/proxy/settings) + function download() { echo "Downloading latest GeoIP ruleset..." # Create temporary directory. mkdir -pv $TMP_PATH + # Proxy settings. + # Check if a proxy should be used. + if [[ $UPSTREAM_PROXY ]]; then + PROXYSETTINGS="-e http_proxy=http://" + + # Check if authentication against the proxy is configured. + if [[ $UPSTREAM_USER && $UPSTREAM_PASSWORD ]]; then + PROXYSETTINGS="$PROXYSETTINGS$UPSTREAM_USER:$UPSTREAM_PASSWORD@" + fi + + # Add proxy server. + PROXYSETTINGS="$PROXYSETTINGS$UPSTREAM_PROXY" + fi + # Get the latest GeoIP database from server. - wget $DL_URL/$DL_FILE -O $TMP_FILE + wget $DL_URL/$DL_FILE $PROXYSETTINGS -O $TMP_FILE # Extract files. unzip $TMP_FILE -d $TMP_PATH From 85abe3323a0b43976686d1c8e875861c7510abce Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 22 Mar 2015 18:53:17 +0100 Subject: [PATCH 35/40] Add spanish translations for GeoIP related strings. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A big thanks to Roberto Peña to provide them on the IPFire forum. http://forum.ipfire.org/viewtopic.php?f=52&t=11950&sid=f50fe6f51e0f45f1402c7a2164225398&start=30#p82360 --- langs/es/cgi-bin/es.pl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/langs/es/cgi-bin/es.pl b/langs/es/cgi-bin/es.pl index b7c50ff10..90f4237fb 100644 --- a/langs/es/cgi-bin/es.pl +++ b/langs/es/cgi-bin/es.pl @@ -866,6 +866,16 @@ 'generating the root and host certificates may take a long time. it can take up to several minutes on older hardware. please be patient' => 'Generar los certificador root y host puede tomar mucho tiempo. Puede durar varios minutos en equipos antiguos. Por favor sea paciente.', 'genkey' => 'Generar PSK', 'genre' => 'Género', +'geoip' => 'GeoIP', +'geoipblock' => 'GeoIP Block', +'geoipblock block countries' => 'Países bloqueados', +'geoipblock configuration' => 'Configuración GeoIP', +'geoipblock country code' => 'Código del País', +'geoipblock country is allowed' => 'Se permite el tráfico procedente de este País', +'geoipblock country is blocked' => 'Se deniega el tráfico procedente de este País', +'geoipblock country name' => 'Nombre del País', +'geoipblock enable feature' => 'Habilitar bloqueo basado GeoIP:', +'geoipblock flag' => 'Bandera', 'global settings' => 'Configuraciones globales', 'gpl i accept these terms and conditions' => 'I accept these terms and conditions', 'gpl license agreement' => 'License Agreement', From 64d886f53f0dcd5c6284b56b4965ad19eaf4d80a Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Tue, 31 Mar 2015 18:56:32 +0200 Subject: [PATCH 36/40] crontab: Call xt_geoip_update random once a month. --- config/cron/crontab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/cron/crontab b/config/cron/crontab index 54e9b5fee..3353092f6 100644 --- a/config/cron/crontab +++ b/config/cron/crontab @@ -59,4 +59,4 @@ HOME=/ 00 2 * 10-11 0 /usr/local/bin/timezone-transition /usr/local/bin/firewallctrl # Update GeoIP database once a month. -3 2 1 * * * [ -f "/var/ipfire/red/active" ] && /usr/local/bin/xt_geoip_update >/dev/null 2>&1 +%monthly,random * * [ -f "/var/ipfire/red/active" ] && /usr/local/bin/xt_geoip_update >/dev/null 2>&1 From 0ff5b2b0ac39be6954e0b727e21d98c631bb051b Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Tue, 31 Mar 2015 19:45:15 +0200 Subject: [PATCH 37/40] GeoIP: Add german translation. --- langs/de/cgi-bin/de.pl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/langs/de/cgi-bin/de.pl b/langs/de/cgi-bin/de.pl index eb29b5fbf..a1578b91d 100644 --- a/langs/de/cgi-bin/de.pl +++ b/langs/de/cgi-bin/de.pl @@ -416,6 +416,7 @@ 'bit' => 'Bit', 'bitrate' => 'Bitrate', 'bleeding rules' => 'Bleeding Edge Snort Rules', +'block' => 'Blocken', 'blue' => 'BLAU', 'blue access' => 'Zugriff auf Blau', 'blue access use hint' => 'Sie müssen mindestens die MAC- oder die IP-Adresse für ein Gerät angeben. Optional können Sie sowohl MAC- als auch IP-Adresse angeben.', @@ -532,6 +533,7 @@ 'chain' => 'Verknüpfung', 'change passwords' => 'Passwörter Ã¤ndern', 'change share' => 'Freigabeeinstellungen ändern', +'check all' =>'Alle auswÃhlen', 'check for net traffic update' => 'Prüfe auf Net-Traffic-Updates', 'check vpn lr' => 'Überprüfen', 'choose config' => 'Konfiguration auswählen', @@ -1067,6 +1069,7 @@ 'fwhost OpenVPN static host' => 'OpenVPN statischer Host', 'fwhost OpenVPN static network' => 'OpenVPN statisches Netzwerk', 'fwhost Standard Network' => 'Standard-Netzwerk', +'fwhost addgeoipgrp' => 'Neue GeoIP-Gruppe hinzufÃgen', 'fwhost addgrp' => 'Neue Gruppe hinzufügen', 'fwhost addgrpname' => 'Gruppenname:', 'fwhost addhost' => 'Neuen Host hinzufügen', @@ -1082,6 +1085,9 @@ 'fwhost change' => 'Ändern', 'fwhost changeremark' => 'Es wurde nur die Bemerkung angepasst.', 'fwhost cust addr' => 'Hosts', +'fwhost cust geoip' => 'GeoIP-Gruppen', +'fwhost cust geoipgroup' => 'GeoIP-Gruppen', +'fwhost cust geoiplocation' => 'GeoIP LÃndercodes', 'fwhost cust grp' => 'Gruppen', 'fwhost cust net' => 'Netzwerke', 'fwhost cust service' => 'Dienste', @@ -1128,6 +1134,7 @@ 'fwhost ipsec net' => 'IPsec-Netzwerke:', 'fwhost menu' => 'Firewallgruppen', 'fwhost netaddress' => 'Netzwerkadresse', +'fwhost newgeoipgrp' => 'GeoIP-Gruppen', 'fwhost newgrp' => 'Netzwerk-/Hostgruppen', 'fwhost newhost' => 'Hosts', 'fwhost newnet' => 'Netzwerke', @@ -1162,6 +1169,16 @@ 'generating the root and host certificates may take a long time. it can take up to several minutes on older hardware. please be patient' => 'Die Erzeugung der Root- und Host-Zertifikate kann lange Zeit dauern. Auf älterer Hardware kann es mehrere Minuten lang dauern. Bitte haben Sie etwas Geduld.', 'genkey' => 'PSK erzeugen', 'genre' => 'Genre', +'geoip' => 'GeoIP', +'geoipblock' => 'GeoIP Block', +'geoipblock block countries' => 'LÃnderfilter', +'geoipblock configuration' => 'GeoIP Konfiguration', +'geoipblock country code' => 'Ländercode', +'geoipblock country is allowed' => 'Eingehende Verbindungen aus diesem Land sind erlaubt.', +'geoipblock country is blocked' => 'Eingehende Verbindungen aus diesem Land werden blockiert.', +'geoipblock country name' => 'Ländername', +'geoipblock enable feature' => 'GeoIP basierte Filterung aktivieren:', +'geoipblock flag' => 'Flagge', 'global settings' => 'Globale Einstellungen', 'gpl i accept these terms and conditions' => 'Ich akzeptiere diese Bedingungen und Konditionen', 'gpl license agreement' => 'Lizenz-Vereinbarung', @@ -2214,8 +2231,11 @@ 'type' => 'Typ', 'umount' => 'Abmelden', 'umount removable media before to unplug' => 'Wechselmedien vor dem Entfernen unbedingt abmelden', +'uncheck all' => 'Alle abwählen', 'unable to alter profiles while red is active' => 'Profile können nicht geändert werden, solange ROT aktiv ist.', 'unable to contact' => 'Kann nicht erreicht werden', +'unblock' => 'Entblocken', +'unblock all' => 'Alle entblocken', 'unencrypted' => 'Nicht verschlüsselt', 'uninstall' => 'Deinstallieren', 'unix charset' => 'UNIX-Charset', From a8e59d803594f5af0ac1532e89aac6bd11600ecf Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Tue, 31 Mar 2015 22:14:56 +0200 Subject: [PATCH 38/40] GeoIP: Update english translation. --- langs/en/cgi-bin/en.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index d8cb5aa67..9d75f579d 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -1203,8 +1203,8 @@ 'geoipblock block countries' => 'Block countries', 'geoipblock configuration' => 'GeoIP Configuration', 'geoipblock country code' => 'Country Code', -'geoipblock country is allowed' => 'Traffic from this country is allowed', -'geoipblock country is blocked' => 'Traffic from this country will be blocked', +'geoipblock country is allowed' => 'Incoming traffic from this country is allowed', +'geoipblock country is blocked' => 'Incoming traffic from this country will be blocked', 'geoipblock country name' => 'Country Name', 'geoipblock enable feature' => 'Enable GeoIP based blocking:', 'geoipblock flag' => 'Flag', From ef4edcfb203a3610efb7e47cb6f4e3337cb2e312 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Wed, 1 Apr 2015 20:29:00 +0200 Subject: [PATCH 39/40] crontab: Fix syntax for xt_geoip_update call. --- config/cron/crontab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/cron/crontab b/config/cron/crontab index 3353092f6..d5e5d7e9f 100644 --- a/config/cron/crontab +++ b/config/cron/crontab @@ -59,4 +59,4 @@ HOME=/ 00 2 * 10-11 0 /usr/local/bin/timezone-transition /usr/local/bin/firewallctrl # Update GeoIP database once a month. -%monthly,random * * [ -f "/var/ipfire/red/active" ] && /usr/local/bin/xt_geoip_update >/dev/null 2>&1 +%monthly,random * * * [ -f "/var/ipfire/red/active" ] && /usr/local/bin/xt_geoip_update >/dev/null 2>&1 From 054d584786a60ed443d96642eb5a094e265da637 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Thu, 9 Apr 2015 18:14:48 +0200 Subject: [PATCH 40/40] de.pl: Fix umlauts in GeoIP related strings. This issue has been intruced in commit 0ff5b2b0ac39be6954e0b727e21d98c631bb051b. --- langs/de/cgi-bin/de.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/langs/de/cgi-bin/de.pl b/langs/de/cgi-bin/de.pl index a1578b91d..88533691d 100644 --- a/langs/de/cgi-bin/de.pl +++ b/langs/de/cgi-bin/de.pl @@ -533,7 +533,7 @@ 'chain' => 'Verknüpfung', 'change passwords' => 'Passwörter Ã¤ndern', 'change share' => 'Freigabeeinstellungen ändern', -'check all' =>'Alle auswÃhlen', +'check all' =>'Alle auswählen', 'check for net traffic update' => 'Prüfe auf Net-Traffic-Updates', 'check vpn lr' => 'Überprüfen', 'choose config' => 'Konfiguration auswählen', @@ -1069,7 +1069,7 @@ 'fwhost OpenVPN static host' => 'OpenVPN statischer Host', 'fwhost OpenVPN static network' => 'OpenVPN statisches Netzwerk', 'fwhost Standard Network' => 'Standard-Netzwerk', -'fwhost addgeoipgrp' => 'Neue GeoIP-Gruppe hinzufÃgen', +'fwhost addgeoipgrp' => 'Neue GeoIP-Gruppe hinzufügen', 'fwhost addgrp' => 'Neue Gruppe hinzufügen', 'fwhost addgrpname' => 'Gruppenname:', 'fwhost addhost' => 'Neuen Host hinzufügen', @@ -1087,7 +1087,7 @@ 'fwhost cust addr' => 'Hosts', 'fwhost cust geoip' => 'GeoIP-Gruppen', 'fwhost cust geoipgroup' => 'GeoIP-Gruppen', -'fwhost cust geoiplocation' => 'GeoIP LÃndercodes', +'fwhost cust geoiplocation' => 'GeoIP Ländercodes', 'fwhost cust grp' => 'Gruppen', 'fwhost cust net' => 'Netzwerke', 'fwhost cust service' => 'Dienste', @@ -1171,7 +1171,7 @@ 'genre' => 'Genre', 'geoip' => 'GeoIP', 'geoipblock' => 'GeoIP Block', -'geoipblock block countries' => 'LÃnderfilter', +'geoipblock block countries' => 'Länderfilter', 'geoipblock configuration' => 'GeoIP Konfiguration', 'geoipblock country code' => 'Ländercode', 'geoipblock country is allowed' => 'Eingehende Verbindungen aus diesem Land sind erlaubt.',