|
Lines 51-63
sub call {
Link Here
|
| 51 |
my $self = shift; |
51 |
my $self = shift; |
| 52 |
my $env = shift; |
52 |
my $env = shift; |
| 53 |
|
53 |
|
| 54 |
# If no reverse_proxy_ip_header, just use HTTP_X_FORWARDED_FOR as the header to check, simplifies logic and is a bit faster that way |
|
|
| 55 |
my $reverse_proxy_ip_header = C4::Context->config('reverse_proxy_ip_header') || 'HTTP_X_FORWARDED_FOR'; |
54 |
my $reverse_proxy_ip_header = C4::Context->config('reverse_proxy_ip_header') || 'HTTP_X_FORWARDED_FOR'; |
|
|
55 |
my $require_trusted = C4::Context->config('require_trusted_proxy_for_headers'); |
| 56 |
|
56 |
|
| 57 |
# Check the env for the custom header, if the custom header is not set, fall back to HTTP_X_FORWARDED_FOR |
|
|
| 58 |
my $header = $env->{$reverse_proxy_ip_header} || $env->{'HTTP_X_FORWARDED_FOR'}; |
57 |
my $header = $env->{$reverse_proxy_ip_header} || $env->{'HTTP_X_FORWARDED_FOR'}; |
|
|
58 |
my $addr = $env->{REMOTE_ADDR}; |
| 59 |
|
| 59 |
if ($header) { |
60 |
if ($header) { |
| 60 |
my $addr = get_real_ip( $env->{REMOTE_ADDR}, $header ); |
61 |
if ($require_trusted) { |
|
|
62 |
|
| 63 |
# Only trust header if REMOTE_ADDR is a trusted proxy |
| 64 |
my $trusted_proxies = get_trusted_proxies(); |
| 65 |
my $is_trusted = 0; |
| 66 |
foreach my $netmask (@$trusted_proxies) { |
| 67 |
if ( $netmask->match($addr) ) { |
| 68 |
$is_trusted = 1; |
| 69 |
last; |
| 70 |
} |
| 71 |
} |
| 72 |
if ($is_trusted) { |
| 73 |
$addr = get_real_ip( $env->{REMOTE_ADDR}, $header ); |
| 74 |
} |
| 75 |
} else { |
| 76 |
|
| 77 |
# Always trust the header |
| 78 |
$addr = get_real_ip( $env->{REMOTE_ADDR}, $header ); |
| 79 |
} |
| 61 |
$ENV{REMOTE_ADDR} = $addr; |
80 |
$ENV{REMOTE_ADDR} = $addr; |
| 62 |
$env->{REMOTE_ADDR} = $addr; |
81 |
$env->{REMOTE_ADDR} = $addr; |
| 63 |
} |
82 |
} |
|
Lines 80-100
sub get_real_ip {
Link Here
|
| 80 |
my @forwarded_for = $header =~ /([^,\s]+)/g; |
99 |
my @forwarded_for = $header =~ /([^,\s]+)/g; |
| 81 |
return $remote_addr unless @forwarded_for; |
100 |
return $remote_addr unless @forwarded_for; |
| 82 |
|
101 |
|
| 83 |
my $trusted_proxies = get_trusted_proxies(); |
|
|
| 84 |
|
| 85 |
#X-Forwarded-For: <client>, <proxy1>, <proxy2> |
102 |
#X-Forwarded-For: <client>, <proxy1>, <proxy2> |
| 86 |
my $real_ip = shift @forwarded_for; |
103 |
my $real_ip = shift @forwarded_for; |
| 87 |
my @unconfirmed = ( @forwarded_for, $remote_addr ); |
104 |
return $real_ip if $real_ip; |
| 88 |
|
105 |
return $remote_addr; |
| 89 |
while ( my $addr = pop @unconfirmed ) { |
|
|
| 90 |
my $has_matched = 0; |
| 91 |
foreach my $netmask (@$trusted_proxies) { |
| 92 |
$has_matched++, last if $netmask->match($addr); |
| 93 |
} |
| 94 |
$real_ip = $addr, last unless $has_matched; |
| 95 |
} |
| 96 |
|
| 97 |
return $real_ip; |
| 98 |
} |
106 |
} |
| 99 |
|
107 |
|
| 100 |
=head2 get_trusted_proxies |
108 |
=head2 get_trusted_proxies |
| 101 |
- |
|
|