Challenges in Migrating ASP.NET Apps to Containers #3 – OpenSSL Issues

Introduction

During a recent project, there was a requirement to migrate existing ASP.NET apps hosted on Windows to Linux Docker containers. Throughout this migration, numerous challenges arose, and a significant amount of time was dedicated to the migration process. In this post, as well as in subsequent posts with similar titles, I will briefly outline some of the key challenges that were encountered. One of those challenges was OpenSSL Legacy Renegotiation.


Credits: https://turnoff.us/geek/we-need-to-talk-about-ssl/

TL;DR

Add the below lines to your Dockerfile on the target runtime container before running your application entry point to enable legacy SSL Renegotiation and change the minimum TLS version allowed.


RUN sed -i 's/CipherString = DEFAULT:@SECLEVEL=2/CipherString = DEFAULT:@SECLEVEL=1\n\
MinProtocol = TLSv1\n\
Options =UnsafeLegacyRenegotiation,UnsafeLegacyServerConnect\n\
/' /etc/ssl/openssl.cnf

Details

During the Linux migration of one of the ASP.NET Windows applications that connects to a large number of third parties, we encountered numerous issues while establishing connections with some of them. Most of these issues were showing SSL exceptions, and one of the major exceptions what we encountered was:


WebServiceException: The SSL connection could not be established, see inner exception.
---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL.
---> Interop+Crypto+OpenSslCryptographicException: error:0A000152:SSL routines::unsafe legacy renegotiation disabled
--- End of inner exception stack trace ---
   at Interop.OpenSsl.DoSslHandshake(SafeSslHandle context, ReadOnlySpan`1 input, Byte[]& sendBuf, Int32& sendCount)

After conducting a comprehensive investigation, we discovered that the issue was caused by certain third parties using legacy SSL protocols and configurations. To resolve this, we have to update our OpenSSL configuration to:

  1. Change the minimum supported TLS version to match your third-party requirements.
  2. Allow unsafe legacy connect and renegotiations.

To apply the above changes, you need to update OpenSSL configuration file, openssl.cnf, which resides in /etc/ssl/. Follow the steps below:

Locate and open /etc/ssl/openssl.cnf:


cd /etc/ssl
cat openssl.cnf

Scroll through the file to locate the relevant sections or configurations mentioned in the previous instructions, such as the minimum supported TLS version and the settings related to unsafe legacy connect and renegotiations.

A long file may appear on the screen, scroll through the file to find our target section, system_default_sect section.


[ssl_sect]
system_default = system_default_sect
[system_default_sect]
CipherString = DEFAULT:@SECLEVEL=2

Full explanation of configurations of this file can be found here: /docs/man1.1.1/man3/SSL_CONF_cmd.html (openssl.org)

Now the action starts, we need to add two configurations to the system_default_sect section:


MinProtocol = TLSv1
Options = UnsafeLegacyRenegotiation,UnsafeLegacyServerConnect

This can be easily achieved by using the sed stream editor command. The following lines will insert our configurations after the CipherString line:


sed -i 's/CipherString = DEFAULT:@SECLEVEL=2/CipherString = DEFAULT:@SECLEVEL=1\n\
MinProtocol = TLSv1\n\
Options = UnsafeLegacyRenegotiation,UnsafeLegacyServerConnect\n\
/' /etc/ssl/openssl.cnf

Now browse the openssl.cnf file again, you can see:


[system_default_sect]
CipherString = DEFAULT:@SECLEVEL=1
MinProtocol = TLSv1
Options = UnsafeLegacyRenegotiation,UnsafeLegacyServerConnect

No need to restart your container or take any additional action. Your configurations will be automatically applied to your next SSL request. Enjoy!