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 |
- |
|
|