From 8d43405844c9a393ab88b15de7aa0a7613ed8011 Mon Sep 17 00:00:00 2001 From: Nicholas van Oudtshoorn Date: Wed, 27 Mar 2024 13:56:26 +0800 Subject: [PATCH] Bug 36304 - Support for an external proxy list, and caching of all trusted proxies --- Koha/Middleware/RealIP.pm | 61 +++++++++++++++---- etc/koha-conf.xml | 4 ++ .../update_external_trusted_proxies_list.sh | 48 +++++++++++++++ 3 files changed, 102 insertions(+), 11 deletions(-) create mode 100755 misc/cronjobs/update_external_trusted_proxies_list.sh diff --git a/Koha/Middleware/RealIP.pm b/Koha/Middleware/RealIP.pm index fc9f280ff6..0427dfec37 100644 --- a/Koha/Middleware/RealIP.pm +++ b/Koha/Middleware/RealIP.pm @@ -79,7 +79,20 @@ sub get_real_ip { my @forwarded_for = $header =~ /([^,\s]+)/g; return $remote_addr unless @forwarded_for; - my $trusted_proxies = get_trusted_proxies(); + my $trusted_proxies; + # Cache the trusted proxies list + my $cache = Koha::Caches->get_instance(); + my $cache_active = $cache->is_cache_active; + my $cache_key = "trustedproxylist"; + if ($cache_active) { + $trusted_proxies = $cache->get_from_cache($cache_key); + } + unless ($trusted_proxies) { + $trusted_proxies = get_trusted_proxies(); + if ($cache_active) { + $cache->set_in_cache( $cache_key, $trusted_proxies); + } + } #X-Forwarded-For: , , my $real_ip = shift @forwarded_for; @@ -105,18 +118,43 @@ the trusted proxies given to Koha. sub get_trusted_proxies { my $proxies_conf = C4::Context->config('koha_trusted_proxies'); - return unless $proxies_conf; - my @trusted_proxies_ip = split( / /, $proxies_conf ); + my $external_proxies_list_file = C4::Context->config('koha_trusted_proxies_external_list'); + + return unless ( $external_proxies_list_file || $proxies_conf ); + my @trusted_proxies = (); - foreach my $ip (@trusted_proxies_ip){ - my $mask = Net::Netmask->new2($ip); - if ($mask){ - push(@trusted_proxies,$mask); - } - else { - warn "$Net::Netmask::error"; - } + + if ($external_proxies_list_file && (-f $external_proxies_list_file)) { + if (open my $in, "<", $external_proxies_list_file) { + while (my $line = <$in>) { + chomp $line; + my $finalmask = Net::Netmask->new2($line); + if ($finalmask) { + push(@trusted_proxies, $finalmask); + } + else { + warn "$Net::Netmask::error"; + } + } + close $in; + } else { + warn "Could not read external proxy list $external_proxies_list_file" + } } + + if ($proxies_conf) { + my @trusted_proxies_ip = split( / /, $proxies_conf ); + foreach my $ip (@trusted_proxies_ip){ + my $mask = Net::Netmask->new2($ip); + if ($mask){ + push(@trusted_proxies,$mask); + } + else { + warn "$Net::Netmask::error"; + } + } + } + return \@trusted_proxies; } @@ -124,6 +162,7 @@ sub get_trusted_proxies { =head1 AUTHORS Kyle M Hall +Nicholas van Oudtshoorn, 2024 =cut diff --git a/etc/koha-conf.xml b/etc/koha-conf.xml index f7cdd2f8d0..3ce15f8ba5 100644 --- a/etc/koha-conf.xml +++ b/etc/koha-conf.xml @@ -158,8 +158,12 @@ 2 + + diff --git a/misc/cronjobs/update_external_trusted_proxies_list.sh b/misc/cronjobs/update_external_trusted_proxies_list.sh new file mode 100755 index 0000000000..88c098ed66 --- /dev/null +++ b/misc/cronjobs/update_external_trusted_proxies_list.sh @@ -0,0 +1,48 @@ +#!/bin/bash +#----------------------------------- +# Copyright 2024 Nicholas van Oudtshoorn +# +# This file is part of Koha. +# +# Koha 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. +# +# Koha 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 Koha; if not, see . + +# This cron job should be run as a user that has write access to the IP_LIST_FILE +# The IP_LIST_FILE should be the same as that referenced in the koha-conf.xml file. +RESTART_KOHA_IF_NEEDED=1 + +IP_LIST_FILE=__KOHA_CONF_DIR__/trusted_proxies +echo "Updating external proxy list: $IP_LIST_FILE" +CURRENT_LIST=$(cat $IP_LIST_FILE) +echo $OLD_LIST + +echo "Downloading cloudflare proxy list"; +curl -sS "https://www.cloudflare.com/ips-v4" > $IP_LIST_FILE +echo >> $IP_LIST_FILE # Make sure there is a new-line at the end of the ip-v4 list +curl -sS "https://www.cloudflare.com/ips-v6" >> $IP_LIST_FILE + +NEW_LIST=$(cat $IP_LIST_FILE) +echo +echo "List contents:" +echo -n "$NEW_LIST" +echo + +if [ "$OLD_LIST" != "$NEW_LIST" ]; then + echo "List contents have changed. Koha needs to be restarted." + if [ $RESTART_KOHA_IF_NEEDED -eq 1 ]; then + echo "Restarting koha-common, if it is already running." + systemctl is-active --quiet koha-common && systemctl restart koha-common && echo "The service is now:" `systemctl is-active koha-common` + echo "Clearing caches" + koha-foreach /usr/share/koha/bin/clear_cache.pl + fi +fi \ No newline at end of file -- 2.34.1