Is your feature request related to a problem? Please describe.
My application resides behind a Google Application Load Balancer. To parse the client's IP I must use the X-Forwarded-For header, which is documented in GCP's docs here.
As this is a valid header, I want axes to continue to use <client-ip>, which is fully determinable because we set PROXY_COUNT accordingly, so it should use the value PROXY_COUNT away from the right-most IP address.
However, because axes uses IpWare in strict mode, it will reject this header and instead populate the client's IP as None.
In the exert, this calls get_client_ip hardcoded with strict=True. This is not exposed as a configurable value
Because we have strict=True means the is_proxy_count_valid check in python-ipware fails in my described scenario. See here.
This is because when the user supplies their own value the ip_count is not exactly proxy_count+1 parts. There is an indefinite number of parts (as the user-supplied value may be any value with any number of parts).
However, if I could use the same logic with strict=False, all my problems would go away, because the get_best_ip function would still resolve to the correct client IP (right-most, offset by the configured proxy count):
if self.proxy_count is not None:
best_client_ip_index = self.proxy_count + 1
best_client_ip = ip_list[-best_client_ip_index]
return best_client_ip, True
Describe the solution you'd like
I would like django-axes to expose a AXES_IPWARE_STRICT config item. The value could default to True for backwards-compatibility reasons. This should get propagated to ipware's get_client_ip arg:
Describe alternatives you've considered
Alternatively, I could use django-axes's config item AXES_CLIENT_IP_CALLABLE to define my own IP resolver function. This would allow me to define my own logic, such as calling IpWare myself with the desired config.
if you're up to it, I think adding the flag for strict or non-strict resolution via e.g. your proposed AXES_IPWARE_STRICT or similarly named flag sounds like a good solution 👍
Is your feature request related to a problem? Please describe. My application resides behind a Google Application Load Balancer. To parse the client's IP I must use the X-Forwarded-For header, which is documented in GCP's docs here.
To achieve this, I set the following config:
This works fine when the header is formed like so:
However, because the Google loadbalancer will propagate the user's own supplied X-Forwarded-For header, it may also be in this format:
As this is a valid header, I want axes to continue to use
<client-ip>
, which is fully determinable because we setPROXY_COUNT
accordingly, so it should use the valuePROXY_COUNT
away from the right-most IP address.However, because axes uses IpWare in strict mode, it will reject this header and instead populate the client's IP as
None
.Here's how this currently works:
get_client_ip
hardcoded with strict=True. This is not exposed as a configurable valueBecause we have
strict=True
means theis_proxy_count_valid
check inpython-ipware
fails in my described scenario. See here.This is because when the user supplies their own value the
ip_count
is not exactlyproxy_count+1
parts. There is an indefinite number of parts (as the user-supplied value may be any value with any number of parts).However, if I could use the same logic with
strict=False
, all my problems would go away, because theget_best_ip
function would still resolve to the correct client IP (right-most, offset by the configured proxy count):Describe the solution you'd like I would like django-axes to expose a
AXES_IPWARE_STRICT
config item. The value could default toTrue
for backwards-compatibility reasons. This should get propagated to ipware'sget_client_ip
arg:Describe alternatives you've considered Alternatively, I could use django-axes's config item
AXES_CLIENT_IP_CALLABLE
to define my own IP resolver function. This would allow me to define my own logic, such as calling IpWare myself with the desired config.