Dominik,

On 7/5/21 2:30 PM, Froehlich, Dominik wrote:
I've played around with your solution a bit and I think I may have found two 
issues with it:

- It doesn't check if the client uses SNI at all and it will deny the request 
if no SNI is used

I always use 'strict-sni' on the bind line, so this is not a concern for me.

- It fails if the client adds a port to the host header

Indeed, but this also not a concern for me, because I use standard ports. There is a "bug" in Firefox for WebSockets via HTTP/2 where it adds the :443 to the 'Host', but this will be worked around in HAProxy. See this mailing list thread: https://www.mail-archive.com/[email protected]/msg40652.html

So to my understanding, it is perfectly fine for a client to not use SNI if 
there is only one certificate to be used.

I don't understand what you mean by "if there is only one certificate to be used".

Here is my iteration of your solution:

   http-request set-var(txn.host) hdr(host),field(1,:)
   acl ssl_sni_http_host_match ssl_fc_sni,strcmp(txn.host) eq 0
   http-request deny deny_status 421 if !ssl_sni_http_host_match { 
ssl_fc_has_sni }

- I am using the field converter to strip away any ports from the host header

This looks good to me.

- I only deny requests that actually use SNI

I disagree, but your mileage may vary.

What are your thoughts on this? I know that technically this would still allow 
clients to do this:

curl https://myhost.com:443 -H "host: myhost.com:1234"

this would then pass and not be denied.
But I don't see any other choice since SNI will never contain a port, I must 
ignore it in the comparison.

You technically could compare the port in the 'host' header, if any, with the actual port (you can retrieve it using 'dst_port'). You must decide whether this is important for your environment or not.

Best regards
Tim Düsterhus

Reply via email to