openvpn: Actually apply configured parameters

Message ID 20201020132825.8416-1-michael.tremer@ipfire.org
State Accepted
Commit d6989b4b0b42937485f5008cda6cdd730275f1ec
Headers
Series openvpn: Actually apply configured parameters |

Commit Message

Michael Tremer Oct. 20, 2020, 1:28 p.m. UTC
  OpenVPN is an absolute mess. The behaviour of configuration
parameters has been changed over the time; default values have been
changed over time; and it looks like nobody is actually testing
anything any more.

I have been spending hours today on figuring out why OpenVPN
is so damn slow. On a Lightning Wire Labs IPFire Mini Appliance
it achieves about 100 MBit/s in the default configuration when
"openssl speed -evp aes-256-gcm" achieves over 3.5 GBit/s.

Changing any of the cryptography parameters does not change
anything. Throughput remains around 100 MBit/s.

I finally set "cipher none" and "auth none" which disables
encryption and authentication altogether but does not increase
throughput. From here on it was absolutely clear that it was
not a crypto issue.

OpenVPN tries to be smart here and does its own fragmentation.
This is the worst idea I have heard of all day, because that job
is normally done best by the OS.

Various settings which allow the user to "tune" this are grossly
ineffective - let alone it isn't even clear what I am supposed
to configure anywhere. Setting "fragment 1500" weirdly still
does not convince openvpn to generate a packet that is longer
than 1400 bytes. Who'd a thunk?

There is a number of other parameters to set the MTU or which
are related to it (tun-mtu, link-mtu, fragment, mssfix).

On top of all of this we have two "bugs" in ovpnmain.cgi which
are being fixed in this patch:

1) mssfix can be configured by the user. However, we always
   enable it in openvpn. The default is on, we only add "mssfix"
   which simply turns it on.
   It is now being disabled when the user has chosen so in the
   web UI. I do not know if this is backwards-compatible.

2) We cap the MTU (tun-mtu) at 1500 bytes when fragment is being
   used. So it becomes pointless that the user can this and the
   user is not being made aware of this when they hit the save
   button.
   This was added when we added path MTU discovery. Since that
   did not work and was removed, we can remove this now, too.

I archived a solid 500-600 MBit/s of goodput with these settings:

* Disable mssfix
* Set "fragment" to 0
* Set MTU to 9000

I am sure the MTU could be further increased to have bigger packets,
but I did not test how badly this will affect latency of the tunnel.

OpenVPN seems to only be able to handle a certain amount of packets
a second - no matter what. With larger packets, the throughput of
the tunnel increases, but latency might as well.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Cc: Erik Kapfer <erik.kapfer@ipfire.org>
Cc: Stefan Schantl <stefan.schantl@ipfire.org>
---
 html/cgi-bin/ovpnmain.cgi | 29 +++++++++--------------------
 1 file changed, 9 insertions(+), 20 deletions(-)
  

Comments

ummeegge Oct. 21, 2020, 4:22 p.m. UTC | #1
Hi Michael,

Am Dienstag, den 20.10.2020, 13:28 +0000 schrieb Michael Tremer:
> OpenVPN is an absolute mess. The behaviour of configuration
> parameters has been changed over the time; default values have been
> changed over time; and it looks like nobody is actually testing
> anything any more.
> 
> I have been spending hours today on figuring out why OpenVPN
> is so damn slow. On a Lightning Wire Labs IPFire Mini Appliance
> it achieves about 100 MBit/s in the default configuration when
> "openssl speed -evp aes-256-gcm" achieves over 3.5 GBit/s.
> 
> Changing any of the cryptography parameters does not change
> anything. Throughput remains around 100 MBit/s.
> 
> I finally set "cipher none" and "auth none" which disables
> encryption and authentication altogether but does not increase
> throughput. From here on it was absolutely clear that it was
> not a crypto issue.
> 
> OpenVPN tries to be smart here and does its own fragmentation.
> This is the worst idea I have heard of all day, because that job
> is normally done best by the OS.
> 
> Various settings which allow the user to "tune" this are grossly
> ineffective - let alone it isn't even clear what I am supposed
> to configure anywhere. Setting "fragment 1500" weirdly still
> does not convince openvpn to generate a packet that is longer
> than 1400 bytes. Who'd a thunk?
> 
> There is a number of other parameters to set the MTU or which
> are related to it (tun-mtu, link-mtu, fragment, mssfix).
> 
> On top of all of this we have two "bugs" in ovpnmain.cgi which
> are being fixed in this patch:
> 
> 1) mssfix can be configured by the user. However, we always
>    enable it in openvpn. The default is on, we only add "mssfix"
>    which simply turns it on.
>    It is now being disabled when the user has chosen so in the
>    web UI. I do not know if this is backwards-compatible.
> 
> 2) We cap the MTU (tun-mtu) at 1500 bytes when fragment is being
>    used. So it becomes pointless that the user can this and the
>    user is not being made aware of this when they hit the save
>    button.
>    This was added when we added path MTU discovery. Since that
>    did not work and was removed, we can remove this now, too.
> 
> I archived a solid 500-600 MBit/s of goodput with these settings:
> 
> * Disable mssfix
> * Set "fragment" to 0
> * Set MTU to 9000
We have had a discussion about that longer time ago -->
https://bugzilla.ipfire.org/show_bug.cgi?id=11364#c18
. Did not know that a MTU of 9000 is possible, sounds like jumbo
frames.

