From a6328e51e0c831ba3f0f4977f776491ac44eaec5 Mon Sep 17 00:00:00 2001 From: Alexander Chernavin Date: Wed, 20 Jul 2022 13:01:42 +0000 Subject: wireguard: add handshake rate limiting support Type: feature With this change, if being under load a handshake message with both valid mac1 and mac2 is received, the peer will be rate limited. Cover this with tests. Signed-off-by: Alexander Chernavin Change-Id: Id8d58bb293a7975c3d922c48b4948fd25e20af4b --- src/plugins/wireguard/wireguard_cookie.h | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'src/plugins/wireguard/wireguard_cookie.h') diff --git a/src/plugins/wireguard/wireguard_cookie.h b/src/plugins/wireguard/wireguard_cookie.h index 9298ece8db5..7467cf2ed4a 100644 --- a/src/plugins/wireguard/wireguard_cookie.h +++ b/src/plugins/wireguard/wireguard_cookie.h @@ -25,7 +25,8 @@ enum cookie_mac_state { INVALID_MAC, VALID_MAC_BUT_NO_COOKIE, - VALID_MAC_WITH_COOKIE + VALID_MAC_WITH_COOKIE, + VALID_MAC_WITH_COOKIE_BUT_RATELIMITED, }; #define COOKIE_MAC_SIZE 16 @@ -50,8 +51,6 @@ enum cookie_mac_state #define INITIATION_COST (NSEC_PER_SEC / INITIATIONS_PER_SECOND) #define TOKEN_MAX (INITIATION_COST * INITIATIONS_BURSTABLE) #define ELEMENT_TIMEOUT 1 -#define IPV4_MASK_SIZE 4 /* Use all 4 bytes of IPv4 address */ -#define IPV6_MASK_SIZE 8 /* Use top 8 bytes (/64) of IPv6 address */ typedef struct cookie_macs { @@ -59,6 +58,19 @@ typedef struct cookie_macs uint8_t mac2[COOKIE_MAC_SIZE]; } message_macs_t; +typedef struct ratelimit_entry +{ + f64 r_last_time; + u64 r_tokens; +} ratelimit_entry_t; + +typedef struct ratelimit +{ + ratelimit_entry_t *rl_pool; + uword *rl_table; + f64 rl_last_gc; +} ratelimit_t; + typedef struct cookie_maker { uint8_t cp_mac1_key[COOKIE_KEY_SIZE]; @@ -72,6 +84,9 @@ typedef struct cookie_maker typedef struct cookie_checker { + ratelimit_t cc_ratelimit_v4; + ratelimit_t cc_ratelimit_v6; + uint8_t cc_mac1_key[COOKIE_KEY_SIZE]; uint8_t cc_cookie_key[COOKIE_KEY_SIZE]; @@ -81,7 +96,9 @@ typedef struct cookie_checker void cookie_maker_init (cookie_maker_t *, const uint8_t[COOKIE_INPUT_SIZE]); +void cookie_checker_init (cookie_checker_t *, ratelimit_entry_t *); void cookie_checker_update (cookie_checker_t *, uint8_t[COOKIE_INPUT_SIZE]); +void cookie_checker_deinit (cookie_checker_t *); void cookie_checker_create_payload (vlib_main_t *vm, cookie_checker_t *cc, message_macs_t *cm, uint8_t nonce[COOKIE_NONCE_SIZE], -- cgit 1.2.3-korg