
    i              	       ,   d Z ddlmZmZ ddlZddlZddlmZmZ ddl	m
Z
 ddl	mZ ddl	mZ dd	lmZmZ  ej                   d
      ZdZ	 dZ	 dZ	 dZ	 dZ	 dZ	 dZ	 dZ	 dZ	 dZ	 deez  dej6                  dej8                  dej:                  dz  fdZy)a  .. _botdetection.ip_limit:

Method ``ip_limit``
-------------------

The ``ip_limit`` method counts request from an IP in *sliding windows*.  If
there are to many requests in a sliding window, the request is evaluated as a
bot request.  This method requires a valkey DB and needs a HTTP X-Forwarded-For_
header.  To take privacy only the hash value of an IP is stored in the valkey DB
and at least for a maximum of 10 minutes.

The :py:obj:`.link_token` method can be used to investigate whether a request is
*suspicious*.  To activate the :py:obj:`.link_token` method in the
:py:obj:`.ip_limit` method add the following configuration:

.. code:: toml

   [botdetection.ip_limit]
   link_token = true

If the :py:obj:`.link_token` method is activated and a request is *suspicious*
the request rates are reduced:

- :py:obj:`BURST_MAX` -> :py:obj:`BURST_MAX_SUSPICIOUS`
- :py:obj:`LONG_MAX` -> :py:obj:`LONG_MAX_SUSPICIOUS`

To intercept bots that get their IPs from a range of IPs, there is a
:py:obj:`SUSPICIOUS_IP_WINDOW`.  In this window the suspicious IPs are stored
for a longer time.  IPs stored in this sliding window have a maximum of
:py:obj:`SUSPICIOUS_IP_MAX` accesses before they are blocked.  As soon as the IP
makes a request that is not suspicious, the sliding window for this IP is
dropped.

.. _X-Forwarded-For:
   https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For

    )IPv4NetworkIPv6NetworkN)incr_sliding_windowdrop_counter   )
link_token)config)valkeydb)too_many_requestsloggerip_limit         iX     
   i     i '    networkrequestcfgreturnc                 0   t        j                         }| j                  r&|d   s!t        j                  d| j
                         y |j                  j                  dd      dk7  r3t        |d| j
                  z   t              }|t        kD  rt        | d      S |d   rt        j                  | |d      }|st        |d	| j
                  z          y t        |d	| j
                  z   t              }|t         kD  rQt        j"                  d
|        t%        j&                  t%        j(                  d      d      }d|j*                  d<   |S t        |d| j
                  z   t,              }|t.        kD  rt        | d      S t        |d| j
                  z   t0              }|t2        kD  rt        | d      S y t        |d| j
                  z   t,              }|t4        kD  rt        | d      S t        |d| j
                  z   t0              }|t6        kD  rt        | d      S y )Nz'botdetection.ip_limit.filter_link_localz<network %s is link-local -> not monitored by ip_limit methodformathtmlzip_limit.API_WINDOW:ztoo many request in API_WINDOWz botdetection.ip_limit.link_tokenTzip_limit.SUSPICIOUS_IP_WINDOWzGBLOCK: too many request from %s in SUSPICIOUS_IP_WINDOW (redirect to /)indexi.  )codezno-store, max-age=0zCache-Controlzip_limit.BURST_WINDOWz7too many request in BURST_WINDOW (BURST_MAX_SUSPICIOUS)zip_limit.LONG_WINDOWz5too many request in LONG_WINDOW (LONG_MAX_SUSPICIOUS)z,too many request in BURST_WINDOW (BURST_MAX)z*too many request in LONG_WINDOW (LONG_MAX))r
   get_valkey_clientis_link_localr   debug
compressedargsgetr   
API_WINDOWAPI_MAXr   r   is_suspiciousr   SUSPICIOUS_IP_WINDOWSUSPICIOUS_IP_MAXerrorflaskredirecturl_forheadersBURST_WINDOWBURST_MAX_SUSPICIOUSLONG_WINDOWLONG_MAX_SUSPICIOUS	BURST_MAXLONG_MAX)r   r   r   valkey_clientc
suspiciousresponses          ,/root/searxng/searx/botdetection/ip_limit.pyfilter_requestr9   \   s    ..0MS)R%SSU\UgUgh||&)V3/EHZHZ/Z\fgw;$W.NOO
-.--gwE
(G'J\J\(\]  :W=O=OOQe
   LLbdkl~~emmG&<3GH0EH_-O/FI[I[/[]ij##$W.ghh/EHZHZ/Z\gh""$W.eff 	M+BWEWEW+WYefA9} *XYYM+AGDVDV+VXcdA8| *VWW    )__doc__	ipaddressr   r   r*   werkzeugsearx.valkeylibr   r    r   r	   r
   _helpersr   r   getChildr.   r2   r/   r0   r3   r1   r$   r%   r'   r(   RequestConfigResponser9    r:   r8   <module>rF      s   $L
   =    
	$ D	 @  N : ?  J
 Q
 >%  E  T8;&8]]8 
8 	8r:   