> 
> I am sure the MTU could be further increased to have bigger packets,
> but I did not test how badly this will affect latency of the tunnel.
> 
> OpenVPN seems to only be able to handle a certain amount of packets
> a second - no matter what. With larger packets, the throughput of
> the tunnel increases, but latency might as well.
> 
> Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
> Cc: Erik Kapfer <erik.kapfer@ipfire.org>
> Cc: Stefan Schantl <stefan.schantl@ipfire.org>
> ---
>  html/cgi-bin/ovpnmain.cgi | 29 +++++++++--------------------
>  1 file changed, 9 insertions(+), 20 deletions(-)
> 
> diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-bin/ovpnmain.cgi
> index e7bc505e7..e5bc45c1c 100644
> --- a/html/cgi-bin/ovpnmain.cgi
> +++ b/html/cgi-bin/ovpnmain.cgi
> @@ -280,14 +280,7 @@ sub writeserverconf {
>      print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n";
>      #print CONF "push \"route $netsettings{'GREEN_NETADDRESS'}
> $netsettings{'GREEN_NETMASK'}\"\n";
>  
> -    # Check if we are using mssfix, fragment and set the corretct
> mtu of 1500.
> -    # If we doesn't use one of them, we can use the configured mtu
> value.
> -    if ($sovpnsettings{'MSSFIX'} eq 'on') 
> -	{ print CONF "tun-mtu 1500\n"; }
> -    elsif ($sovpnsettings{'FRAGMENT'} ne '' &&
> $sovpnsettings{'DPROTOCOL'} ne 'tcp') 
> -	{ print CONF "tun-mtu 1500\n"; }
> -    else 
> -	{ print CONF "tun-mtu $sovpnsettings{'DMTU'}\n"; }
> +    print CONF "tun-mtu $sovpnsettings{'DMTU'}\n";
>  
>      if ($vpnsettings{'ROUTES_PUSH'} ne '') {
>  		@temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'});
> @@ -320,6 +313,8 @@ sub writeserverconf {
>      }
>      if ($sovpnsettings{MSSFIX} eq 'on') {
>  		print CONF "mssfix\n";
> +    } else {
> +		print CONF "mssfix 0\n";
>      }
>      if ($sovpnsettings{FRAGMENT} ne '' &&
> $sovpnsettings{'DPROTOCOL'} ne 'tcp') {
>  		print CONF "fragment $sovpnsettings{'FRAGMENT'}\n";
> @@ -975,7 +970,7 @@ unless(-d
> "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir
> "${General
>    if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu =
> $cgiparams{'MTU'}};
>    print SERVERCONF "tun-mtu $tunmtu\n";
>    if ($cgiparams{'FRAGMENT'} ne '') {print SERVERCONF "fragment
> $cgiparams{'FRAGMENT'}\n";} 
> -  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n";
> }; 
> +  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; }
> else { print SERVERCONF "mssfix 0\n" };
>    }
>  
>    print SERVERCONF "# Auth. Server\n"; 
> @@ -1074,7 +1069,7 @@ unless(-d
> "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir
> "${General
>    if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu =
> $cgiparams{'MTU'}};
>    print CLIENTCONF "tun-mtu $tunmtu\n";
>    if ($cgiparams{'FRAGMENT'} ne '') {print CLIENTCONF "fragment
> $cgiparams{'FRAGMENT'}\n";}
> -  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n";
> }; 
> +  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; }
> else { print CLIENTCONF "mssfix 0\n" };
>    }
>  
>    # Check host certificate if X509 is RFC3280 compliant.
> @@ -2204,7 +2199,7 @@ if ($confighash{$cgiparams{'KEY'}}[3] eq
> 'net'){
>     if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu = '1500'}
> else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]};
>     print CLIENTCONF "tun-mtu $tunmtu\n";
>     if ($confighash{$cgiparams{'KEY'}}[24] ne '') {print CLIENTCONF
> "fragment $confighash{$cgiparams{'KEY'}}[24]\n";}
> -   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF
> "mssfix\n";}
> +   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF
> "mssfix\n";} else { print CLIENTCONF "mssfix 0\n"; }
>     }
>     # Check host certificate if X509 is RFC3280 compliant.
>     # If not, old --ns-cert-type directive will be used.
> @@ -2285,15 +2280,7 @@ else
>      print CLIENTCONF "nobind\r\n";
>      print CLIENTCONF "dev tun\r\n";
>      print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n";
> -
> -    # Check if we are using fragment, mssfix and set MTU to 1500
> -    # or use configured value.
> -    if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne
> 'tcp' )
> -	{ print CLIENTCONF "tun-mtu 1500\r\n"; }
> -    elsif ($vpnsettings{MSSFIX} eq 'on')
> -	{ print CLIENTCONF "tun-mtu 1500\r\n"; }
> -    else
> -	{ print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n"; }
> +    print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n";
>  
>      if ( $vpnsettings{'ENABLED'} eq 'on'){
>      	print CLIENTCONF "remote $vpnsettings{'VPN_IP'}
> $vpnsettings{'DDEST_PORT'}\r\n";
> @@ -2383,6 +2370,8 @@ else
>      print CLIENTCONF "verify-x509-name
> $vpnsettings{ROOTCERT_HOSTNAME} name\r\n";
>      if ($vpnsettings{MSSFIX} eq 'on') {
>  	print CLIENTCONF "mssfix\r\n";
> +    } else {
> +	print CLIENTCONF "mssfix 0\r\n";
>      }
>      if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne
> 'tcp' ) {
>  	print CLIENTCONF "fragment $vpnsettings{'FRAGMENT'}\r\n";
  
Michael Tremer Oct. 23, 2020, 10:18 a.m. UTC | #2
Hello Erik,

Thank you for your prompt reply.

Interesting that we have talked about this that long ago. I totally forgot about that conversation, and I could not derive any actionable items from it.

I guess I have now implemented the option to actually disable mssfix.

The last post refers to this:

  https://sourceforge.net/p/openvpn/mailman/message/13218191/

A post from 2004 which simply says what has to be done - ideally. The problem with that only is that it is incredibly slow - presumably because of implementation issues.

If VPNs are slow, people tend to stop using them. That will of course expose them to loads of security issues.

So what can we do here? I have no idea apart from adding this patch, so that the user has at least some kind of choice.

Do you think this will be backwards-compatible, or are we going to break installations if we were to accept the patch?

Best,
-Michael

> On 21 Oct 2020, at 17:22, ummeegge <ummeegge@ipfire.org> wrote:
> 
> Hi Michael,
> 
> Am Dienstag, den 20.10.2020, 13:28 +0000 schrieb Michael Tremer:
>> OpenVPN is an absolute mess. The behaviour of configuration
>> parameters has been changed over the time; default values have been
>> changed over time; and it looks like nobody is actually testing
>> anything any more.
>> 
>> I have been spending hours today on figuring out why OpenVPN
>> is so damn slow. On a Lightning Wire Labs IPFire Mini Appliance
>> it achieves about 100 MBit/s in the default configuration when
>> "openssl speed -evp aes-256-gcm" achieves over 3.5 GBit/s.
>> 
>> Changing any of the cryptography parameters does not change
>> anything. Throughput remains around 100 MBit/s.
>> 
>> I finally set "cipher none" and "auth none" which disables
>> encryption and authentication altogether but does not increase
>> throughput. From here on it was absolutely clear that it was
>> not a crypto issue.
>> 
>> OpenVPN tries to be smart here and does its own fragmentation.
>> This is the worst idea I have heard of all day, because that job
>> is normally done best by the OS.
>> 
>> Various settings which allow the user to "tune" this are grossly
>> ineffective - let alone it isn't even clear what I am supposed
>> to configure anywhere. Setting "fragment 1500" weirdly still
>> does not convince openvpn to generate a packet that is longer
>> than 1400 bytes. Who'd a thunk?
>> 
>> There is a number of other parameters to set the MTU or which
>> are related to it (tun-mtu, link-mtu, fragment, mssfix).
>> 
>> On top of all of this we have two "bugs" in ovpnmain.cgi which
>> are being fixed in this patch:
>> 
>> 1) mssfix can be configured by the user. However, we always
>>   enable it in openvpn. The default is on, we only add "mssfix"
>>   which simply turns it on.
>>   It is now being disabled when the user has chosen so in the
>>   web UI. I do not know if this is backwards-compatible.
>> 
>> 2) We cap the MTU (tun-mtu) at 1500 bytes when fragment is being
>>   used. So it becomes pointless that the user can this and the
>>   user is not being made aware of this when they hit the save
>>   button.
>>   This was added when we added path MTU discovery. Since that
>>   did not work and was removed, we can remove this now, too.
>> 
>> I archived a solid 500-600 MBit/s of goodput with these settings:
>> 
>> * Disable mssfix
>> * Set "fragment" to 0
>> * Set MTU to 9000
> We have had a discussion about that longer time ago -->
> https://bugzilla.ipfire.org/show_bug.cgi?id=11364#c18
> . Did not know that a MTU of 9000 is possible, sounds like jumbo
> frames.
> 
>> 
>> I am sure the MTU could be further increased to have bigger packets,
>> but I did not test how badly this will affect latency of the tunnel.
>> 
>> OpenVPN seems to only be able to handle a certain amount of packets
>> a second - no matter what. With larger packets, the throughput of
>> the tunnel increases, but latency might as well.
>> 
>> Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
>> Cc: Erik Kapfer <erik.kapfer@ipfire.org>
>> Cc: Stefan Schantl <stefan.schantl@ipfire.org>
>> ---
>> html/cgi-bin/ovpnmain.cgi | 29 +++++++++--------------------
>> 1 file changed, 9 insertions(+), 20 deletions(-)
>> 
>> diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-bin/ovpnmain.cgi
>> index e7bc505e7..e5bc45c1c 100644
>> --- a/html/cgi-bin/ovpnmain.cgi
>> +++ b/html/cgi-bin/ovpnmain.cgi
>> @@ -280,14 +280,7 @@ sub writeserverconf {
>>     print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n";
>>     #print CONF "push \"route $netsettings{'GREEN_NETADDRESS'}
>> $netsettings{'GREEN_NETMASK'}\"\n";
>> 
>> -    # Check if we are using mssfix, fragment and set the corretct
>> mtu of 1500.
>> -    # If we doesn't use one of them, we can use the configured mtu
>> value.
>> -    if ($sovpnsettings{'MSSFIX'} eq 'on') 
>> -	{ print CONF "tun-mtu 1500\n"; }
>> -    elsif ($sovpnsettings{'FRAGMENT'} ne '' &&
>> $sovpnsettings{'DPROTOCOL'} ne 'tcp') 
>> -	{ print CONF "tun-mtu 1500\n"; }
>> -    else 
>> -	{ print CONF "tun-mtu $sovpnsettings{'DMTU'}\n"; }
>> +    print CONF "tun-mtu $sovpnsettings{'DMTU'}\n";
>> 
>>     if ($vpnsettings{'ROUTES_PUSH'} ne '') {
>> 		@temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'});
>> @@ -320,6 +313,8 @@ sub writeserverconf {
>>     }
>>     if ($sovpnsettings{MSSFIX} eq 'on') {
>> 		print CONF "mssfix\n";
>> +    } else {
>> +		print CONF "mssfix 0\n";
>>     }
>>     if ($sovpnsettings{FRAGMENT} ne '' &&
>> $sovpnsettings{'DPROTOCOL'} ne 'tcp') {
>> 		print CONF "fragment $sovpnsettings{'FRAGMENT'}\n";
>> @@ -975,7 +970,7 @@ unless(-d
>> "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir
>> "${General
>>   if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu =
>> $cgiparams{'MTU'}};
>>   print SERVERCONF "tun-mtu $tunmtu\n";
>>   if ($cgiparams{'FRAGMENT'} ne '') {print SERVERCONF "fragment
>> $cgiparams{'FRAGMENT'}\n";} 
>> -  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n";
>> }; 
>> +  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; }
>> else { print SERVERCONF "mssfix 0\n" };
>>   }
>> 
>>   print SERVERCONF "# Auth. Server\n"; 
>> @@ -1074,7 +1069,7 @@ unless(-d
>> "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir
>> "${General
>>   if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu =
>> $cgiparams{'MTU'}};
>>   print CLIENTCONF "tun-mtu $tunmtu\n";
>>   if ($cgiparams{'FRAGMENT'} ne '') {print CLIENTCONF "fragment
>> $cgiparams{'FRAGMENT'}\n";}
>> -  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n";
>> }; 
>> +  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; }
>> else { print CLIENTCONF "mssfix 0\n" };
>>   }
>> 
>>   # Check host certificate if X509 is RFC3280 compliant.
>> @@ -2204,7 +2199,7 @@ if ($confighash{$cgiparams{'KEY'}}[3] eq
>> 'net'){
>>    if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu = '1500'}
>> else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]};
>>    print CLIENTCONF "tun-mtu $tunmtu\n";
>>    if ($confighash{$cgiparams{'KEY'}}[24] ne '') {print CLIENTCONF
>> "fragment $confighash{$cgiparams{'KEY'}}[24]\n";}
>> -   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF
>> "mssfix\n";}
>> +   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF
>> "mssfix\n";} else { print CLIENTCONF "mssfix 0\n"; }
>>    }
>>    # Check host certificate if X509 is RFC3280 compliant.
>>    # If not, old --ns-cert-type directive will be used.
>> @@ -2285,15 +2280,7 @@ else
>>     print CLIENTCONF "nobind\r\n";
>>     print CLIENTCONF "dev tun\r\n";
>>     print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n";
>> -
>> -    # Check if we are using fragment, mssfix and set MTU to 1500
>> -    # or use configured value.
>> -    if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne
>> 'tcp' )
>> -	{ print CLIENTCONF "tun-mtu 1500\r\n"; }
>> -    elsif ($vpnsettings{MSSFIX} eq 'on')
>> -	{ print CLIENTCONF "tun-mtu 1500\r\n"; }
>> -    else
>> -	{ print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n"; }
>> +    print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n";
>> 
>>     if ( $vpnsettings{'ENABLED'} eq 'on'){
>>     	print CLIENTCONF "remote $vpnsettings{'VPN_IP'}
>> $vpnsettings{'DDEST_PORT'}\r\n";
>> @@ -2383,6 +2370,8 @@ else
>>     print CLIENTCONF "verify-x509-name
>> $vpnsettings{ROOTCERT_HOSTNAME} name\r\n";
>>     if ($vpnsettings{MSSFIX} eq 'on') {
>> 	print CLIENTCONF "mssfix\r\n";
>> +    } else {
>> +	print CLIENTCONF "mssfix 0\r\n";
>>     }
>>     if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne
>> 'tcp' ) {
>> 	print CLIENTCONF "fragment $vpnsettings{'FRAGMENT'}\r\n";
  
ummeegge Oct. 24, 2020, 10:06 a.m. UTC | #3
Hi Michael,

Am Freitag, den 23.10.2020, 11:18 +0100 schrieb Michael Tremer:
> Hello Erik,
> 
> Thank you for your prompt reply.
Your welcome.

> 
> Interesting that we have talked about this that long ago. I totally
> forgot about that conversation, and I could not derive any actionable
> items from it.
> 
> I guess I have now implemented the option to actually disable mssfix.
> 
> The last post refers to this:
> 
>   https://sourceforge.net/p/openvpn/mailman/message/13218191/
> 
> A post from 2004 which simply says what has to be done - ideally. The
> problem with that only is that it is incredibly slow - presumably
> because of implementation issues.
> 
> If VPNs are slow, people tend to stop using them. That will of course
> expose them to loads of security issues.
> 
> So what can we do here? I have no idea apart from adding this patch,
> so that the user has at least some kind of choice.
In principal it is a good idea to give the possibility to open up such
limits. OpenVPN used a fixed mssfix with value of 1450 even it has not
been configured, probably to prevent misconfigurations. The limit of
1450 can only be deactivated with a value of 0 for mssfix.

> 
> Do you think this will be backwards-compatible, or are we going to
> break installations if we were to accept the patch?
Have tested your patch now. Requirement was activated mssfix and
fragment, default value at MTU settings. After applying your patch and
changed a value (logging in that case) the MTU on server side has been
changed from 1400 to 1500. This fires warnings like:

Sat Oct 24 11:11:46 2020 WARNING: 'tun-mtu' is used inconsistently, local='tun-mtu 1500', remote='tun-mtu 1400'

on client side and on server side

Oct 24 11:11:49 ipfire-prime openvpnserver[8009]: 192.168.110.2:36002 WARNING: 'link-mtu' is used inconsistently, local='link-mtu 1453', remote='link-mtu 1553'
Oct 24 11:11:49 ipfire-prime openvpnserver[8009]: 192.168.110.2:36002 WARNING: 'tun-mtu' is used inconsistently, local='tun-mtu 1400', remote='tun-mtu 1500'

but the OPTIONS IMPORT adjusts nevertheless the link mtu -->

Sat Oct 24 11:11:48 2020 OPTIONS IMPORT: adjusting link_mtu to 1628

and the connection worked so far. But am not sure on how this warning
can be a problem... In here
https://forums.openvpn.net/viewtopic.php?f=33&t=29440
it has been said that this warning can safely be ignored unless there
are real problems with the VPN ?!

Some first tests from here.

Best,

Erik

> 
> Best,
> -Michael
> 
> > On 21 Oct 2020, at 17:22, ummeegge <ummeegge@ipfire.org> wrote:
> > 
> > Hi Michael,
> > 
> > Am Dienstag, den 20.10.2020, 13:28 +0000 schrieb Michael Tremer:
> > > OpenVPN is an absolute mess. The behaviour of configuration
> > > parameters has been changed over the time; default values have
> > > been
> > > changed over time; and it looks like nobody is actually testing
> > > anything any more.
> > > 
> > > I have been spending hours today on figuring out why OpenVPN
> > > is so damn slow. On a Lightning Wire Labs IPFire Mini Appliance
> > > it achieves about 100 MBit/s in the default configuration when
> > > "openssl speed -evp aes-256-gcm" achieves over 3.5 GBit/s.
> > > 
> > > Changing any of the cryptography parameters does not change
> > > anything. Throughput remains around 100 MBit/s.
> > > 
> > > I finally set "cipher none" and "auth none" which disables
> > > encryption and authentication altogether but does not increase
> > > throughput. From here on it was absolutely clear that it was
> > > not a crypto issue.
> > > 
> > > OpenVPN tries to be smart here and does its own fragmentation.
> > > This is the worst idea I have heard of all day, because that job
> > > is normally done best by the OS.
> > > 
> > > Various settings which allow the user to "tune" this are grossly
> > > ineffective - let alone it isn't even clear what I am supposed
> > > to configure anywhere. Setting "fragment 1500" weirdly still
> > > does not convince openvpn to generate a packet that is longer
> > > than 1400 bytes. Who'd a thunk?
> > > 
> > > There is a number of other parameters to set the MTU or which
> > > are related to it (tun-mtu, link-mtu, fragment, mssfix).
> > > 
> > > On top of all of this we have two "bugs" in ovpnmain.cgi which
> > > are being fixed in this patch:
> > > 
> > > 1) mssfix can be configured by the user. However, we always
> > >   enable it in openvpn. The default is on, we only add "mssfix"
> > >   which simply turns it on.
> > >   It is now being disabled when the user has chosen so in the
> > >   web UI. I do not know if this is backwards-compatible.
> > > 
> > > 2) We cap the MTU (tun-mtu) at 1500 bytes when fragment is being
> > >   used. So it becomes pointless that the user can this and the
> > >   user is not being made aware of this when they hit the save
> > >   button.
> > >   This was added when we added path MTU discovery. Since that
> > >   did not work and was removed, we can remove this now, too.
> > > 
> > > I archived a solid 500-600 MBit/s of goodput with these settings:
> > > 
> > > * Disable mssfix
> > > * Set "fragment" to 0
> > > * Set MTU to 9000
> > 
> > We have had a discussion about that longer time ago -->
> > https://bugzilla.ipfire.org/show_bug.cgi?id=11364#c18
> > . Did not know that a MTU of 9000 is possible, sounds like jumbo
> > frames.
> > 
> > > 
> > > I am sure the MTU could be further increased to have bigger
> > > packets,
> > > but I did not test how badly this will affect latency of the
> > > tunnel.
> > > 
> > > OpenVPN seems to only be able to handle a certain amount of
> > > packets
> > > a second - no matter what. With larger packets, the throughput of
> > > the tunnel increases, but latency might as well.
> > > 
> > > Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
> > > Cc: Erik Kapfer <erik.kapfer@ipfire.org>
> > > Cc: Stefan Schantl <stefan.schantl@ipfire.org>
> > > ---
> > > html/cgi-bin/ovpnmain.cgi | 29 +++++++++--------------------
> > > 1 file changed, 9 insertions(+), 20 deletions(-)
> > > 
> > > diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-
> > > bin/ovpnmain.cgi
> > > index e7bc505e7..e5bc45c1c 100644
> > > --- a/html/cgi-bin/ovpnmain.cgi
> > > +++ b/html/cgi-bin/ovpnmain.cgi
> > > @@ -280,14 +280,7 @@ sub writeserverconf {
> > >     print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n";
> > >     #print CONF "push \"route $netsettings{'GREEN_NETADDRESS'}
> > > $netsettings{'GREEN_NETMASK'}\"\n";
> > > 
> > > -    # Check if we are using mssfix, fragment and set the
> > > corretct
> > > mtu of 1500.
> > > -    # If we doesn't use one of them, we can use the configured
> > > mtu
> > > value.
> > > -    if ($sovpnsettings{'MSSFIX'} eq 'on') 
> > > -	{ print CONF "tun-mtu 1500\n"; }
> > > -    elsif ($sovpnsettings{'FRAGMENT'} ne '' &&
> > > $sovpnsettings{'DPROTOCOL'} ne 'tcp') 
> > > -	{ print CONF "tun-mtu 1500\n"; }
> > > -    else 
> > > -	{ print CONF "tun-mtu $sovpnsettings{'DMTU'}\n"; }
> > > +    print CONF "tun-mtu $sovpnsettings{'DMTU'}\n";
> > > 
> > >     if ($vpnsettings{'ROUTES_PUSH'} ne '') {
> > > 		@temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'});
> > > @@ -320,6 +313,8 @@ sub writeserverconf {
> > >     }
> > >     if ($sovpnsettings{MSSFIX} eq 'on') {
> > > 		print CONF "mssfix\n";
> > > +    } else {
> > > +		print CONF "mssfix 0\n";
> > >     }
> > >     if ($sovpnsettings{FRAGMENT} ne '' &&
> > > $sovpnsettings{'DPROTOCOL'} ne 'tcp') {
> > > 		print CONF "fragment $sovpnsettings{'FRAGMENT'}\n";
> > > @@ -975,7 +970,7 @@ unless(-d
> > > "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir
> > > "${General
> > >   if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu =
> > > $cgiparams{'MTU'}};
> > >   print SERVERCONF "tun-mtu $tunmtu\n";
> > >   if ($cgiparams{'FRAGMENT'} ne '') {print SERVERCONF "fragment
> > > $cgiparams{'FRAGMENT'}\n";} 
> > > -  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF
> > > "mssfix\n";
> > > }; 
> > > +  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF
> > > "mssfix\n"; }
> > > else { print SERVERCONF "mssfix 0\n" };
> > >   }
> > > 
> > >   print SERVERCONF "# Auth. Server\n"; 
> > > @@ -1074,7 +1069,7 @@ unless(-d
> > > "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir
> > > "${General
> > >   if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu =
> > > $cgiparams{'MTU'}};
> > >   print CLIENTCONF "tun-mtu $tunmtu\n";
> > >   if ($cgiparams{'FRAGMENT'} ne '') {print CLIENTCONF "fragment
> > > $cgiparams{'FRAGMENT'}\n";}
> > > -  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF
> > > "mssfix\n";
> > > }; 
> > > +  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF
> > > "mssfix\n"; }
> > > else { print CLIENTCONF "mssfix 0\n" };
> > >   }
> > > 
> > >   # Check host certificate if X509 is RFC3280 compliant.
> > > @@ -2204,7 +2199,7 @@ if ($confighash{$cgiparams{'KEY'}}[3] eq
> > > 'net'){
> > >    if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu =
> > > '1500'}
> > > else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]};
> > >    print CLIENTCONF "tun-mtu $tunmtu\n";
> > >    if ($confighash{$cgiparams{'KEY'}}[24] ne '') {print
> > > CLIENTCONF
> > > "fragment $confighash{$cgiparams{'KEY'}}[24]\n";}
> > > -   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print
> > > CLIENTCONF
> > > "mssfix\n";}
> > > +   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print
> > > CLIENTCONF
> > > "mssfix\n";} else { print CLIENTCONF "mssfix 0\n"; }
> > >    }
> > >    # Check host certificate if X509 is RFC3280 compliant.
> > >    # If not, old --ns-cert-type directive will be used.
> > > @@ -2285,15 +2280,7 @@ else
> > >     print CLIENTCONF "nobind\r\n";
> > >     print CLIENTCONF "dev tun\r\n";
> > >     print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n";
> > > -
> > > -    # Check if we are using fragment, mssfix and set MTU to 1500
> > > -    # or use configured value.
> > > -    if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL}
> > > ne
> > > 'tcp' )
> > > -	{ print CLIENTCONF "tun-mtu 1500\r\n"; }
> > > -    elsif ($vpnsettings{MSSFIX} eq 'on')
> > > -	{ print CLIENTCONF "tun-mtu 1500\r\n"; }
> > > -    else
> > > -	{ print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n"; }
> > > +    print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n";
> > > 
> > >     if ( $vpnsettings{'ENABLED'} eq 'on'){
> > >     	print CLIENTCONF "remote $vpnsettings{'VPN_IP'}
> > > $vpnsettings{'DDEST_PORT'}\r\n";
> > > @@ -2383,6 +2370,8 @@ else
> > >     print CLIENTCONF "verify-x509-name
> > > $vpnsettings{ROOTCERT_HOSTNAME} name\r\n";
> > >     if ($vpnsettings{MSSFIX} eq 'on') {
> > > 	print CLIENTCONF "mssfix\r\n";
> > > +    } else {
> > > +	print CLIENTCONF "mssfix 0\r\n";
> > >     }
> > >     if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL}
> > > ne
> > > 'tcp' ) {
> > > 	print CLIENTCONF "fragment $vpnsettings{'FRAGMENT'}\r\n";
> 
>
  
ummeegge Nov. 24, 2020, 3:19 p.m. UTC | #4
Hi Michael,
wanted to warm this up alittle :-) do you want to deliver this patch ?

