Loading...

TLS 1.0/1.1 retirement for Azure Cache for Redis

Image

When the cache is configured with a minimum of TLS 1.2, the supported cipher suites are limited to the following options:

  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256

To obtain a list of the ciphers currently running on a Linux environment, you can utilize the 'openssl ciphers -v' command. Running this command will provide you with an output containing all the ciphers available on the client machine:

Marcelo_Rodriguez_2-1697595170542.png

 

Once you have verified the presence of the correct ciphers on the client machine, you can proceed to check the TLS version being used to connect to a remote server in a Linux environment. Here are the steps to follow:

  • Open a terminal on your Linux system.

  • Use the following command to inspect the TLS version supported by the cache:

 

openssl s_client -connect cachename.redis.cache.windows.net:6380 -tls1_2

 

 

After executing the command, you should receive a "Connected" message if the connection is successful. Additionally, within the output, look for the 'Protocol' and 'Cipher' details, which are typically found in the 'ssl-session' section, as highlighted in the image below:​

 

Marcelo_Rodriguez_0-1697595050023.png

 

Marcelo_Rodriguez_1-1697595055066.png

In the event that the connection is not successful, you'll receive a 'Not Connected' message. This indicates that there may be an issue with establishing a connection to the Azure Redis Cache over TLS 1.2. To delve deeper into troubleshooting, it's advisable to capture a network trace while executing the command take a look if the TLS connection is failing or not.

 

Another client that can be used to test the connection through SSL is Redis CLI using stunnel, please refer to this article Connect to Azure Cache for Redis using SSL Port 6380 from Linux VM - Microsoft Community Hub

 

Capturing a network trace

To capture a network trace, we'll use 'tcpdump.' But before we start, let's check the current network interfaces on the virtual machine by running the 'ifconfig' command.

Marcelo_Rodriguez_3-1697595222992.png

"ip a sh" can also be used to obtain the information: 

Marcelo_Rodriguez_4-1697595246992.png

We can specify the directory where the capture files will be saved using the '-w' option with 'tcpdump.' For demonstration purposes, we've created a 'logs' directory, and the captures will be saved in the '/root/logs' path.

To initiate the capture, use the following command:

 

tcpdump -w /root/logs/traffic.pcap -i eth0 -v port 6380

 

This will make the tcpdump to listing to ‘eth0’ interface and capture the packages.

Marcelo_Rodriguez_5-1697595321048.png

 

The '*pcap' file is stored locally, and if you need to move it to a different location, you can use AzCopy. Here's how:

  1. Download Azcopy with ‘wget https://azcopyvnext.azureedge.net/releases/release-10.21.0-20230928/azcopy_linux_amd64_10.21.0.tar.gz’.
  2. List the contents of the downloaded file using 'ls -l.'
  3. Extract the downloaded files with the 'tar xvf' command followed by the '.gz' file. This action creates a directory, and within it, you'll find the AzCopy executable. For example, "tar xvf azcopy_linux_amd64_10.21.0.tar.gz"
  4. Navigate to the AzCopy directory using 'cd azcopy_linux_amd64_10.21.0/'.
  5. Copy the *.pcap file using AzCopy + Account SAS token:

 

‘/root/logs/azcopy_linux_amd64_10.21.0/azcopy cp "/root/logs/traffic.pcap" "https://storageaccount.blob.core.windows.net/myfs? + SAS token"’​

 

From your storage account, you can then download the capture file and open it with Wireshark. To analyze the network traffic, apply a filter by using "tcp.port == 6380 || udp.port == 6380" and then follow these steps:

  1. Open 'Transport Layer Security.'
  2. Navigate to 'TLSv1 Record Layer: Handshake Protocol: Client Hello.'
  3. Explore 'Cipher Suites' and locate the 'Client Suite.'

Once you capture the network trace, you will have 2 scenarios:

  1. Connection is successful and you should see a successful TLS Handshake.

Marcelo_Rodriguez_0-1697648047925.png

 

  1. The connection is failing due to client issues with TLS you will notice connection failures due to the cipher suites used from the client to the server, in this case, you can go ahead and open the Client Hello on Wireshark that will allow you to review the list of ciphers sent by the client:

