From ce91af8ad27e5ddef1e1f8316129bfcaa3de9ef6 Mon Sep 17 00:00:00 2001 From: Alexander Chernavin Date: Wed, 20 Jul 2022 12:43:42 +0000 Subject: wireguard: add dos mitigation support Type: feature With this change: - if the number of received handshake messages exceeds the limit calculated based on the peers number, under load state will activate; - if being under load a handshake message with a valid mac1 is received, but mac2 is invalid, a cookie reply will be sent. Also, cover these with tests. Signed-off-by: Alexander Chernavin Change-Id: I3003570a9cf807cfb0b5145b89a085455c30e717 --- src/plugins/wireguard/wireguard_input.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'src/plugins/wireguard/wireguard_input.c') diff --git a/src/plugins/wireguard/wireguard_input.c b/src/plugins/wireguard/wireguard_input.c index ef60d50c3da..3f546cc494f 100644 --- a/src/plugins/wireguard/wireguard_input.c +++ b/src/plugins/wireguard/wireguard_input.c @@ -32,6 +32,7 @@ _ (HANDSHAKE_SEND, "Failed while sending Handshake") \ _ (HANDSHAKE_RECEIVE, "Failed while receiving Handshake") \ _ (COOKIE_DECRYPTION, "Failed during Cookie decryption") \ + _ (COOKIE_SEND, "Failed during sending Cookie") \ _ (TOO_BIG, "Packet too big") \ _ (UNDEFINED, "Undefined error") \ _ (CRYPTO_ENGINE_ERROR, "crypto engine error (packet dropped)") @@ -173,7 +174,6 @@ wg_handshake_process (vlib_main_t *vm, wg_main_t *wmp, vlib_buffer_t *b, u16 udp_dst_port = clib_host_to_net_u16 (uhd->dst_port);; message_header_t *header = current_b_data; - under_load = false; if (PREDICT_FALSE (header->type == MESSAGE_HANDSHAKE_COOKIE)) { @@ -211,11 +211,13 @@ wg_handshake_process (vlib_main_t *vm, wg_main_t *wmp, vlib_buffer_t *b, if (NULL == wg_if) continue; + under_load = wg_if_is_under_load (vm, wg_if); mac_state = cookie_checker_validate_macs ( vm, &wg_if->cookie_checker, macs, current_b_data, len, under_load, &src_ip, udp_src_port); if (mac_state == INVALID_MAC) { + wg_if_dec_handshake_num (wg_if); wg_if = NULL; continue; } @@ -241,8 +243,16 @@ wg_handshake_process (vlib_main_t *vm, wg_main_t *wmp, vlib_buffer_t *b, if (packet_needs_cookie) { - // TODO: Add processing + + if (!wg_send_handshake_cookie (vm, message->sender_index, + &wg_if->cookie_checker, macs, + &ip_addr_46 (&wg_if->src_ip), + wg_if->port, &src_ip, udp_src_port)) + return WG_INPUT_ERROR_COOKIE_SEND; + + return WG_INPUT_ERROR_NONE; } + noise_remote_t *rp; if (noise_consume_initiation (vm, noise_local_get (wg_if->local_idx), &rp, @@ -271,6 +281,18 @@ wg_handshake_process (vlib_main_t *vm, wg_main_t *wmp, vlib_buffer_t *b, case MESSAGE_HANDSHAKE_RESPONSE: { message_handshake_response_t *resp = current_b_data; + + if (packet_needs_cookie) + { + if (!wg_send_handshake_cookie (vm, resp->sender_index, + &wg_if->cookie_checker, macs, + &ip_addr_46 (&wg_if->src_ip), + wg_if->port, &src_ip, udp_src_port)) + return WG_INPUT_ERROR_COOKIE_SEND; + + return WG_INPUT_ERROR_NONE; + } + index_t peeri = INDEX_INVALID; u32 *entry = wg_index_table_lookup (&wmp->index_table, resp->receiver_index); @@ -292,10 +314,6 @@ wg_handshake_process (vlib_main_t *vm, wg_main_t *wmp, vlib_buffer_t *b, { return WG_INPUT_ERROR_PEER; } - if (packet_needs_cookie) - { - // TODO: Add processing - } // set_peer_address (peer, ip4_src, udp_src_port); if (noise_remote_begin_session (vm, &peer->remote)) -- cgit 1.2.3-korg