From patchwork Thu Nov 16 03:09:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steffan Karger X-Patchwork-Id: 84 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director3.mail.ord1d.rsapps.net ([172.30.191.6]) by backend31.mail.ord1d.rsapps.net (Dovecot) with LMTP id 1dBqCIScDVqTYgAAgoeIoA for ; Thu, 16 Nov 2017 09:11:16 -0500 Received: from proxy18.mail.ord1d.rsapps.net ([172.30.191.6]) by director3.mail.ord1d.rsapps.net (Dovecot) with LMTP id gyWgKIScDVqcCAAAkXNnRw ; Thu, 16 Nov 2017 09:11:16 -0500 Received: from smtp43.gate.ord1c ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy18.mail.ord1d.rsapps.net (Dovecot) with LMTP id /m48AoScDVqALgAATCaURg ; Thu, 16 Nov 2017 09:11:16 -0500 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.34.181.88] Authentication-Results: smtp43.gate.ord1c.rsapps.net; iprev=pass policy.iprev="216.34.181.88"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dkim=fail (signature verification failed) header.d=karger-me.20150623.gappssmtp.com; dmarc=none (p=nil; dis=none) header.from=karger.me X-Classification-ID: 02037aa8-cad8-11e7-87dc-bc305befc478-1-1 Received: from [216.34.181.88] ([216.34.181.88:52914] helo=lists.sourceforge.net) by smtp43.gate.ord1c.rsapps.net (envelope-from ) (ecelerity 4.2.1.56364 r(Core:4.2.1.14)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id BE/C4-35534-38C9D0A5; Thu, 16 Nov 2017 09:11:15 -0500 Received: from localhost ([127.0.0.1] helo=sfs-ml-3.v29.ch3.sourceforge.com) by sfs-ml-3.v29.ch3.sourceforge.com with esmtp (Exim 4.89) (envelope-from ) id 1eFKrw-0002nW-IM; Thu, 16 Nov 2017 14:10:16 +0000 Received: from sfi-mx-1.v28.ch3.sourceforge.com ([172.29.28.191] helo=mx.sourceforge.net) by sfs-ml-3.v29.ch3.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.89) (envelope-from ) id 1eFKru-0002nM-8P for openvpn-devel@lists.sourceforge.net; Thu, 16 Nov 2017 14:10:14 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Sender:Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=59qsJZbUKi36eXoCPZ1b63CQxflOB1rAhbbhYzr5CiU=; b=b/1odhaGHPOrWfQrFF15FEW7rS 7BFBFzgYDp8WgR6+gLVSfTcKyjOzSO3pBFZQUfkIONGWk9OU34os0EwY4fg5tEgNOPNgceQxGvpvZ 02DqcR1uoe6cyLixRKzgUeDPyd8DHFSs4Kn3AcQbekErLRA7WOre5SDbapKsLZsZch74=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To :MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=59qsJZbUKi36eXoCPZ1b63CQxflOB1rAhbbhYzr5CiU=; b=KMsGcEZ0BVpvUIkIyF8zXA1MLR iKVj3dn6o0zGoKxVi0YFzbjVRBn57lxEqxueTVdx6VqhzDEfstWr72HCmOzsXSbEnmrmhpW7KJbsX iIInJOQmPFC0mcLQ70Ox5+nWKqMbtUPUFH/v4Jh9PtTSdXpnBXs0ahDIS3OuNDnlTRAg=; Received: from mail-wm0-f49.google.com ([74.125.82.49]) by sfi-mx-1.v28.ch3.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.89) id 1eFKrn-0008Df-Ly for openvpn-devel@lists.sourceforge.net; Thu, 16 Nov 2017 14:10:14 +0000 Received: by mail-wm0-f49.google.com with SMTP id x63so260157wmf.2 for ; Thu, 16 Nov 2017 06:10:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=karger-me.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=59qsJZbUKi36eXoCPZ1b63CQxflOB1rAhbbhYzr5CiU=; b=wOW9/2ffOBWeNLnqIfu6JxM1Zkm4CKfPD1g0ufezIdrg+9u+2BIEvWGz6HV2g1nYT5 de6nc1bby51LQfBXw8ePa7MHEdqX9j/MmeErOV6uhYhDpFZN2Ex6BBLkw99v6RwNi5uf qPOdfcVhLX8kFtamHf6RsRf8AhW+RTARJkzmF3NfW6a9Yle6ffYiE3n7D9EPcXSTT6Kf VISYfxgch13Ho2n4ccAZ0KAx09dE5e3RdqF+002N8WHizgi4GXJNHyBbxwNynwoAI6KN /fQXUo1n1IqVDrKOL6+/FlGHNuKjuS19Im55CJEyC9kr3HPKHdTHyYS8UodCPf+AdPZG 7ZVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=59qsJZbUKi36eXoCPZ1b63CQxflOB1rAhbbhYzr5CiU=; b=rYXQs2jyZUs4SSVF1kNgjlabIsb2UZmtg15fiMddOJi5DstVqswOVhkd7XIwlpoURm m4I2P0pZVbv8E/AD164ats2l6PBP8oj0mghFTpvReNVXyRJamU8uTxEAIyQrtUw9iKea Ocqko4Ca2rGmnB8RfFT7SUgCvX0peuZVzE+PaSluzOuqEVmu9nBMGJ9lODVdG3o1YV8t K1q3nRjJHbTR0bc41/sFEtcRClNO5V0alKYZF9MOSah5+l79Bwi8SWy1iHr/GgHSp7Qj UkZzjSItF9UtE8UlgGsFyWicS3YycTjXXxQZ1nu98znSI/n7JS+Ou877/kqcw/O8nwko gxtg== X-Gm-Message-State: AJaThX4O9PwafcyM7ne+NOV6M/19J3pB4iCk66w0GqtnyMGmTo8UsUwR k3pG78dyMcwU4oONPXZVpSdz6jmqc8VS9A== X-Google-Smtp-Source: AGs4zMYnDRR0fyx9y91vNUxXUjkrrqILh+x85MwYv0LRXZzEmt/rUujoGTmJlJRpG2lw10M/A7hcvQ== X-Received: by 10.80.152.66 with SMTP id h2mr2919703edb.192.1510841401239; Thu, 16 Nov 2017 06:10:01 -0800 (PST) Received: from vesta.fritz.box ([2001:985:e54:1:b12c:a91a:d0c:7814]) by smtp.gmail.com with ESMTPSA id 3sm1178868edv.50.2017.11.16.06.09.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 16 Nov 2017 06:10:00 -0800 (PST) From: Steffan Karger To: openvpn-devel@lists.sourceforge.net Date: Thu, 16 Nov 2017 15:09:58 +0100 Message-Id: <20171116140958.12847-1-steffan@karger.me> X-Mailer: git-send-email 2.14.1 In-Reply-To: <830a17f8babbca92e21d64c1324a15b1.squirrel@webmail.bi.invoca.ch> References: <830a17f8babbca92e21d64c1324a15b1.squirrel@webmail.bi.invoca.ch> X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [74.125.82.49 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-Headers-End: 1eFKrn-0008Df-Ly Subject: [Openvpn-devel] [PATCH v4] Add per session pseudo-random jitter to --reneg-sec intervals X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox From: Simon Matter While we were suffering from the "TLS Renegotiation Slowdown" bug here https://community.openvpn.net/openvpn/ticket/854 we realized that there is still room for improvement in our use case. It appears that TLS renegotiation is getting more and more expensive in terms of CPU cycles with recent changes for more security. To make things worse, we realized that most renegotiation procedures took place at almost the same time and increased the CPU load too much during these periods. That's especially true on large, multi-instance openvpn setups. I've created attached patch to add a per session pseudo-random component to the --reneg-sec intervals so that renegotiation is evenly spread over time. It is configured by simply adding a second value to --reneg-sec as described in the --help text: --reneg-sec max [min] : Renegotiate data chan. key after at most max (default=3600) and at least min (default 90% of max on servers and equal to max on clients). The jitter is only enabled by default on servers, because the actual reneg time is min(reneg_server, reneg_client). Introducing jitter at both ends would bias the actual reneg time to the min value. Note that the patch also slightly changes the log output to show the sec value in the same way as the bytes/pkts values: TLS: soft reset sec=3084/3084 bytes=279897/-1 pkts=1370/0 The idea and first versions of this patch are from Simon Matter. Steffan Karger later incorporated the mailing list comments into this patch. So credits go to Simon, and all bugs are Steffan's fault ;-) Signed-off-by: Simon Matter Signed-off-by: Steffan Karger Acked-by: Gert Doering --- v3: incorporate comments from openvpn-devel@, don't add jitter by default on the client side. v4: fix printing of reneg interval, clarify/typofix comments doc/openvpn.8 | 26 +++++++++++++++++++++----- src/openvpn/init.c | 15 ++++++++++++++- src/openvpn/options.c | 11 +++++++++-- src/openvpn/options.h | 1 + src/openvpn/ssl.c | 6 +++--- 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/doc/openvpn.8 b/doc/openvpn.8 index a4189ac2..eb5258f9 100644 --- a/doc/openvpn.8 +++ b/doc/openvpn.8 @@ -33,7 +33,7 @@ .\" .ft -- normal face .\" .in +|-{n} -- indent .\" -.TH openvpn 8 "25 August 2016" +.TH openvpn 8 "04 April 2017" .\"********************************************************* .SH NAME openvpn \- secure IP tunnel daemon. @@ -4957,10 +4957,26 @@ Renegotiate data channel key after packets sent and received (disabled by default). .\"********************************************************* .TP -.B \-\-reneg\-sec n -Renegotiate data channel key after -.B n -seconds (default=3600). +.B \-\-reneg\-sec max [min] +Renegotiate data channel key after at most +.B max +seconds (default=3600) and at least +.B min +seconds (default is 90% of +.B max +for servers, and equal to +.B max +for clients). + +The effective +.B reneg\-sec +value used is per session pseudo-uniform-randomized between +.B min +and +.B max\fR. + +With the default value of 3600 this results in an effective per session value +in the range of 3240..3600 seconds for servers, or just 3600 for clients. When using dual\-factor authentication, note that this default value may cause the end user to be challenged to reauthorize once per hour. diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 1ed2c55e..a4dd2c87 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -2693,7 +2693,20 @@ do_init_crypto_tls(struct context *c, const unsigned int flags) to.packet_timeout = options->tls_timeout; to.renegotiate_bytes = options->renegotiate_bytes; to.renegotiate_packets = options->renegotiate_packets; - to.renegotiate_seconds = options->renegotiate_seconds; + if (options->renegotiate_seconds_min < 0) + { + /* Add 10% jitter to reneg-sec by default (server side only) */ + int auto_jitter = options->mode != MODE_SERVER ? 0 : + get_random() % max_int(options->renegotiate_seconds / 10, 1); + to.renegotiate_seconds = options->renegotiate_seconds - auto_jitter; + } + else + { + /* Add user-specified jitter to reneg-sec */ + to.renegotiate_seconds = options->renegotiate_seconds - + (get_random() % max_int(options->renegotiate_seconds + - options->renegotiate_seconds_min, 1)); + } to.single_session = options->single_session; to.mode = options->mode; to.pull = options->pull; diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 49ed004b..0a5c6a64 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -603,7 +603,9 @@ static const char usage_message[] = " if no ACK from remote within n seconds (default=%d).\n" "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and recvd.\n" "--reneg-pkts n : Renegotiate data chan. key after n packets sent and recvd.\n" - "--reneg-sec n : Renegotiate data chan. key after n seconds (default=%d).\n" + "--reneg-sec max [min] : Renegotiate data chan. key after at most max (default=%d)\n" + " and at least min (defaults to 90%% of max on servers and equal\n" + " to max on clients).\n" "--hand-window n : Data channel key exchange must finalize within n seconds\n" " of handshake initiation by any peer (default=%d).\n" "--tran-window n : Transition window -- old key can live this many seconds\n" @@ -870,6 +872,7 @@ init_options(struct options *o, const bool init_gc) o->tls_timeout = 2; o->renegotiate_bytes = -1; o->renegotiate_seconds = 3600; + o->renegotiate_seconds_min = -1; o->handshake_window = 60; o->transition_window = 3600; o->ecdh_curve = NULL; @@ -8001,10 +8004,14 @@ add_option(struct options *options, VERIFY_PERMISSION(OPT_P_TLS_PARMS); options->renegotiate_packets = positive_atoi(p[1]); } - else if (streq(p[0], "reneg-sec") && p[1] && !p[2]) + else if (streq(p[0], "reneg-sec") && p[1] && !p[3]) { VERIFY_PERMISSION(OPT_P_TLS_PARMS); options->renegotiate_seconds = positive_atoi(p[1]); + if (p[2]) + { + options->renegotiate_seconds_min = positive_atoi(p[2]); + } } else if (streq(p[0], "hand-window") && p[1] && !p[2]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 496c1143..a74dc94d 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -548,6 +548,7 @@ struct options int renegotiate_bytes; int renegotiate_packets; int renegotiate_seconds; + int renegotiate_seconds_min; /* Data channel key handshake must finalize * within n seconds of handshake initiation. */ diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index cb94229a..27f81cf3 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -2732,9 +2732,9 @@ tls_process(struct tls_multi *multi, && ks->n_packets >= session->opt->renegotiate_packets) || (packet_id_close_to_wrapping(&ks->crypto_options.packet_id.send)))) { - msg(D_TLS_DEBUG_LOW, - "TLS: soft reset sec=%d bytes=" counter_format "/%d pkts=" counter_format "/%d", - (int)(ks->established + session->opt->renegotiate_seconds - now), + msg(D_TLS_DEBUG_LOW, "TLS: soft reset sec=%d/%d bytes=" counter_format + "/%d pkts=" counter_format "/%d", + (int) (now - ks->established), session->opt->renegotiate_seconds, ks->n_bytes, session->opt->renegotiate_bytes, ks->n_packets, session->opt->renegotiate_packets); key_state_soft_reset(session);