on 21-Jun-2023 05:00
Recently, I learned that the iRule that is deployed by default with HTTPS VIPs created by Container Ingress Services (CIS) can be removed natively with a Policy CRD. And I learned a little about TLS versions and TLS extensions, and testing with openssl.
If you are unfamiliar with CIS, it is a controller that runs within Kubernetes (K8s) and monitors the K8s API server. CIS is able to modify the BIG-IP system configuration based on changes made to containerized applications.
By default, when you use a VirtualServer CRD to create a HTTPS VIP with CIS, an iRule is created and attached to the VIP on the BIG-IP. This iRule is about 292 lines long, and from what I can tell, is used for deciding which clientSSL profile should be used if there are mutliple profiles to choose from. (I'm not an expert with this iRule, but it looks like it would be required if you used SNI to distinguish between multiple TLS websites hosted at the same IP address).
However, the iRule isn't strictly required if you have a very basic (but common) set up: a simple HTTP/S VIP that performs TLS decryption, only has 1 possible clientSSL profile (no shared VIP with other TLS sites), and then simply proxies the traffic to pool members.
A customer called me and said:
"CIS is creating an unnecessary iRule that's attached to my VIP. Half of my TLS clients cannot connect to the VIP, but when I remove this iRule manually in the GUI, they connect fine. These TLS clients are old medical devices. Can we just have CIS not create this?"
With the default set up, my TLS connections were failing from medical devices.
After some packet captures, I saw that when the TLS client is a browser, the TCP handshake, TLS handshake, and conversation look successful. But when the medical devices try to connect, the BIG-IP is sending a RST packet immediately after receiving the Client Hello - so it's likely that there is something in this Client Hello message that the BIG-IP doesn't like.
Focusing in on the troublesome Client Hello, we can see a few things that jump out immediately:
I used openssl to test, trying to emulate these medical devices. I ran this command to use an old TLS version, cipher suite and remove the SNI header.
openssl s_client -connect demo.my-f5.com:443 -noservername -tls1 -cipher 'DHE-RSA-AES128-SHA'
But my connections still worked! I showed the problem was not the TLS version, the cipher suite, or the lack of SNI extension. Perhaps the problem is that there are no extensions at all in the Client Hello from the medical devices?
I couldn't remove every TLS extension from my Client Hello, and I wondered why. After researching, it looks like I cannot use openssl s_client
to make a connection without any TLS extensions. For that I'd need to use python or some other language, but frankly I gave up this pursuit and checked out the iRule in more detail.
Sure enough, the iRule contains this line, which was dropping any connection where the Client Hello does not contain any TLS extensions at all. After this line, the iRule goes on to identify the extensions and use the SNI extension.
if { ! [ expr { [info exists tls_extensions_len] && [string is integer -strict $tls_extensions_len] } ] } { reject ; event disable all; return; }
What does all this mean? It means that by default, really old TLS clients that don't have any TLS extensions at all will fail to connect to a VIP created by CIS. This is certainly an edge case, but let's solve it!
Here are the ideas I had to solve for this.
Lastly, I was embarrased when the customer found the answer by themselves. It turns out I'm not special and this was requested once before.
There is a Policy CRD that can remove the iRules that are created by default. I simply created and attached this Policy CRD.
Well, this was a long story for a short answer in the end! What I learned: I knew that old TLS versions, old cipher suites, and non-SNI-enabled clients often cause problems, but I didn't know much about TLS extensions generally before this experience. It's rare to see no TLS extensions from the client at all, and probably a warning sign that you should ask why and proceed carefully.
In the end, we dealt with our problem by removing an iRule that required the existence of TLS extensions and fortunately was not serving any other purpose for our application. If it was, we may have had to resort to another option, but hey, that's what we as developers/architects/devops folks love! Thanks for reading!