From patchwork Tue May 10 07:07:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arne Schwabe X-Patchwork-Id: 2444 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director7.mail.ord1d.rsapps.net ([172.27.255.52]) by backend41.mail.ord1d.rsapps.net with LMTP id 8F/3HCGcemLENAAAqwncew (envelope-from ) for ; Tue, 10 May 2022 13:08:49 -0400 Received: from proxy9.mail.iad3a.rsapps.net ([172.27.255.52]) by director7.mail.ord1d.rsapps.net with LMTP id UEIoMSGcemKbNAAAovjBpQ (envelope-from ) for ; Tue, 10 May 2022 13:08:49 -0400 Received: from smtp14.gate.iad3a ([172.27.255.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy9.mail.iad3a.rsapps.net with LMTPS id sIOPKCGcemLIIAAAGuSQww (envelope-from ) for ; Tue, 10 May 2022 13:08:49 -0400 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.105.38.7] Authentication-Results: smtp14.gate.iad3a.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; 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; dmarc=none (p=nil; dis=none) header.from=rfc2549.org X-Suspicious-Flag: YES X-Classification-ID: db7e7660-d083-11ec-8a5d-5254005d41e3-1-1 Received: from [216.105.38.7] ([216.105.38.7:54154] helo=lists.sourceforge.net) by smtp14.gate.iad3a.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 53/03-09692-02C9A726; Tue, 10 May 2022 13:08:49 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.94.2) (envelope-from ) id 1noTKy-0002Mk-Nr; Tue, 10 May 2022 17:07:51 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1noTKx-0002Me-Ld for openvpn-devel@lists.sourceforge.net; Tue, 10 May 2022 17:07:50 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: 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=ook7Fn0UNXJ+vxj+o8/uHBl04NBcwwnlrWQqteTD4bY=; b=PAjII5/9ZRaZvfE+QrMnlB1VC2 L9OFQSm26ZUvaV+NwhDSIb7FIjZygPqlr7QBOThwyfZedqKG+Q/SFI53UDXoClmyUpWzRYbN/L9Py JAKFNY57AXVjHj21jK03Mhay2L5M71j9qR2335kIe3p4Fs9Y8F1Qs/xWw/Smq1xXbixk=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: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=ook7Fn0UNXJ+vxj+o8/uHBl04NBcwwnlrWQqteTD4bY=; b=E8na1TtAEu7bv1JrOPWbTbgafM ffXdRMmLzHfIEGLhmL5ocOIWe2mX+EFuehEj9UB8J8pX98xqPpNB3uCC7eDPQqes3ZC1bEK5u/HN5 b1CUkKaQAZ35tjVXepLHUtAeE4WmGUZ+8gRghVMcjTTOR1q5DU/asDkajL5XThOZ53jE=; Received: from mail.blinkt.de ([192.26.174.232]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.94.2) id 1noTKu-0003nI-CV for openvpn-devel@lists.sourceforge.net; Tue, 10 May 2022 17:07:49 +0000 Received: from kamera.blinkt.de ([2001:638:502:390:20c:29ff:fec8:535c]) by mail.blinkt.de with smtp (Exim 4.95 (FreeBSD)) (envelope-from ) id 1noTKn-000J7x-UV for openvpn-devel@lists.sourceforge.net; Tue, 10 May 2022 19:07:41 +0200 Received: (nullmailer pid 1856889 invoked by uid 10006); Tue, 10 May 2022 17:07:41 -0000 From: Arne Schwabe To: openvpn-devel@lists.sourceforge.net Date: Tue, 10 May 2022 19:07:41 +0200 Message-Id: <20220510170741.1856843-1-arne@rfc2549.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220422142953.3805364-17-arne@rfc2549.org> References: <20220422142953.3805364-17-arne@rfc2549.org> MIME-Version: 1.0 X-Spam-Report: Spam detection software, running on the system "util-spamd-2.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Currently control packet size is controlled by tun-mtu in a very non-obvious way since the control overhead is not taken into account and control channel packet will end up with a different size than [...] Content analysis details: (0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 T_SCC_BODY_TEXT_LINE No description available. X-Headers-End: 1noTKu-0003nI-CV Subject: [Openvpn-devel] [PATCH v2 26/28] Allow setting control channel packet size with tls-mtu 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox Currently control packet size is controlled by tun-mtu in a very non-obvious way since the control overhead is not taken into account and control channel packet will end up with a different size than data channel packet. Instead we decouple this and introduce tls-mtu which defaults to 1250. Patch v2: rebase on latest patch set Signed-off-by: Arne Schwabe --- Changes.rst | 8 ++++++++ doc/man-sections/link-options.rst | 7 +++++++ src/openvpn/init.c | 8 ++++++-- src/openvpn/mtu.h | 5 +++++ src/openvpn/options.c | 14 ++++++++++++++ src/openvpn/options.h | 1 + src/openvpn/ssl.c | 25 +++++++++++++------------ src/openvpn/ssl.h | 8 +++----- 8 files changed, 57 insertions(+), 19 deletions(-) diff --git a/Changes.rst b/Changes.rst index 67a23c792..f40fc09ae 100644 --- a/Changes.rst +++ b/Changes.rst @@ -79,6 +79,12 @@ Cookie based handshake for UDP server shake. The tls-crypt-v2 option allows controlling if older clients are accepted. +Improved control channel packet size control (``--tls-mtu``) + The size of control channel is no longer tied to + ``--link-mtu``/``--tun-mtu`` and can be set using ``--tls-mtu``. Setting + the size to small sizes no longer breaks the OpenVPN protocol in certain + situation. + Deprecated features ------------------- ``inetd`` has been removed @@ -141,6 +147,8 @@ User-visible Changes - Option ``--nobind`` is default when ``--client`` or ``--pull`` is used in the configuration - :code:`link_mtu` parameter is removed from environment or replaced with 0 when scripts are called with parameters. This parameter is unreliable and no longer internally calculated. +- control channel packet maximum size is no longer influenced by ``--link-mtu``/``--tun-mtu`` + and must be set by ``--tls-mtu`` now. Overview of changes in 2.5 ========================== diff --git a/doc/man-sections/link-options.rst b/doc/man-sections/link-options.rst index 6473ad423..b084fe082 100644 --- a/doc/man-sections/link-options.rst +++ b/doc/man-sections/link-options.rst @@ -454,3 +454,10 @@ the local and the remote host. if mode server: socket-flags TCP_NODELAY push "socket-flags TCP_NODELAY" + +--tls-mtu size + This option sets the maximum size for control channel packets. OpenVPN will + try to keep its control channel messages below this size but due to some + constraints in the protocol this is not always possible. If the option is + not set, it default to 1250. Valid sizes are between 512 and 2048. + The maximum packet size includes encapsalution overhead like UDP and IP. \ No newline at end of file diff --git a/src/openvpn/init.c b/src/openvpn/init.c index b0c62a859..c86866219 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -2451,6 +2451,10 @@ frame_finalize_options(struct context *c, const struct options *o) * space */ size_t payload_size = max_int(1500, frame->tun_mtu); + /* we need to be also large enough to hold larger control channel packets + * if configured */ + payload_size = max_int(payload_size, o->ce.tls_mtu); + /* The extra tun needs to be added to the payload size */ if (o->ce.tun_mtu_defined) { @@ -2987,7 +2991,7 @@ do_init_frame_tls(struct context *c) { if (c->c2.tls_multi) { - tls_multi_init_finalize(c->c2.tls_multi, &c->c2.frame); + tls_multi_init_finalize(c->c2.tls_multi, c->options.ce.tls_mtu); ASSERT(c->c2.tls_multi->opt.frame.buf.payload_size <= c->c2.frame.buf.payload_size); frame_print(&c->c2.tls_multi->opt.frame, D_MTU_INFO, @@ -2995,7 +2999,7 @@ do_init_frame_tls(struct context *c) } if (c->c2.tls_auth_standalone) { - tls_init_control_channel_frame_parameters(&c->c2.frame, &c->c2.tls_auth_standalone->frame); + tls_init_control_channel_frame_parameters(&c->c2.tls_auth_standalone->frame, c->options.ce.tls_mtu); frame_print(&c->c2.tls_auth_standalone->frame, D_MTU_INFO, "TLS-Auth MTU parms"); c->c2.tls_auth_standalone->tls_wrap.work = alloc_buf_gc(BUF_SIZE(&c->c2.frame), &c->c2.gc); diff --git a/src/openvpn/mtu.h b/src/openvpn/mtu.h index 7f967e066..86959bd53 100644 --- a/src/openvpn/mtu.h +++ b/src/openvpn/mtu.h @@ -79,6 +79,11 @@ */ #define MSSFIX_DEFAULT 1492 +/* + * Default maximum size of control channel packets + */ +#define TLS_MTU_DEFAULT 1250 + /* * Alignment of payload data such as IP packet or * ethernet frame. diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 9ff384d09..d156e0ed1 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -815,6 +815,7 @@ init_options(struct options *o, const bool init_gc) o->ce.bind_local = true; o->ce.tun_mtu = TUN_MTU_DEFAULT; o->ce.link_mtu = LINK_MTU_DEFAULT; + o->ce.tls_mtu = TLS_MTU_DEFAULT; o->ce.mtu_discover_type = -1; o->ce.mssfix = 0; o->ce.mssfix_default = true; @@ -1582,6 +1583,7 @@ show_connection_entry(const struct connection_entry *o) SHOW_BOOL(link_mtu_defined); SHOW_INT(tun_mtu_extra); SHOW_BOOL(tun_mtu_extra_defined); + SHOW_INT(tls_mtu); SHOW_INT(mtu_discover_type); @@ -6281,6 +6283,18 @@ add_option(struct options *options, options->ce.tun_mtu_extra = positive_atoi(p[1]); options->ce.tun_mtu_extra_defined = true; } + else if (streq(p[0], "tls-mtu") && p[1] && !p[2]) + { + VERIFY_PERMISSION(OPT_P_MTU|OPT_P_CONNECTION); + int tls_mtu = atoi(p[1]); + if (tls_mtu < 512 || tls_mtu > TLS_CHANNEL_BUF_SIZE) + { + msg(msglevel, "Bad tls-mtu value, must be between %d and %d", + 512, TLS_CHANNEL_BUF_SIZE); + goto err; + } + options->ce.tls_mtu = positive_atoi(p[1]); + } #ifdef ENABLE_FRAGMENT else if (streq(p[0], "mtu-dynamic")) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index c2937dc37..6615d1c74 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -123,6 +123,7 @@ struct connection_entry bool tun_mtu_extra_defined; int link_mtu; /* MTU of device over which tunnel packets pass via TCP/UDP */ bool link_mtu_defined; /* true if user overriding parm with command line option */ + int tls_mtu; /* Maximum MTU for the control channel messages */ /* Advanced MTU negotiation and datagram fragmentation options */ int mtu_discover_type; /* used if OS supports setting Path MTU discovery options on socket */ diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 1e3c500d8..d1708c19b 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -296,8 +296,7 @@ tls_limit_reneg_bytes(const char *ciphername, int *reneg_bytes) } void -tls_init_control_channel_frame_parameters(const struct frame *data_channel_frame, - struct frame *frame) +tls_init_control_channel_frame_parameters(struct frame *frame, int tls_mtu) { /* * frame->extra_frame is already initialized with tls_auth buffer requirements, @@ -322,18 +321,20 @@ tls_init_control_channel_frame_parameters(const struct frame *data_channel_frame /* Previous OpenVPN version calculated the maximum size and buffer of a * control frame depending on the overhead of the data channel frame - * overhead and limited its maximum size to 1250. We always allocate the - * TLS_CHANNEL_BUF_SIZE buffer size since a lot of code blindly assumes - * a large buffer (e.g. PUSH_BUNDLE_SIZE) and also our peer might have - * a higher size configured and we still want to be able to receive the - * packets. frame->mtu_mtu is set as suggestion for the maximum packet - * size */ - frame->buf.payload_size = 1250 + overhead; + * overhead and limited its maximum size to 1250. Since control frame + * frames also need to fit into data channel buffer we have the same + * default of 1500 + 100 as data channel buffers have. Increasing + * tls-mtu beyond this limit also increases the data channel buffers */ + frame->buf.payload_size = max_int(1500, tls_mtu) + 100; frame->buf.headroom = overhead; frame->buf.tailroom = overhead; - frame->tun_mtu = min_int(data_channel_frame->tun_mtu, 1250); + frame->tun_mtu = tls_mtu; + + /* Ensure the tun-mtu stays in a valid range */ + frame->tun_mtu = min_int(frame->tun_mtu, TLS_CHANNEL_BUF_SIZE); + frame->tun_mtu = max_int(frame->tun_mtu, 512); } /** @@ -1299,9 +1300,9 @@ tls_multi_init(struct tls_options *tls_options) } void -tls_multi_init_finalize(struct tls_multi *multi, const struct frame *frame) +tls_multi_init_finalize(struct tls_multi *multi, int tls_mtu) { - tls_init_control_channel_frame_parameters(frame, &multi->opt.frame); + tls_init_control_channel_frame_parameters(&multi->opt.frame, tls_mtu); /* initialize the active and untrusted sessions */ tls_session_init(multi, &multi->session[TM_ACTIVE]); diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h index 0ba86d3e6..cab5f449e 100644 --- a/src/openvpn/ssl.h +++ b/src/openvpn/ssl.h @@ -156,10 +156,9 @@ struct tls_multi *tls_multi_init(struct tls_options *tls_options); * * @param multi - The \c tls_multi structure of which to finalize * initialization. - * @param frame - The data channel's \c frame structure. + * @param tls_mtu - maximum allowed size for control channel packets */ -void tls_multi_init_finalize(struct tls_multi *multi, - const struct frame *frame); +void tls_multi_init_finalize(struct tls_multi *multi, int tls_mtu); /* * Initialize a standalone tls-auth verification object. @@ -171,8 +170,7 @@ struct tls_auth_standalone *tls_auth_standalone_init(struct tls_options *tls_opt * Setups the control channel frame size parameters from the data channel * parameters */ -void tls_init_control_channel_frame_parameters(const struct frame *data_channel_frame, - struct frame *frame); +void tls_init_control_channel_frame_parameters(struct frame *frame, int tls_mtu); /* * Set local and remote option compatibility strings.