Best,

Erik

Am Dienstag, den 20.10.2020, 13:28 +0000 schrieb Michael Tremer:
> OpenVPN is an absolute mess. The behaviour of configuration
> parameters has been changed over the time; default values have been
> changed over time; and it looks like nobody is actually testing
> anything any more.
> 
> I have been spending hours today on figuring out why OpenVPN
> is so damn slow. On a Lightning Wire Labs IPFire Mini Appliance
> it achieves about 100 MBit/s in the default configuration when
> "openssl speed -evp aes-256-gcm" achieves over 3.5 GBit/s.
> 
> Changing any of the cryptography parameters does not change
> anything. Throughput remains around 100 MBit/s.
> 
> I finally set "cipher none" and "auth none" which disables
> encryption and authentication altogether but does not increase
> throughput. From here on it was absolutely clear that it was
> not a crypto issue.
> 
> OpenVPN tries to be smart here and does its own fragmentation.
> This is the worst idea I have heard of all day, because that job
> is normally done best by the OS.
> 
> Various settings which allow the user to "tune" this are grossly
> ineffective - let alone it isn't even clear what I am supposed
> to configure anywhere. Setting "fragment 1500" weirdly still
> does not convince openvpn to generate a packet that is longer
> than 1400 bytes. Who'd a thunk?
> 
> There is a number of other parameters to set the MTU or which
> are related to it (tun-mtu, link-mtu, fragment, mssfix).
> 
> On top of all of this we have two "bugs" in ovpnmain.cgi which
> are being fixed in this patch:
> 
> 1) mssfix can be configured by the user. However, we always
>    enable it in openvpn. The default is on, we only add "mssfix"
>    which simply turns it on.
>    It is now being disabled when the user has chosen so in the
>    web UI. I do not know if this is backwards-compatible.
> 
> 2) We cap the MTU (tun-mtu) at 1500 bytes when fragment is being
>    used. So it becomes pointless that the user can this and the
>    user is not being made aware of this when they hit the save
>    button.
>    This was added when we added path MTU discovery. Since that
>    did not work and was removed, we can remove this now, too.
> 
> I archived a solid 500-600 MBit/s of goodput with these settings:
> 
> * Disable mssfix
> * Set "fragment" to 0
> * Set MTU to 9000
> 
> I am sure the MTU could be further increased to have bigger packets,
> but I did not test how badly this will affect latency of the tunnel.
> 
> OpenVPN seems to only be able to handle a certain amount of packets
> a second - no matter what. With larger packets, the throughput of
> the tunnel increases, but latency might as well.
> 
> Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
> Cc: Erik Kapfer <erik.kapfer@ipfire.org>
> Cc: Stefan Schantl <stefan.schantl@ipfire.org>
> ---
>  html/cgi-bin/ovpnmain.cgi | 29 +++++++++--------------------
>  1 file changed, 9 insertions(+), 20 deletions(-)
> 
> diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-bin/ovpnmain.cgi
> index e7bc505e7..e5bc45c1c 100644
> --- a/html/cgi-bin/ovpnmain.cgi
> +++ b/html/cgi-bin/ovpnmain.cgi
> @@ -280,14 +280,7 @@ sub writeserverconf {
>      print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n";
>      #print CONF "push \"route $netsettings{'GREEN_NETADDRESS'}
> $netsettings{'GREEN_NETMASK'}\"\n";
>  
> -    # Check if we are using mssfix, fragment and set the corretct
> mtu of 1500.
> -    # If we doesn't use one of them, we can use the configured mtu
> value.
> -    if ($sovpnsettings{'MSSFIX'} eq 'on') 
> -       { print CONF "tun-mtu 1500\n"; }
> -    elsif ($sovpnsettings{'FRAGMENT'} ne '' &&
> $sovpnsettings{'DPROTOCOL'} ne 'tcp') 
> -       { print CONF "tun-mtu 1500\n"; }
> -    else 
> -       { print CONF "tun-mtu $sovpnsettings{'DMTU'}\n"; }
> +    print CONF "tun-mtu $sovpnsettings{'DMTU'}\n";
>  
>      if ($vpnsettings{'ROUTES_PUSH'} ne '') {
>                 @temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'});
> @@ -320,6 +313,8 @@ sub writeserverconf {
>      }
>      if ($sovpnsettings{MSSFIX} eq 'on') {
>                 print CONF "mssfix\n";
> +    } else {
> +               print CONF "mssfix 0\n";
>      }
>      if ($sovpnsettings{FRAGMENT} ne '' &&
> $sovpnsettings{'DPROTOCOL'} ne 'tcp') {
>                 print CONF "fragment $sovpnsettings{'FRAGMENT'}\n";
> @@ -975,7 +970,7 @@ unless(-d
> "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir
> "${General
>    if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu =
> $cgiparams{'MTU'}};
>    print SERVERCONF "tun-mtu $tunmtu\n";
>    if ($cgiparams{'FRAGMENT'} ne '') {print SERVERCONF "fragment
> $cgiparams{'FRAGMENT'}\n";} 
> -  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; };
> +  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; }
> else { print SERVERCONF "mssfix 0\n" };
>    }
>  
>    print SERVERCONF "# Auth. Server\n"; 
> @@ -1074,7 +1069,7 @@ unless(-d
> "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir
> "${General
>    if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu =
> $cgiparams{'MTU'}};
>    print CLIENTCONF "tun-mtu $tunmtu\n";
>    if ($cgiparams{'FRAGMENT'} ne '') {print CLIENTCONF "fragment
> $cgiparams{'FRAGMENT'}\n";}
> -  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; };
> +  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; }
> else { print CLIENTCONF "mssfix 0\n" };
>    }
>  
>    # Check host certificate if X509 is RFC3280 compliant.
> @@ -2204,7 +2199,7 @@ if ($confighash{$cgiparams{'KEY'}}[3] eq
> 'net'){
>     if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu = '1500'}
> else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]};
>     print CLIENTCONF "tun-mtu $tunmtu\n";
>     if ($confighash{$cgiparams{'KEY'}}[24] ne '') {print CLIENTCONF
> "fragment $confighash{$cgiparams{'KEY'}}[24]\n";}
> -   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF
> "mssfix\n";}
> +   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF
> "mssfix\n";} else { print CLIENTCONF "mssfix 0\n"; }
>     }
>     # Check host certificate if X509 is RFC3280 compliant.
>     # If not, old --ns-cert-type directive will be used.
> @@ -2285,15 +2280,7 @@ else
>      print CLIENTCONF "nobind\r\n";
>      print CLIENTCONF "dev tun\r\n";
>      print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n";
> -
> -    # Check if we are using fragment, mssfix and set MTU to 1500
> -    # or use configured value.
> -    if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne
> 'tcp' )
> -       { print CLIENTCONF "tun-mtu 1500\r\n"; }
> -    elsif ($vpnsettings{MSSFIX} eq 'on')
> -       { print CLIENTCONF "tun-mtu 1500\r\n"; }
> -    else
> -       { print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n"; }
> +    print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n";
>  
>      if ( $vpnsettings{'ENABLED'} eq 'on'){
>         print CLIENTCONF "remote $vpnsettings{'VPN_IP'}
> $vpnsettings{'DDEST_PORT'}\r\n";
> @@ -2383,6 +2370,8 @@ else
>      print CLIENTCONF "verify-x509-name
> $vpnsettings{ROOTCERT_HOSTNAME} name\r\n";
>      if ($vpnsettings{MSSFIX} eq 'on') {
>         print CLIENTCONF "mssfix\r\n";
> +    } else {
> +       print CLIENTCONF "mssfix 0\r\n";
>      }
>      if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne
> 'tcp' ) {
>         print CLIENTCONF "fragment $vpnsettings{'FRAGMENT'}\r\n";
  
Michael Tremer Nov. 25, 2020, 7:56 p.m. UTC | #5
Hello,

I didn’t merge this yet, because I did not get any testing feedback (with a Tested-by tag).

Since nobody has anything to complain, I will merge it then.

Best,
-Michael

> On 24 Nov 2020, at 15:19, ummeegge <ummeegge@ipfire.org> wrote:
> 
> Hi Michael,
> wanted to warm this up alittle :-) do you want to deliver this patch ?
> 
> Best,
> 
> Erik
> 
> Am Dienstag, den 20.10.2020, 13:28 +0000 schrieb Michael Tremer:
>> OpenVPN is an absolute mess. The behaviour of configuration
>> parameters has been changed over the time; default values have been
>> changed over time; and it looks like nobody is actually testing
>> anything any more.
>> 
>> I have been spending hours today on figuring out why OpenVPN
>> is so damn slow. On a Lightning Wire Labs IPFire Mini Appliance
>> it achieves about 100 MBit/s in the default configuration when
>> "openssl speed -evp aes-256-gcm" achieves over 3.5 GBit/s.
>> 
>> Changing any of the cryptography parameters does not change
>> anything. Throughput remains around 100 MBit/s.
>> 
>> I finally set "cipher none" and "auth none" which disables
>> encryption and authentication altogether but does not increase
>> throughput. From here on it was absolutely clear that it was
>> not a crypto issue.
>> 
>> OpenVPN tries to be smart here and does its own fragmentation.
>> This is the worst idea I have heard of all day, because that job
>> is normally done best by the OS.
>> 
>> Various settings which allow the user to "tune" this are grossly
>> ineffective - let alone it isn't even clear what I am supposed
>> to configure anywhere. Setting "fragment 1500" weirdly still
>> does not convince openvpn to generate a packet that is longer
>> than 1400 bytes. Who'd a thunk?
>> 
>> There is a number of other parameters to set the MTU or which
>> are related to it (tun-mtu, link-mtu, fragment, mssfix).
>> 
>> On top of all of this we have two "bugs" in ovpnmain.cgi which
>> are being fixed in this patch:
>> 
>> 1) mssfix can be configured by the user. However, we always
>>    enable it in openvpn. The default is on, we only add "mssfix"
>>    which simply turns it on.
>>    It is now being disabled when the user has chosen so in the
>>    web UI. I do not know if this is backwards-compatible.
>> 
>> 2) We cap the MTU (tun-mtu) at 1500 bytes when fragment is being
>>    used. So it becomes pointless that the user can this and the
>>    user is not being made aware of this when they hit the save
>>    button.
>>    This was added when we added path MTU discovery. Since that
>>    did not work and was removed, we can remove this now, too.
>> 
>> I archived a solid 500-600 MBit/s of goodput with these settings:
>> 
>> * Disable mssfix
>> * Set "fragment" to 0
>> * Set MTU to 9000
>> 
>> I am sure the MTU could be further increased to have bigger packets,
>> but I did not test how badly this will affect latency of the tunnel.
>> 
>> OpenVPN seems to only be able to handle a certain amount of packets
>> a second - no matter what. With larger packets, the throughput of
>> the tunnel increases, but latency might as well.
>> 
>> Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
>> Cc: Erik Kapfer <erik.kapfer@ipfire.org>
>> Cc: Stefan Schantl <stefan.schantl@ipfire.org>
>> ---
>>  html/cgi-bin/ovpnmain.cgi | 29 +++++++++--------------------
>>  1 file changed, 9 insertions(+), 20 deletions(-)
>> 
>> diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-bin/ovpnmain.cgi
>> index e7bc505e7..e5bc45c1c 100644
>> --- a/html/cgi-bin/ovpnmain.cgi
>> +++ b/html/cgi-bin/ovpnmain.cgi
>> @@ -280,14 +280,7 @@ sub writeserverconf {
>>      print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n";
>>      #print CONF "push \"route $netsettings{'GREEN_NETADDRESS'}
>> $netsettings{'GREEN_NETMASK'}\"\n";
>>  
>> -    # Check if we are using mssfix, fragment and set the corretct
>> mtu of 1500.
>> -    # If we doesn't use one of them, we can use the configured mtu
>> value.
>> -    if ($sovpnsettings{'MSSFIX'} eq 'on') 
>> -       { print CONF "tun-mtu 1500\n"; }
>> -    elsif ($sovpnsettings{'FRAGMENT'} ne '' &&
>> $sovpnsettings{'DPROTOCOL'} ne 'tcp') 
>> -       { print CONF "tun-mtu 1500\n"; }
>> -    else 
>> -       { print CONF "tun-mtu $sovpnsettings{'DMTU'}\n"; }
>> +    print CONF "tun-mtu $sovpnsettings{'DMTU'}\n";
>>  
>>      if ($vpnsettings{'ROUTES_PUSH'} ne '') {
>>                 @temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'});
>> @@ -320,6 +313,8 @@ sub writeserverconf {
>>      }
>>      if ($sovpnsettings{MSSFIX} eq 'on') {
>>                 print CONF "mssfix\n";
>> +    } else {
>> +               print CONF "mssfix 0\n";
>>      }
>>      if ($sovpnsettings{FRAGMENT} ne '' &&
>> $sovpnsettings{'DPROTOCOL'} ne 'tcp') {
>>                 print CONF "fragment $sovpnsettings{'FRAGMENT'}\n";
>> @@ -975,7 +970,7 @@ unless(-d
>> "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir
>> "${General
>>    if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu =
>> $cgiparams{'MTU'}};
>>    print SERVERCONF "tun-mtu $tunmtu\n";
>>    if ($cgiparams{'FRAGMENT'} ne '') {print SERVERCONF "fragment
>> $cgiparams{'FRAGMENT'}\n";} 
>> -  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; };
>> +  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; }
>> else { print SERVERCONF "mssfix 0\n" };
>>    }
>>  
>>    print SERVERCONF "# Auth. Server\n"; 
>> @@ -1074,7 +1069,7 @@ unless(-d
>> "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir
>> "${General
>>    if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu =
>> $cgiparams{'MTU'}};
>>    print CLIENTCONF "tun-mtu $tunmtu\n";
>>    if ($cgiparams{'FRAGMENT'} ne '') {print CLIENTCONF "fragment
>> $cgiparams{'FRAGMENT'}\n";}
>> -  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; };
>> +  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; }
>> else { print CLIENTCONF "mssfix 0\n" };
>>    }
>>  
>>    # Check host certificate if X509 is RFC3280 compliant.
>> @@ -2204,7 +2199,7 @@ if ($confighash{$cgiparams{'KEY'}}[3] eq
>> 'net'){
>>     if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu = '1500'}
>> else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]};
>>     print CLIENTCONF "tun-mtu $tunmtu\n";
>>     if ($confighash{$cgiparams{'KEY'}}[24] ne '') {print CLIENTCONF
>> "fragment $confighash{$cgiparams{'KEY'}}[24]\n";}
>> -   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF
>> "mssfix\n";}
>> +   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF
>> "mssfix\n";} else { print CLIENTCONF "mssfix 0\n"; }
>>     }
>>     # Check host certificate if X509 is RFC3280 compliant.
>>     # If not, old --ns-cert-type directive will be used.
>> @@ -2285,15 +2280,7 @@ else
>>      print CLIENTCONF "nobind\r\n";
>>      print CLIENTCONF "dev tun\r\n";
>>      print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n";
>> -
>> -    # Check if we are using fragment, mssfix and set MTU to 1500
>> -    # or use configured value.
>> -    if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne
>> 'tcp' )
>> -       { print CLIENTCONF "tun-mtu 1500\r\n"; }
>> -    elsif ($vpnsettings{MSSFIX} eq 'on')
>> -       { print CLIENTCONF "tun-mtu 1500\r\n"; }
>> -    else
>> -       { print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n"; }
>> +    print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n";
>>  
>>      if ( $vpnsettings{'ENABLED'} eq 'on'){
>>         print CLIENTCONF "remote $vpnsettings{'VPN_IP'}
>> $vpnsettings{'DDEST_PORT'}\r\n";
>> @@ -2383,6 +2370,8 @@ else
>>      print CLIENTCONF "verify-x509-name
>> $vpnsettings{ROOTCERT_HOSTNAME} name\r\n";
>>      if ($vpnsettings{MSSFIX} eq 'on') {
>>         print CLIENTCONF "mssfix\r\n";
>> +    } else {
>> +       print CLIENTCONF "mssfix 0\r\n";
>>      }
>>      if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne
>> 'tcp' ) {
>>         print CLIENTCONF "fragment $vpnsettings{'FRAGMENT'}\r\n";
> 
>
  
ummeegge Nov. 25, 2020, 8:44 p.m. UTC | #6
Hi Michael,

Am Mittwoch, den 25.11.2020, 19:56 +0000 schrieb Michael Tremer:
> Hello,
> 
> I didn’t merge this yet, because I did not get any testing feedback
> (with a Tested-by tag).
Have tested it here and in the worst case there was only a warning in
the log and server/client negotiate via OPTIONS IMPORT the best result
out. The advantage in my opinion might be to have a chance to raise the
values (Jumbo frames ?!) and get more controll over the package size.

> 
> Since nobody has anything to complain, I will merge it then.
Great.

> 
> Best,
> -Michael

Best,

Erik

> 
> > On 24 Nov 2020, at 15:19, ummeegge <ummeegge@ipfire.org> wrote:
> > 
> > Hi Michael,
> > wanted to warm this up alittle :-) do you want to deliver this
> > patch ?
> > 
> > Best,
> > 
> > Erik
> > 
> > Am Dienstag, den 20.10.2020, 13:28 +0000 schrieb Michael Tremer:
> > > OpenVPN is an absolute mess. The behaviour of configuration
> > > parameters has been changed over the time; default values have
> > > been
> > > changed over time; and it looks like nobody is actually testing
> > > anything any more.
> > > 
> > > I have been spending hours today on figuring out why OpenVPN
> > > is so damn slow. On a Lightning Wire Labs IPFire Mini Appliance
> > > it achieves about 100 MBit/s in the default configuration when
> > > "openssl speed -evp aes-256-gcm" achieves over 3.5 GBit/s.
> > > 
> > > Changing any of the cryptography parameters does not change
> > > anything. Throughput remains around 100 MBit/s.
> > > 
> > > I finally set "cipher none" and "auth none" which disables
> > > encryption and authentication altogether but does not increase
> > > throughput. From here on it was absolutely clear that it was
> > > not a crypto issue.
> > > 
> > > OpenVPN tries to be smart here and does its own fragmentation.
> > > This is the worst idea I have heard of all day, because that job
> > > is normally done best by the OS.
> > > 
> > > Various settings which allow the user to "tune" this are grossly
> > > ineffective - let alone it isn't even clear what I am supposed
> > > to configure anywhere. Setting "fragment 1500" weirdly still
> > > does not convince openvpn to generate a packet that is longer
> > > than 1400 bytes. Who'd a thunk?
> > > 
> > > There is a number of other parameters to set the MTU or which
> > > are related to it (tun-mtu, link-mtu, fragment, mssfix).
> > > 
> > > On top of all of this we have two "bugs" in ovpnmain.cgi which
> > > are being fixed in this patch:
> > > 
> > > 1) mssfix can be configured by the user. However, we always
> > >    enable it in openvpn. The default is on, we only add "mssfix"
> > >    which simply turns it on.
> > >    It is now being disabled when the user has chosen so in the
> > >    web UI. I do not know if this is backwards-compatible.
> > > 
> > > 2) We cap the MTU (tun-mtu) at 1500 bytes when fragment is being
> > >    used. So it becomes pointless that the user can this and the
> > >    user is not being made aware of this when they hit the save
> > >    button.
> > >    This was added when we added path MTU discovery. Since that
> > >    did not work and was removed, we can remove this now, too.
> > > 
> > > I archived a solid 500-600 MBit/s of goodput with these settings:
> > > 
> > > * Disable mssfix
> > > * Set "fragment" to 0
> > > * Set MTU to 9000
> > > 
> > > I am sure the MTU could be further increased to have bigger
> > > packets,
> > > but I did not test how badly this will affect latency of the
> > > tunnel.
> > > 
> > > OpenVPN seems to only be able to handle a certain amount of
> > > packets
> > > a second - no matter what. With larger packets, the throughput of
> > > the tunnel increases, but latency might as well.
> > > 
> > > Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
> > > Cc: Erik Kapfer <erik.kapfer@ipfire.org>
> > > Cc: Stefan Schantl <stefan.schantl@ipfire.org>
> > > ---
> > >  html/cgi-bin/ovpnmain.cgi | 29 +++++++++--------------------
> > >  1 file changed, 9 insertions(+), 20 deletions(-)
> > > 
> > > diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-
> > > bin/ovpnmain.cgi
> > > index e7bc505e7..e5bc45c1c 100644
> > > --- a/html/cgi-bin/ovpnmain.cgi
> > > +++ b/html/cgi-bin/ovpnmain.cgi
> > > @@ -280,14 +280,7 @@ sub writeserverconf {
> > >      print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n";
> > >      #print CONF "push \"route $netsettings{'GREEN_NETADDRESS'}
> > > $netsettings{'GREEN_NETMASK'}\"\n";
> > >  
> > > -    # Check if we are using mssfix, fragment and set the
> > > corretct
> > > mtu of 1500.
> > > -    # If we doesn't use one of them, we can use the configured
> > > mtu
> > > value.
> > > -    if ($sovpnsettings{'MSSFIX'} eq 'on') 
> > > -       { print CONF "tun-mtu 1500\n"; }
> > > -    elsif ($sovpnsettings{'FRAGMENT'} ne '' &&
> > > $sovpnsettings{'DPROTOCOL'} ne 'tcp') 
> > > -       { print CONF "tun-mtu 1500\n"; }
> > > -    else 
> > > -       { print CONF "tun-mtu $sovpnsettings{'DMTU'}\n"; }
> > > +    print CONF "tun-mtu $sovpnsettings{'DMTU'}\n";
> > >  
> > >      if ($vpnsettings{'ROUTES_PUSH'} ne '') {
> > >                 @temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'});
> > > @@ -320,6 +313,8 @@ sub writeserverconf {
> > >      }
> > >      if ($sovpnsettings{MSSFIX} eq 'on') {
> > >                 print CONF "mssfix\n";
> > > +    } else {
> > > +               print CONF "mssfix 0\n";
> > >      }
> > >      if ($sovpnsettings{FRAGMENT} ne '' &&
> > > $sovpnsettings{'DPROTOCOL'} ne 'tcp') {
> > >                 print CONF "fragment
> > > $sovpnsettings{'FRAGMENT'}\n";
> > > @@ -975,7 +970,7 @@ unless(-d
> > > "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir
> > > "${General
> > >    if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu
> > > =
> > > $cgiparams{'MTU'}};
> > >    print SERVERCONF "tun-mtu $tunmtu\n";
> > >    if ($cgiparams{'FRAGMENT'} ne '') {print SERVERCONF "fragment
> > > $cgiparams{'FRAGMENT'}\n";} 
> > > -  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF
> > > "mssfix\n"; };
> > > +  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF
> > > "mssfix\n"; }
> > > else { print SERVERCONF "mssfix 0\n" };
> > >    }
> > >  
> > >    print SERVERCONF "# Auth. Server\n"; 
> > > @@ -1074,7 +1069,7 @@ unless(-d
> > > "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir
> > > "${General
> > >    if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu
> > > =
> > > $cgiparams{'MTU'}};
> > >    print CLIENTCONF "tun-mtu $tunmtu\n";
> > >    if ($cgiparams{'FRAGMENT'} ne '') {print CLIENTCONF "fragment
> > > $cgiparams{'FRAGMENT'}\n";}
> > > -  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF
> > > "mssfix\n"; };
> > > +  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF
> > > "mssfix\n"; }
> > > else { print CLIENTCONF "mssfix 0\n" };
> > >    }
> > >  
> > >    # Check host certificate if X509 is RFC3280 compliant.
> > > @@ -2204,7 +2199,7 @@ if ($confighash{$cgiparams{'KEY'}}[3] eq
> > > 'net'){
> > >     if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu =
> > > '1500'}
> > > else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]};
> > >     print CLIENTCONF "tun-mtu $tunmtu\n";
> > >     if ($confighash{$cgiparams{'KEY'}}[24] ne '') {print
> > > CLIENTCONF
> > > "fragment $confighash{$cgiparams{'KEY'}}[24]\n";}
> > > -   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print
> > > CLIENTCONF
> > > "mssfix\n";}
> > > +   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print
> > > CLIENTCONF
> > > "mssfix\n";} else { print CLIENTCONF "mssfix 0\n"; }
> > >     }
> > >     # Check host certificate if X509 is RFC3280 compliant.
> > >     # If not, old --ns-cert-type directive will be used.
> > > @@ -2285,15 +2280,7 @@ else
> > >      print CLIENTCONF "nobind\r\n";
> > >      print CLIENTCONF "dev tun\r\n";
> > >      print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n";
> > > -
> > > -    # Check if we are using fragment, mssfix and set MTU to 1500
> > > -    # or use configured value.
> > > -    if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL}
> > > ne
> > > 'tcp' )
> > > -       { print CLIENTCONF "tun-mtu 1500\r\n"; }
> > > -    elsif ($vpnsettings{MSSFIX} eq 'on')
> > > -       { print CLIENTCONF "tun-mtu 1500\r\n"; }
> > > -    else
> > > -       { print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n"; }
> > > +    print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n";
> > >  
> > >      if ( $vpnsettings{'ENABLED'} eq 'on'){
> > >         print CLIENTCONF "remote $vpnsettings{'VPN_IP'}
> > > $vpnsettings{'DDEST_PORT'}\r\n";
> > > @@ -2383,6 +2370,8 @@ else
> > >      print CLIENTCONF "verify-x509-name
> > > $vpnsettings{ROOTCERT_HOSTNAME} name\r\n";
> > >      if ($vpnsettings{MSSFIX} eq 'on') {
> > >         print CLIENTCONF "mssfix\r\n";
> > > +    } else {
> > > +       print CLIENTCONF "mssfix 0\r\n";
> > >      }
> > >      if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL}
> > > ne
> > > 'tcp' ) {
> > >         print CLIENTCONF "fragment $vpnsettings{'FRAGMENT'}\r\n";
> > 
> > 
>
  

Patch

diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-bin/ovpnmain.cgi
index e7bc505e7..e5bc45c1c 100644
--- a/html/cgi-bin/ovpnmain.cgi
+++ b/html/cgi-bin/ovpnmain.cgi
@@ -280,14 +280,7 @@  sub writeserverconf {
     print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n";
     #print CONF "push \"route $netsettings{'GREEN_NETADDRESS'} $netsettings{'GREEN_NETMASK'}\"\n";
 
-    # Check if we are using mssfix, fragment and set the corretct mtu of 1500.
-    # If we doesn't use one of them, we can use the configured mtu value.
-    if ($sovpnsettings{'MSSFIX'} eq 'on') 
-	{ print CONF "tun-mtu 1500\n"; }
-    elsif ($sovpnsettings{'FRAGMENT'} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') 
-	{ print CONF "tun-mtu 1500\n"; }
-    else 
-	{ print CONF "tun-mtu $sovpnsettings{'DMTU'}\n"; }
+    print CONF "tun-mtu $sovpnsettings{'DMTU'}\n";
 
     if ($vpnsettings{'ROUTES_PUSH'} ne '') {
 		@temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'});
@@ -320,6 +313,8 @@  sub writeserverconf {
     }
     if ($sovpnsettings{MSSFIX} eq 'on') {
 		print CONF "mssfix\n";
+    } else {
+		print CONF "mssfix 0\n";
     }
     if ($sovpnsettings{FRAGMENT} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') {
 		print CONF "fragment $sovpnsettings{'FRAGMENT'}\n";
@@ -975,7 +970,7 @@  unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
   if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu = $cgiparams{'MTU'}};
   print SERVERCONF "tun-mtu $tunmtu\n";
   if ($cgiparams{'FRAGMENT'} ne '') {print SERVERCONF "fragment $cgiparams{'FRAGMENT'}\n";} 
-  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; }; 
+  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; } else { print SERVERCONF "mssfix 0\n" };
   }
 
   print SERVERCONF "# Auth. Server\n"; 
@@ -1074,7 +1069,7 @@  unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
   if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu = $cgiparams{'MTU'}};
   print CLIENTCONF "tun-mtu $tunmtu\n";
   if ($cgiparams{'FRAGMENT'} ne '') {print CLIENTCONF "fragment $cgiparams{'FRAGMENT'}\n";}