Marcelo_Rodriguez_0-1698440863312.png

Scenario and Considerations for Legacy .NET Frameworks and Azure Redis Cache Connectivity: 

There is a scenario to consider when working with client applications that rely on older .NET Framework versions, such as .NET 4.5 or older. This scenario can lead to potential misunderstandings regarding the security of application connectivity.

 

Scenario Details:

Imagine a situation where you have a connection string like this:

 

string redisConnectionString = "tlstesting.redis.cache.windows.net:6380,password=cache_key,ssl=true,abortConnect=false"

 

 

At first glance, it might appear that the connection is secure since it's directed to the TLS port "6380," and the configuration indicates "ssl=true." However, when doing a connectivity test and capturing a network trace (as mentioned above), you might discover that the TLS version being used is 1.0. This is because Azure Redis Cache allows a minimum TLS requirement of 1.0, and it doesn't deny connections with this older version, while the .Net framework is overwriting the Redis.stackexchange configuration and making requests go over older versions of TLS. 

 

Here is a sample of a "server hello" captured when executing a code on .Net 4.5 using the connection string mentioned above. Capturing a network trace and filtering with "tcp.port == 6380 || udp.port == 6380" on Wireshark, will allow you to see exactly what TLS connection is been used: 

 

Marcelo_Rodriguez_6-1697599083097.png

You can also leverage .NET logging to gain deeper insights into any errors encountered when establishing a connection. This can be particularly useful for troubleshooting.

 

Here's how you can do it:

  1. First, create a "TextWriter" for logging purposes, which will help you track the error details:

 

 

TextWriter debugoutput = new StreamWriter("newFile.txt");

 

 

Next, establish a connection using the ConnectionMultiplexer class while directing the output to the debugoutput:

 

 

ConnectionMultiplexer connection = ConnectionMultiplexer.Connect(configurationOptions, debugoutput);

 

 

The ConnectionMultiplexer utilizes a "Ping" command to validate the connection. If you encounter a fault at this stage, you will be able to observe it in the log. Keep in mind that it may not provide extensive details about TLS (Transport Layer Security) failures, but it will give you a starting point to pinpoint the location of the error.

 

You should be able to find the logs located at "Project_Path\bin\Debug":

 

Marcelo_Rodriguez_0-1698432970114.png

 

The Challenge:

In the context of TLS security, the challenge arises when TLS 1.0 and 1.1 retirements become official. At that point, applications built with older .NET Framework versions could face connectivity failures due to how .NET determines the TLS version when using the Redis.StackExchange framework.

 

Recommended Solution:

To address this challenge, consider the following best practices and recommendations:

  • Upgrade your application to .NET Framework 4.7 or a later version if possible. Newer .NET Framework versions offer improved security and TLS support.

  • If upgrading is not feasible, you can modify registry keys to control the TLS settings:

    • SchUseStrongCrypto: This registry key, located at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319, has a value of type DWORD. A value of 1 enables strong cryptography using secure network protocols (TLS 1.2, TLS 1.1, and TLS 1.0), while a value of 0 disables strong cryptography. For .NET Framework 4.5.2 or earlier versions, the key defaults to 0, so you should explicitly set its value to 1.

    • SystemDefaultTlsVersions: This registry key, also located at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319, has a value of type DWORD. A value of 1 allows the operating system to choose the protocol, while a value of 0 causes your app to use protocols selected by the .NET Framework. If your application targets .NET Framework 4.6.1 or earlier versions, the key defaults to 0, so you should explicitly set its value to 1.

By implementing these solutions, you can ensure that your application maintains secure and reliable connectivity to Azure Redis Cache while addressing TLS version compatibility issues associated with legacy .NET Frameworks.

Learn more
Author image

Azure PaaS Blog articles

Azure PaaS Blog articles

Share post:

Related

Stay up to date with latest Microsoft Dynamics 365 and Power Platform news!

* Yes, I agree to the privacy policy