]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add proxy_dedup_window
authorAlan T. DeKok <aland@freeradius.org>
Thu, 7 Dec 2023 11:46:31 +0000 (06:46 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 7 Dec 2023 11:54:08 +0000 (06:54 -0500)
which controls how the server drops aggressive retransmissions
from a misbehaving NAS

raddb/radiusd.conf.in
src/include/radiusd.h
src/main/mainconfig.c
src/main/process.c

index 5a521cb4f48b2aaedea63228bc3afcdaa8423c52..12fac7abd5e3cd5ec083621a227cfce89c26979d 100644 (file)
@@ -269,6 +269,27 @@ hostname_lookups = no
 #
 #postauth_client_lost = no
 
+#
+#  Some NASes will aggressively retransmit packets, and cause a DoS of
+#  the RADIUS infrastructure.  They should follow he recommended
+#  retransmission behavior of RFC 5080 Section 2.2.2, but it seems
+#  that only (some) RADIUS servers follow that guidance.
+#
+#  When a duplicate packet is received from the NAS, the server will
+#  see when the last retransmission was done.  If it is within the
+#  "proxy_dedup_window", the retransmitted packet is dropped.
+#
+#  i.e. There is zero benefit to sending the same RADIUS packet
+#  multiple times in one second.  There is, in fact, serious harm
+#  in doing so.  Aggressive retransmissions can result in network
+#  congestion, and ultimately failure of the RADIUS infrastructure.
+#
+#  This behavior *cannot* be disabled.
+#
+#  Allowed values here are 1..10.  Only integers are supported.
+#
+#proxy_dedup_window = 1
+
 #
 #  Logging section.  The various "log_*" configuration items
 #  will eventually be moved here.
index 594a6bde8721b540dcaf6f51d461046c5836ab12..982f2124c62f8309bddfbebb2c5f57f6734fd5f0 100644 (file)
@@ -141,6 +141,8 @@ typedef struct main_config {
        uint32_t        cleanup_delay;                  //!< How long before cleaning up cached responses.
        uint32_t        max_requests;
 
+       uint32_t        proxy_dedup_window;             //!< suppress duplicate retransmitssions from a NAS
+
        bool            postauth_client_lost;           //!< Whether to run Post-Auth-Type Client-Lost section
 
        uint32_t        debug_level;
index 227ae4acfde86d209b249e15174b6bc83be1d5ec..9c268a1ce08d3ccb67bd62a30ca903e2c41346c1 100644 (file)
@@ -195,6 +195,7 @@ static const CONF_PARSER server_config[] = {
        { "panic_action", FR_CONF_POINTER(PW_TYPE_STRING, &main_config.panic_action), NULL},
        { "hostname_lookups", FR_CONF_POINTER(PW_TYPE_BOOLEAN, &fr_dns_lookups), "no" },
        { "max_request_time", FR_CONF_POINTER(PW_TYPE_INTEGER, &main_config.max_request_time), STRINGIFY(MAX_REQUEST_TIME) },
+       { "proxy_dedup_window", FR_CONF_POINTER(PW_TYPE_INTEGER, &main_config.proxy_dedup_window), "1" },
        { "cleanup_delay", FR_CONF_POINTER(PW_TYPE_INTEGER, &main_config.cleanup_delay), STRINGIFY(CLEANUP_DELAY) },
        { "max_requests", FR_CONF_POINTER(PW_TYPE_INTEGER, &main_config.max_requests), STRINGIFY(MAX_REQUESTS) },
        { "postauth_client_lost", FR_CONF_POINTER(PW_TYPE_BOOLEAN, &main_config.postauth_client_lost), "no" },
@@ -1144,6 +1145,10 @@ do {\
        if ((main_config.reject_delay.tv_sec != 0) || (main_config.reject_delay.tv_usec != 0)) {
                FR_TIMEVAL_BOUND_CHECK("reject_delay", &main_config.reject_delay, >=, 1, 0);
        }
+
+       FR_INTEGER_BOUND_CHECK("proxy_dedup_window", main_config.proxy_dedup_window, <=, 10);
+       FR_INTEGER_BOUND_CHECK("proxy_dedup_window", main_config.proxy_dedup_window, >=, 1);
+
        FR_TIMEVAL_BOUND_CHECK("reject_delay", &main_config.reject_delay, <=, 10, 0);
 
        FR_INTEGER_BOUND_CHECK("cleanup_delay", main_config.cleanup_delay, <=, 30);
index ff3263bbe760b7c0bc0751a61ab6ba92e5855e8e..34e9866dd712b3ef02911c7272e29616be3a0b69 100644 (file)
@@ -4363,7 +4363,7 @@ static void proxy_wait_for_reply(REQUEST *request, int action)
                 *      and should be suppressed by the proxy.
                 */
                when = request->proxy->timestamp;
-               when.tv_sec++;
+               when.tv_sec += main_config.proxy_dedup_window;
 
                if (timercmp(&now, &when, <)) {
                        DEBUG2("Suppressing duplicate proxied request (too fast) to home server %s port %d - ID: %d",