From patchwork Thu Dec 3 12:08:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Erik Kapfer X-Patchwork-Id: 3698 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 4CmvkD34D5z3wpp for ; Thu, 3 Dec 2020 12:08:20 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail02.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 4Cmvk856Nwz1pb; Thu, 3 Dec 2020 12:08:16 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 4Cmvk71MGkz2xmW; Thu, 3 Dec 2020 12:08:15 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 4Cmvk610vwz2xWR for ; Thu, 3 Dec 2020 12:08:14 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by mail01.ipfire.org (Postfix) with ESMTPSA id 4Cmvk52Wvrz5s; Thu, 3 Dec 2020 12:08:13 +0000 (UTC) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003ed25519; t=1606997293; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=a1zIWE4uXfxmbmBwcglRIGzOJ6DgzyzXGwgh+V22Zek=; b=FPQqPuKkTfysNHFcCKlWWsupqY6A1X/lHvlPjekE9DZSyCk4VcPXhy2l+Fz1NVhFCXS7gk a0sU9HotEm7JWADA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003rsa; t=1606997293; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=a1zIWE4uXfxmbmBwcglRIGzOJ6DgzyzXGwgh+V22Zek=; b=SIb17ZT3A3yHODONURY6Y5dbR9FlrGt87B4Xwnj7eARqLwGIzazh8Elux0oNyO6MlbRj1w ETlz9EADGryfEDd6AjBpz7pi9R/L+1aUW8lu8anrA/P2bPTQcECB6AJu6NEuWyX4bGGznx +Hk4ueOCMEj7yxvKZqZy08Ay8jEsQjJk5H86BbBrI7FqgyHbvZmzcifGlsM5j4+6LLH54D vOXTIJko2QmovQ4oI9DSmARAW2LI8+toy3c8gv08QMCjV2dxqCczj2oZ7Z3MXxGLneYE/q GIQgf+4OC02986zv5Q2Ozpxs1OqW4CzUeKojRwuYh1J8j+bBP9rHqhEwRazJYg== From: ummeegge To: development@lists.ipfire.org Subject: [PATCH 1/3] OpenVPN: Introduce advanced encryption section Date: Thu, 3 Dec 2020 12:08:05 +0000 Message-Id: <20201203120807.20694-1-erik.kapfer@ipfire.org> MIME-Version: 1.0 X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" - The whole crypto section has been outsorted from the global section to an extra page. - Since --cipher is deprecated and will be handled via --data-cipher-fallback, the VAR name and the index has been kept but renamed from --cipher to --data-cipher-fallback. Old default AES-256-CBC has also been kept. - The new directive --data-ciphers has been introduced for RWs which negotiates now between the GCM family and the new CHACHA20-POLY1305. All ciphers can be combined. - The new directive --data-ciphers substitutes --ncp-disable, there --ncp-disable has been removed which fixes the deprecation warning in the updated OpenVPN-2.5.0. - While client generation the client version can be set which enables, if client is >=2.5.0 a full cipher negotiation. Existing clients can also subsequently be enhanced via edit. - The new ciphers and HMACs as been completely integrated into N2N environment without further modification. Code for update process via update.sh needs to be integrated: /usr/local/bin/openvpnctrl -k > /dev/null if grep -q 'cipher' /var/ipfire/ovpn/server.conf; then sed -i 's/cipher/data-ciphers-fallback/' /var/ipfire/ovpn/server.conf fi /usr/local/bin/openvpnctrl -s > /dev/null Signed-off-by: ummeegge --- html/cgi-bin/ovpnmain.cgi | 330 ++++++++++++++++++++++++++++---------- langs/de/cgi-bin/de.pl | 11 +- langs/en/cgi-bin/en.pl | 11 +- 3 files changed, 269 insertions(+), 83 deletions(-) diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-bin/ovpnmain.cgi index 68a70d147..fc4c6193a 100644 --- a/html/cgi-bin/ovpnmain.cgi +++ b/html/cgi-bin/ovpnmain.cgi @@ -75,6 +75,7 @@ my $name; my $col=""; my $local_serverconf = "${General::swroot}/ovpn/scripts/server.conf.local"; my $local_clientconf = "${General::swroot}/ovpn/scripts/client.conf.local"; +my @advcipherchar=(); &General::readhash("${General::swroot}/ethernet/settings", \%netsettings); $cgiparams{'ENABLED'} = 'off'; @@ -98,6 +99,7 @@ $cgiparams{'number'} = ''; $cgiparams{'DCIPHER'} = ''; $cgiparams{'DAUTH'} = ''; $cgiparams{'TLSAUTH'} = ''; +$cgiparams{'DATACIPHERS'} = ''; $routes_push_file = "${General::swroot}/ovpn/routes_push"; # Perform crypto and configration test &pkiconfigcheck; @@ -325,8 +327,16 @@ sub writeserverconf { } print CONF "status-version 1\n"; print CONF "status /var/run/ovpnserver.log 30\n"; - print CONF "ncp-disable\n"; - print CONF "cipher $sovpnsettings{DCIPHER}\n"; + print CONF "data-ciphers-fallback $sovpnsettings{DCIPHER}\n"; + + # Data channel encryption + # Set seperator for data ciphers + @advcipherchar = ($sovpnsettings{'DATACIPHERS'} =~ s/\|/:/g); + # Add also algorithm from --cipher directive + if ($sovpnsettings{'DATACIPHERS'} ne '') { + print CONF "data-ciphers $sovpnsettings{'DATACIPHERS'}\n"; + } + print CONF "auth $sovpnsettings{'DAUTH'}\n"; # Set TLSv2 as minimum print CONF "tls-version-min 1.2\n"; @@ -911,6 +921,28 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) { &writeserverconf();#hier ok } +### +### Save Advanced encryption +### + +if ($cgiparams{'ACTION'} eq $Lang::tr{'save-enc-options'}) { + &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings); + + $vpnsettings{'DCIPHER'} = $cgiparams{'DCIPHER'}; + $vpnsettings{'DATACIPHERS'} = $cgiparams{'DATACIPHERS'}; + + # --data-ciphers needs at least one cipher + if ($cgiparams{'DATACIPHERS'} eq '') { + $errormessage = $Lang::tr{'ovpn errmsg invalid data cipher input'}; + goto ADV_ENC_ERROR; + } + + &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings); + &writeserverconf(); +} + +### End Save advanced encryption + ### # m.a.d net2net ### @@ -982,10 +1014,11 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General print SERVERCONF "# Cipher\n"; print SERVERCONF "cipher $cgiparams{'DCIPHER'}\n"; - # If GCM cipher is used, do not use --auth + # If AEAD cipher is used, do not use --auth if (($cgiparams{'DCIPHER'} eq 'AES-256-GCM') || ($cgiparams{'DCIPHER'} eq 'AES-192-GCM') || - ($cgiparams{'DCIPHER'} eq 'AES-128-GCM')) { + ($cgiparams{'DCIPHER'} eq 'AES-128-GCM') || + ($cgiparams{'DCIPHER'} eq 'ChaCha20-Poly1305')) { print SERVERCONF unless "# HMAC algorithm\n"; print SERVERCONF unless "auth $cgiparams{'DAUTH'}\n"; } else { @@ -1087,10 +1120,11 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General print CLIENTCONF "cipher $cgiparams{'DCIPHER'}\n"; print CLIENTCONF "pkcs12 ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}.p12\r\n"; - # If GCM cipher is used, do not use --auth + # If AEAD cipher is used, do not use --auth if (($cgiparams{'DCIPHER'} eq 'AES-256-GCM') || ($cgiparams{'DCIPHER'} eq 'AES-192-GCM') || - ($cgiparams{'DCIPHER'} eq 'AES-128-GCM')) { + ($cgiparams{'DCIPHER'} eq 'AES-128-GCM') || + ($cgiparams{'DCIPHER'} eq 'ChaCha20-Poly1305')) { print CLIENTCONF unless "# HMAC algorithm\n"; print CLIENTCONF unless "auth $cgiparams{'DAUTH'}\n"; } else { @@ -1214,7 +1248,6 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg $vpnsettings{'DDEST_PORT'} = $cgiparams{'DDEST_PORT'}; $vpnsettings{'DMTU'} = $cgiparams{'DMTU'}; $vpnsettings{'DCOMPLZO'} = $cgiparams{'DCOMPLZO'}; - $vpnsettings{'DCIPHER'} = $cgiparams{'DCIPHER'}; $vpnsettings{'DAUTH'} = $cgiparams{'DAUTH'}; $vpnsettings{'TLSAUTH'} = $cgiparams{'TLSAUTH'}; #wrtie enable @@ -2344,7 +2377,15 @@ else $zip->addFile( "${General::swroot}/ovpn/ca/cacert.pem", "cacert.pem") or die "Can't add file cacert.pem\n"; $zip->addFile( "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem", "$confighash{$cgiparams{'KEY'}}[1]cert.pem") or die "Can't add file $confighash{$cgiparams{'KEY'}}[1]cert.pem\n"; } - print CLIENTCONF "cipher $vpnsettings{DCIPHER}\r\n"; + + # Set --data-ciphers for client >=2.5.0 or --cipher for <2.5.0 + if ($confighash{$cgiparams{'KEY'}}[45] eq 'on') { + @advcipherchar = ($vpnsettings{'DATACIPHERS'} =~ s/\|/:/g); + print CLIENTCONF "data-ciphers $vpnsettings{'DATACIPHERS'}\r\n"; + } else { + print CLIENTCONF "cipher $vpnsettings{'DCIPHER'}\r\n"; + } + print CLIENTCONF "auth $vpnsettings{'DAUTH'}\r\n"; if ($vpnsettings{'TLSAUTH'} eq 'on') { @@ -2859,7 +2900,169 @@ END &Header::closebigbox(); &Header::closepage(); exit(0); - + +### +### Advanced encryption settings +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'ovpn advanced encryption'}) { + %cgiparams = (); + %confighash = (); + my @temp=(); + my $disabled; + &General::readhash("${General::swroot}/ovpn/settings", \%cgiparams); + + my $key = $cgiparams{'KEY'}; + if (! $key) { + $key = &General::findhasharraykey (\%confighash); + foreach my $i (39.. 45) { $confighash{$key}[$i] = ""; } + } + $confighash{$key}[40] = $cgiparams{'DCIPHER'}; + $confighash{$key}[42] = $cgiparams{'DATACIPHERS'}; + +ADV_ENC_ERROR: + + # Set default for data-cipher-fallback (the old --cipher directive) + if ($cgiparams{'DCIPHER'} eq '') { + $cgiparams{'DCIPHER'} = 'AES-256-CBC'; #[40] + } + $checked{'DCIPHER'}{'AES-256-CBC'} = ''; + $checked{'DCIPHER'}{'AES-192-CBC'} = ''; + $checked{'DCIPHER'}{'AES-128-CBC'} = ''; + $checked{'DCIPHER'}{'CAMELLIA-256-CBC'} = ''; + $checked{'DCIPHER'}{'CAMELLIA-192-CBC'} = ''; + $checked{'DCIPHER'}{'CAMELLIA-128-CBC'} = ''; + $checked{'DCIPHER'}{'SEED-CBC'} = ''; + $checked{'DCIPHER'}{'DES-EDE3-CBC'} = ''; + $checked{'DCIPHER'}{'DESX-CBC'} = ''; + $checked{'DCIPHER'}{'DES-EDE-CBC'} = ''; + $checked{'DCIPHER'}{'BF-CBC'} = ''; + $checked{'DCIPHER'}{'CAST5-CBC'} = ''; + @temp = split('\|', $cgiparams{'DCIPHER'}); + foreach my $key (@temp) {$checked{'DCIPHER'}{$key} = "selected='selected'"; } + + # Set default data channel ciphers + if ($cgiparams{'DATACIPHERS'} eq '') { + $cgiparams{'DATACIPHERS'} = 'ChaCha20-Poly1305|AES-256-GCM'; #[42]; + } + $checked{'DATACIPHERS'}{'ChaCha20-Poly1305'} = ''; + $checked{'DATACIPHERS'}{'AES-256-GCM'} = ''; + $checked{'DATACIPHERS'}{'AES-192-GCM'} = ''; + $checked{'DATACIPHERS'}{'AES-128-GCM'} = ''; + @temp = split('\|', $cgiparams{'DATACIPHERS'}); + foreach my $key (@temp) {$checked{'DATACIPHERS'}{$key} = "selected='selected'"; } + + # Save settings and display default if not configured + if ($cgiparams{'ACTION'} eq $Lang::tr{'save-enc-options'}) { + $confighash{$cgiparams{'KEY'}}[40] = $cgiparams{'DCIPHER'}; + $confighash{$cgiparams{'KEY'}}[42] = $cgiparams{'DATACIPHERS'}; + } else { + $cgiparams{'DCIPHER'} = $vpnsettings{'DCIPHER'}; + $cgiparams{'DATACIPHERS'} = $vpnsettings{'DATACIPHERS'}; + } + +ADV_ENC_ERROR: + + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'ovpn'}, 1, ''); + &Header::openbigbox('100%', 'left', '', $errormessage); + if ($errormessage) { + &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); + print "$errormessage"; + print " "; + &Header::closebox(); + } + if ($warnmessage) { + &Header::openbox('100%', 'left', "$Lang::tr{'warning messages'}:"); + print "$warnmessage"; + print " "; + &Header::closebox(); + } + print "
"; + &Header::openbox('100%', 'left', "$Lang::tr{'ovpn advanced encryption'}:"); + print< + + + + + + + + + + + + + + + + + + +
$Lang::tr{'ovpn data channel'}$Lang::tr{'ovpn data channel fallback'}
$Lang::tr{'ovpn data encryption'} + + + +
+
+END +; + if ( -e "/var/run/openvpn.pid") { + print"
$Lang::tr{'attention'}:
$Lang::tr{'server restart'}


"; + print< + +   + + +   + + + +END +; + + } else { + print< + +   + + +   + + + +END +; + + } + + &Header::closebox(); + &Header::closebigbox(); + &Header::closepage(); + exit(0); + +### END advanced encryption # A.Marx CCD Add,delete or edit CCD net @@ -3595,6 +3798,8 @@ if ($confighash{$cgiparams{'KEY'}}) { $cgiparams{'DAUTH'} = $confighash{$cgiparams{'KEY'}}[39]; $cgiparams{'DCIPHER'} = $confighash{$cgiparams{'KEY'}}[40]; $cgiparams{'TLSAUTH'} = $confighash{$cgiparams{'KEY'}}[41]; + # Index from [39] to [44] has been reserved by advanced encryption + $cgiparams{'CLIENTVERSION'} = $confighash{$cgiparams{'KEY'}}[45]; } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) { $cgiparams{'REMARK'} = &Header::cleanhtml($cgiparams{'REMARK'}); @@ -4338,6 +4543,8 @@ if ($cgiparams{'TYPE'} eq 'net') { if (($cgiparams{'TYPE'} eq 'host') && ($cgiparams{'CERT_PASS1'} eq "")) { $confighash{$key}[41] = "no-pass"; } + # Index from [39] to [44] has been reserved by advanced encryption + $confighash{$key}[45] = $cgiparams{'CLIENTVERSION'}; &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); @@ -4508,28 +4715,6 @@ if ($cgiparams{'TYPE'} eq 'net') { $checked{'MSSFIX'}{'on'} = ''; $checked{'MSSFIX'}{$cgiparams{'MSSFIX'}} = 'CHECKED'; - $selected{'DCIPHER'}{'AES-256-GCM'} = ''; - $selected{'DCIPHER'}{'AES-192-GCM'} = ''; - $selected{'DCIPHER'}{'AES-128-GCM'} = ''; - $selected{'DCIPHER'}{'CAMELLIA-256-CBC'} = ''; - $selected{'DCIPHER'}{'CAMELLIA-192-CBC'} = ''; - $selected{'DCIPHER'}{'CAMELLIA-128-CBC'} = ''; - $selected{'DCIPHER'}{'AES-256-CBC'} = ''; - $selected{'DCIPHER'}{'AES-192-CBC'} = ''; - $selected{'DCIPHER'}{'AES-128-CBC'} = ''; - $selected{'DCIPHER'}{'DESX-CBC'} = ''; - $selected{'DCIPHER'}{'SEED-CBC'} = ''; - $selected{'DCIPHER'}{'DES-EDE3-CBC'} = ''; - $selected{'DCIPHER'}{'DES-EDE-CBC'} = ''; - $selected{'DCIPHER'}{'CAST5-CBC'} = ''; - $selected{'DCIPHER'}{'BF-CBC'} = ''; - $selected{'DCIPHER'}{'DES-CBC'} = ''; - # If no cipher has been chossen yet, select - # the old default (AES-256-CBC) for compatiblity reasons. - if ($cgiparams{'DCIPHER'} eq '') { - $cgiparams{'DCIPHER'} = 'AES-256-CBC'; - } - $selected{'DCIPHER'}{$cgiparams{'DCIPHER'}} = 'SELECTED'; $selected{'DAUTH'}{'whirlpool'} = ''; $selected{'DAUTH'}{'SHA512'} = ''; $selected{'DAUTH'}{'SHA384'} = ''; @@ -4595,11 +4780,12 @@ if ($cgiparams{'TYPE'} eq 'net') { print ""; } - # If GCM ciphers are in usage, HMAC menu is disabled + # If AEAD ciphers are in usage, HMAC menu is disabled my $hmacdisabled; if (($confighash{$cgiparams{'KEY'}}[40] eq 'AES-256-GCM') || ($confighash{$cgiparams{'KEY'}}[40] eq 'AES-192-GCM') || - ($confighash{$cgiparams{'KEY'}}[40] eq 'AES-128-GCM')) { + ($confighash{$cgiparams{'KEY'}}[40] eq 'AES-128-GCM') || + ($confighash{$cgiparams{'KEY'}}[40] eq 'ChaCha20-Poly1305')) { $hmacdisabled = "disabled='disabled'"; }; @@ -4673,9 +4859,10 @@ if ($cgiparams{'TYPE'} eq 'net') { $Lang::tr{'cipher'} - + + + + + + @@ -4713,7 +4905,7 @@ print< var disable_options = false; document.getElementById('n2ncipher').onchange = function () { - if((this.value == "AES-256-GCM"||this.value == "AES-192-GCM"||this.value == "AES-128-GCM")) { + if((this.value == "AES-256-GCM"||this.value == "AES-192-GCM"||this.value == "AES-128-GCM"||this.value == "CHACHA20-POLY1305")) { document.getElementById('n2nhmac').setAttribute('disabled', true); } else { document.getElementById('n2nhmac').removeAttribute('disabled'); @@ -4749,6 +4941,7 @@ if ($cgiparams{'TYPE'} eq 'host') { print"

"; my $name=$cgiparams{'CHECK1'}; $checked{'RG'}{$cgiparams{'RG'}} = 'CHECKED'; + $checked{'CLIENTVERSION'}{$cgiparams{'CLIENTVERSION'}} = 'CHECKED'; if (! -z "${General::swroot}/ovpn/ccd.conf"){ print""; @@ -4884,7 +5077,13 @@ if ($cgiparams{'TYPE'} eq 'host') { print < - + + + + + +
$Lang::tr{'ccd name'}$Lang::tr{'network'}$Lang::tr{'ccd clientip'}
Redirect Gateway:
Redirect Gateway:
$Lang::tr{'ovpn client version 25 cipher negotiation'}: +  $Lang::tr{'ovpn client version 25 warning'}

$Lang::tr{'ccd routes'}
 
$Lang::tr{'ccd iroute'}