Bugzilla – Attachment 92461 Details for
Bug 23068
Add ability for Koha to handle X-Forwarded-For headers so REMOTE_ADDR features work behind a proxy
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 23068: Add ability for Koha to handle X-Forwarded-For headers so REMOTE_ADDR features work behind a proxy
Bug-23068-Add-ability-for-Koha-to-handle-X-Forward.patch (text/plain), 11.32 KB, created by
Kyle M Hall (khall)
on 2019-08-23 18:23:15 UTC
(
hide
)
Description:
Bug 23068: Add ability for Koha to handle X-Forwarded-For headers so REMOTE_ADDR features work behind a proxy
Filename:
MIME Type:
Creator:
Kyle M Hall (khall)
Created:
2019-08-23 18:23:15 UTC
Size:
11.32 KB
patch
obsolete
>From 9f8ce62163b824e447e5569961b50e68ad983329 Mon Sep 17 00:00:00 2001 >From: Kyle M Hall <kyle@bywatersolutions.com> >Date: Thu, 6 Jun 2019 15:35:10 -0400 >Subject: [PATCH] Bug 23068: Add ability for Koha to handle X-Forwarded-For > headers so REMOTE_ADDR features work behind a proxy > >Koha has a number of features that rely on knowing the IP address of the connecting client. If that server is behind a proxy these features do not work. >This patch adds a module to automatically convert the X-Forwarded-For header into the REMOTE_ADDR environment variable for both CGI and Plack processes. > >TEST PLAN: >1) Apply this patch set >2) Install Plack::Middleware::RealIP via cpanm or your favorite utility >3) Update your plack.psgi with the changes you find in this patch set ( this process differs based on your testing environment ) >4) Restart plack >5) Tail the plack error log for your instance >6) Use curl to access the OPAC, adding an X-Forwarded-For header: curl --header "X-Forwarded-For: 32.32.32.32" http://127.0.0.1:8080 >7) Note the logs output this address if you are unproxied >8) If you are proxied, restart plack using a command like below, where the ip you see in the logs ("REAL IP) is what you put in the koha conf: > <koha_trusted_proxies>172.22.0.1 1.1.1.1</koha_trusted_proxies> >9) Restart all the things! >10) Repeat step 6 >11) You should now see "REAL IP: 32.32.32.32" in the plack logs as the remote address in your plack-error.log logs! >12) Disable plack so you are running in cgi mode, repeat step 6 again >13) You should see "REAL IP: 32.32.32.32" as the remove address in your opac-error.log logs! >--- > C4/Context.pm | 21 +++++ > Koha/Middleware/RealIP.pm | 118 +++++++++++++++++++++++++ > debian/templates/koha-conf-site.xml.in | 5 ++ > debian/templates/plack.psgi | 2 + > etc/koha-conf.xml | 5 ++ > offline_circ/process.pl | 2 + > svc/cataloguing/metasearch | 2 + > tools/background-job-progress.pl | 2 + > tools/batchMod.pl | 2 + > tools/batch_record_modification.pl | 2 + > tools/manage-marc-import.pl | 2 + > tools/stage-marc-import.pl | 2 + > tools/upload-cover-image.pl | 2 + > 13 files changed, 167 insertions(+) > create mode 100644 Koha/Middleware/RealIP.pm > >diff --git a/C4/Context.pm b/C4/Context.pm >index fa612472f7..664d644c19 100644 >--- a/C4/Context.pm >+++ b/C4/Context.pm >@@ -95,6 +95,7 @@ use DateTime::TimeZone; > use Encode; > use File::Spec; > use Module::Load::Conditional qw(can_load); >+use Net::Netmask; > use POSIX (); > use ZOOM; > >@@ -1078,6 +1079,26 @@ sub temporary_directory { > return C4::Context->config('tmp_path') || File::Spec->tmpdir; > } > >+=head3 set_remote_address >+ >+set_remote_address should be called at the beginning of every script >+that is *not* running under plack in order to the REMOTE_ADDR environment >+variable to be set correctly. >+ >+=cut >+ >+sub set_remote_address { >+ if ( C4::Context->config('koha_trusted_proxies') ) { >+ require CGI; >+ my $cgi = CGI->new; >+ my $header = $cgi->http('HTTP_X_FORWARDED_FOR'); >+ >+ if ($header) { >+ require Koha::Middleware::RealIP; >+ $ENV{REMOTE_ADDR} = Koha::Middleware::RealIP::get_real_ip( $ENV{REMOTE_ADDR}, $header ); >+ } >+ } >+} > > 1; > >diff --git a/Koha/Middleware/RealIP.pm b/Koha/Middleware/RealIP.pm >new file mode 100644 >index 0000000000..256790ee54 >--- /dev/null >+++ b/Koha/Middleware/RealIP.pm >@@ -0,0 +1,118 @@ >+package Koha::Middleware::RealIP; >+ >+# Copyright 2019 ByWater Solutions and the Koha Dev Team >+# >+# 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 <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use parent qw(Plack::Middleware); >+ >+use C4::Context; >+ >+use Net::Netmask; >+use Plack::Util::Accessor qw( trusted_proxy ); >+ >+=head3 prepare_app >+ >+This method generates and stores the list of trusted ip's as Netmask objects >+at the time Plack starts up, obviating the need to regerenate them on each request. >+ >+=cut >+ >+sub prepare_app { >+ my $self = shift; >+ $self->trusted_proxy( get_trusted_proxies() ); >+} >+ >+=head3 call >+ >+This method is called for each request, and will ensure the correct remote address >+is set in the REMOTE_ADDR environment variable. >+ >+=cut >+ >+sub call { >+ my $self = shift; >+ my $env = shift; >+ >+ if ( $env->{HTTP_X_FORWARDED_FOR} ) { >+ my @trusted_proxy = @{ $self->trusted_proxy } if $self->trusted_proxy; >+ >+ if (@trusted_proxy) { >+ my $addr = get_real_ip( $env->{REMOTE_ADDR}, $env->{HTTP_X_FORWARDED_FOR}, \@trusted_proxy ); >+ $ENV{REMOTE_ADDR} = $addr; >+ $env->{REMOTE_ADDR} = $addr; >+ } >+ } >+ >+ return $self->app->($env); >+} >+ >+=head3 get_real_ip >+ >+my $address = get_real_ip( $remote_addres, $x_forwarded_for_header ); >+ >+This method takes the current remote address and the x-forwarded-for header string, >+determines the correct external ip address, and returns it. >+ >+=cut >+ >+sub get_real_ip { >+ my ( $remote_addr, $header ) = @_; >+ >+ my @forwarded_for = $header =~ /([^,\s]+)/g; >+ return $remote_addr unless @forwarded_for; >+ >+ my $trusted_proxies = get_trusted_proxies(); >+ >+ my @unconfirmed = ( @forwarded_for, $remote_addr ); >+ >+ my $real_ip; >+ while (my $addr = pop @unconfirmed) { >+ my $has_matched = 0; >+ foreach my $netmask (@$trusted_proxies) { >+ $has_matched++, last if $netmask->match($addr); >+ } >+ $real_ip = $addr, last unless $has_matched; >+ } >+ >+ return $real_ip; >+} >+ >+=head3 get_trusted_proxies >+ >+This method returns an arrayref of Net::Netmask objects for all >+the trusted proxies given to Koha. >+ >+=cut >+ >+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 @trusted_proxies = map { Net::Netmask->new($_) } @trusted_proxies_ip; >+ return \@trusted_proxies; >+} >+ >+ >+=head1 AUTHORS >+ >+Kyle M Hall <kyle@bywatersolutions.com> >+ >+=cut >+ >+1; >diff --git a/debian/templates/koha-conf-site.xml.in b/debian/templates/koha-conf-site.xml.in >index e9e562439d..6694cc76ee 100644 >--- a/debian/templates/koha-conf-site.xml.in >+++ b/debian/templates/koha-conf-site.xml.in >@@ -345,6 +345,11 @@ __END_SRU_PUBLICSERVER__ > <plack_max_requests>50</plack_max_requests> > <plack_workers>2</plack_workers> > >+ <!-- Configuration for X-Forwarded-For --> >+ <!-- >+ <koha_trusted_proxies>1.2.3.4 2.3.4.5 3.4.5.6</koha_trusted_proxies> >+ --> >+ > <!-- Elasticsearch Configuration --> > <elasticsearch> > <server>localhost:9200</server> >diff --git a/debian/templates/plack.psgi b/debian/templates/plack.psgi >index 3538b9a5a1..cde680ee30 100644 >--- a/debian/templates/plack.psgi >+++ b/debian/templates/plack.psgi >@@ -68,8 +68,10 @@ my $apiv1 = builder { > builder { > enable "ReverseProxy"; > enable "Plack::Middleware::Static"; >+ > # + is required so Plack doesn't try to prefix Plack::Middleware:: > enable "+Koha::Middleware::SetEnv"; >+ enable "+Koha::Middleware::RealIP"; > > mount '/opac' => $opac; > mount '/intranet' => $intranet; >diff --git a/etc/koha-conf.xml b/etc/koha-conf.xml >index fc7c7cfead..1f9342dd6e 100644 >--- a/etc/koha-conf.xml >+++ b/etc/koha-conf.xml >@@ -161,6 +161,11 @@ __PAZPAR2_TOGGLE_XML_POST__ > <plack_max_requests>50</plack_max_requests> > <plack_workers>2</plack_workers> > >+ <!-- Configuration for X-Forwarded-For --> >+ <!-- >+ <koha_trusted_proxies>1.2.3.4 2.3.4.5 3.4.5.6</koha_trusted_proxies> >+ --> >+ > <!-- Elasticsearch Configuration --> > <elasticsearch> > <server>localhost:9200</server> >diff --git a/offline_circ/process.pl b/offline_circ/process.pl >index a8a59dd73f..fb247ee17a 100755 >--- a/offline_circ/process.pl >+++ b/offline_circ/process.pl >@@ -24,6 +24,8 @@ use CGI qw ( -utf8 ); > use C4::Auth; > use C4::Circulation; > >+C4::Context->set_remote_address; >+ > my $query = CGI->new; > > my ($template, $loggedinuser, $cookie) = get_template_and_user({ >diff --git a/svc/cataloguing/metasearch b/svc/cataloguing/metasearch >index 110732f7cf..55e425fab4 100755 >--- a/svc/cataloguing/metasearch >+++ b/svc/cataloguing/metasearch >@@ -23,6 +23,8 @@ use C4::Service; > use Encode qw( encode_utf8 ); > use Koha::MetaSearcher; > >+C4::Context->set_remote_address; >+ > my ( $query, $response ) = C4::Service->init( catalogue => 1 ); > > my ( $query_string, $servers ) = C4::Service->require_params( 'q', 'servers' ); >diff --git a/tools/background-job-progress.pl b/tools/background-job-progress.pl >index 625389f902..3c18b7a603 100755 >--- a/tools/background-job-progress.pl >+++ b/tools/background-job-progress.pl >@@ -29,6 +29,8 @@ use C4::BackgroundJob; > use CGI::Cookie; # need to check cookies before > # having CGI parse the POST request > >+C4::Context->set_remote_address; >+ > my $input = CGI->new; > my %cookies = CGI::Cookie->fetch; > my ($auth_status, $sessionID) = check_cookie_auth($cookies{'CGISESSID'}->value, { tools => '*' }); >diff --git a/tools/batchMod.pl b/tools/batchMod.pl >index 9b1f958950..d2f5c31e9f 100755 >--- a/tools/batchMod.pl >+++ b/tools/batchMod.pl >@@ -41,6 +41,8 @@ use Koha::Items; > use Koha::ItemTypes; > use Koha::Patrons; > >+C4::Context->set_remote_address; >+ > my $input = new CGI; > my $dbh = C4::Context->dbh; > my $error = $input->param('error'); >diff --git a/tools/batch_record_modification.pl b/tools/batch_record_modification.pl >index 1a82c476c3..405fc0e738 100755 >--- a/tools/batch_record_modification.pl >+++ b/tools/batch_record_modification.pl >@@ -34,6 +34,8 @@ use Koha::Biblios; > use Koha::MetadataRecord::Authority; > use Koha::Virtualshelves; > >+C4::Context->set_remote_address; >+ > my $input = new CGI; > our $dbh = C4::Context->dbh; > my $op = $input->param('op') // q|form|; >diff --git a/tools/manage-marc-import.pl b/tools/manage-marc-import.pl >index 4fea4005d7..bbfcbd1f98 100755 >--- a/tools/manage-marc-import.pl >+++ b/tools/manage-marc-import.pl >@@ -37,6 +37,8 @@ use C4::BackgroundJob; > use C4::Labels::Batch; > use Koha::BiblioFrameworks; > >+C4::Context->set_remote_address; >+ > my $script_name = "/cgi-bin/koha/tools/manage-marc-import.pl"; > > my $input = new CGI; >diff --git a/tools/stage-marc-import.pl b/tools/stage-marc-import.pl >index d76c35ac18..c3a2e342c2 100755 >--- a/tools/stage-marc-import.pl >+++ b/tools/stage-marc-import.pl >@@ -43,6 +43,8 @@ use C4::BackgroundJob; > use C4::MarcModificationTemplates; > use Koha::Plugins; > >+C4::Context->set_remote_address; >+ > my $input = new CGI; > > my $fileID = $input->param('uploadedfileid'); >diff --git a/tools/upload-cover-image.pl b/tools/upload-cover-image.pl >index ff89afb1d6..939290eeae 100755 >--- a/tools/upload-cover-image.pl >+++ b/tools/upload-cover-image.pl >@@ -49,6 +49,8 @@ use C4::Images; > use Koha::UploadedFiles; > use C4::Log; > >+C4::Context->set_remote_address; >+ > my $debug = 1; > > my $input = new CGI; >-- >2.20.1 (Apple Git-117)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 23068
:
90395
|
90396
|
90582
|
91173
|
91174
|
91447
|
92461
|
92462
|
92463
|
92464
|
94807
|
94808
|
94838
|
94839
|
94919