-  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; }; 
+  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; } else { print CLIENTCONF "mssfix 0\n" };
   }
 
   # Check host certificate if X509 is RFC3280 compliant.
@@ -2204,7 +2199,7 @@  if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
    if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu = '1500'} else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]};
    print CLIENTCONF "tun-mtu $tunmtu\n";
    if ($confighash{$cgiparams{'KEY'}}[24] ne '') {print CLIENTCONF "fragment $confighash{$cgiparams{'KEY'}}[24]\n";}
-   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF "mssfix\n";}
+   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF "mssfix\n";} else { print CLIENTCONF "mssfix 0\n"; }
    }
    # Check host certificate if X509 is RFC3280 compliant.
    # If not, old --ns-cert-type directive will be used.
@@ -2285,15 +2280,7 @@  else
     print CLIENTCONF "nobind\r\n";
     print CLIENTCONF "dev tun\r\n";
     print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n";
-
-    # Check if we are using fragment, mssfix and set MTU to 1500
-    # or use configured value.
-    if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne 'tcp' )
-	{ print CLIENTCONF "tun-mtu 1500\r\n"; }
-    elsif ($vpnsettings{MSSFIX} eq 'on')
-	{ print CLIENTCONF "tun-mtu 1500\r\n"; }
-    else
-	{ print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n"; }
+    print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n";
 
     if ( $vpnsettings{'ENABLED'} eq 'on'){
     	print CLIENTCONF "remote $vpnsettings{'VPN_IP'} $vpnsettings{'DDEST_PORT'}\r\n";
@@ -2383,6 +2370,8 @@  else
     print CLIENTCONF "verify-x509-name $vpnsettings{ROOTCERT_HOSTNAME} name\r\n";
     if ($vpnsettings{MSSFIX} eq 'on') {
 	print CLIENTCONF "mssfix\r\n";
+    } else {
+	print CLIENTCONF "mssfix 0\r\n";
     }
     if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne 'tcp' ) {
 	print CLIENTCONF "fragment $vpnsettings{'FRAGMENT'}\r\n";