76 """Returns real IP of the request. Since not all proxies set all the HTTP
77 headers and incoming headers can be faked it may happen that the IP cannot
78 be determined correctly.
80 .. sidebar:: :py:obj:`flask.Request.remote_addr`
82 SearXNG uses Werkzeug's ProxyFix_ (with it default ``x_for=1``).
84 This function tries to get the remote IP in the order listed below,
85 additional some tests are done and if inconsistencies or errors are
86 detected, they are logged.
88 The remote IP of the request is taken from (first match):
90 - X-Forwarded-For_ header
91 - `X-real-IP header <https://github.com/searxng/searxng/issues/1237#issuecomment-1147564516>`__
92 - :py:obj:`flask.Request.remote_addr`
95 https://werkzeug.palletsprojects.com/middleware/proxy_fix/
98 https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
102 forwarded_for = request.headers.get(
"X-Forwarded-For")
103 real_ip = request.headers.get(
'X-Real-IP')
104 remote_addr = request.remote_addr
109 if not forwarded_for:
114 forwarded_for = [x.strip()
for x
in forwarded_for.split(
',')]
115 x_for: int = cfg[
'real_ip.x_for']
116 forwarded_for = forwarded_for[-min(len(forwarded_for), x_for)]
121 if forwarded_for
and real_ip
and forwarded_for != real_ip:
122 logger.warning(
"IP from X-Real-IP (%s) is not equal to IP from X-Forwarded-For (%s)", real_ip, forwarded_for)
124 if forwarded_for
and remote_addr
and forwarded_for != remote_addr:
126 "IP from WSGI environment (%s) is not equal to IP from X-Forwarded-For (%s)", remote_addr, forwarded_for
129 if real_ip
and remote_addr
and real_ip != remote_addr:
130 logger.warning(
"IP from WSGI environment (%s) is not equal to IP from X-Real-IP (%s)", remote_addr, real_ip)
132 request_ip = ip_address(forwarded_for
or real_ip
or remote_addr
or '0.0.0.0')
133 if request_ip.version == 6
and request_ip.ipv4_mapped:
134 request_ip = request_ip.ipv4_mapped
137 return str(request_ip)