Re: HAproxy 2.2.5 possible bug in ssl crt-list socket commands?

2020-12-15 Thread William Lallemand
On Fri, Dec 11, 2020 at 10:19:22AM +, Froehlich, Dominik wrote:
> Hi,
> 
> I am trying to implement a dynamic certificate updater for my crt-list in 
> HAproxy 2.2.5.
> I have noticed that somehow, when I update an existing certificate and add it 
> to the crt-list twice, I can never remove it again.
> 

For people interested, the bug was discussed here:
https://github.com/haproxy/haproxy/issues/1004

-- 
William Lallemand



HAproxy 2.2.5 possible bug in ssl crt-list socket commands?

2020-12-11 Thread Froehlich, Dominik
Hi,

I am trying to implement a dynamic certificate updater for my crt-list in 
HAproxy 2.2.5.
I have noticed that somehow, when I update an existing certificate and add it 
to the crt-list twice, I can never remove it again.

Here is what I am doing at the moment:

Step 1: Add a new certificate

echo "new ssl cert mycert.pem " | nc -U haproxy.sock
echo -e "set ssl cert mycert.pem <<\n$(cat mycert.pem)\n" | nc -U haproxy.sock
echo "commit ssl cert mycert.pem " | nc -U haproxy.sock

Step 2: Reference the certificate in crt-list

echo -e "add ssl crt-list my-crt-list <<\nmycert.pem [verify: none] 
myhost.mydomain.com\n" | nc -U haproxy.sock

Step 3: openssl check

openssl s_client -connect localhost:443 -servername myhost.mydomain.com
(…)
subject=… /CN=myhost.mydomain.com

So it works as expected.

Step 4: Update the certificate again

echo "new ssl cert mycert.pem " | nc -U haproxy.sock. (already exists)
echo -e "set ssl cert mycert.pem <<\n$(cat mycert.pem)\n" | nc -U haproxy.sock
echo "commit ssl cert mycert.pem " | nc -U haproxy.sock

Step 5: Add another reference in crt-list

echo -e "add ssl crt-list my-crt-list <<\nmycert.pem [verify: none] 
myhost.mydomain.com\n" | nc -U haproxy.sock

There are now 2 references in the crt-list:
mycert.pem:7 [verify none] myhost.mydomain.com
mycert.pem:8 [verify none] myhost.mydomain.com

Step 6: Remove the old reference

echo "del ssl crt-list my-crt-list mycert.pem:7 " | nc -U haproxy.sock

This was my original idea of how to update certificates without a downtime.

However, I found an odd issue when trying to finally delete the crt-list entry 
and the certificate thereafter:

Step 7: Remove the last reference

echo "del ssl crt-list my-crt-list mycert.pem:8 " | nc -U haproxy.sock

The crt-list now contains no more references to the certificate.

Step 8: Delete certificate

echo "del ssl cert mycert.pem" | nc -U haproxy.sock
Can't remove the certificate: certificate 'mycert.pem' in use, can't be deleted!

Huh? Checking certificate status:

echo "show ssl cert mycert.pem" | nc -U haproxy.sock
Filename: mycert.pem
Status: Used

So I can’t delete the cert even though there is no reference to it.
But there seems to be still a “hidden” reference somehow, because I can still 
see it in TLS:

Step 9: openssl check again

openssl s_client -connect localhost:443 -servername myhost.mydomain.com
(…)
subject=… /CN=myhost.mydomain.com

This should not be. The crt-list no longer contains any SNI filter for this 
domain, so it should fall back to the default certificate.


Is this a bug or am I just using the socket API wrong somehow?