On Fri, Jul 13, 2018 at 11:26 AM, Igor Cicimov <
[email protected]> wrote:

> On Fri, Jul 13, 2018 at 11:08 AM, Igor Cicimov <
> [email protected]> wrote:
>
>> Hi Martin,
>>
>> On Thu, Jul 12, 2018 at 6:55 PM, Martin RADEL <
>> [email protected]> wrote:
>>
>>> Hi all,
>>>
>>>
>>>
>>> we have a strange situation with our HAProxy, running on Version 1.8.8
>>> with OpenSSL.
>>>
>>> (See the details in the setup listed below - some lines are missing by
>>> intention. It’s a config snippet with just the interesting parts mentioned)
>>>
>>>
>>>
>>> Initial situation:
>>>
>>> We run a HAProxy instance which enforces mutual TLS on the frontend,
>>> allowing only clients to connect to it when they will present a specific
>>> certificate.
>>>
>>> The HAPRoxy also does mutual TLS to the backend, presenting its frontend
>>> server certificate to the backend as a client certificate.
>>>
>>> The backend only allows connections when the HAProxy’s certificate is
>>> presented to it.
>>>
>>> To have a proper TLS handshake to the backend, and to be able to
>>> identify a man-in-the-middle scenario, we use the “verify required”
>>> directive together with the “verifyhost” directive.
>>>
>>>
>>>
>>> The HAProxy is not able to resolve the backend’s real DNS-hostname, so
>>> it’s using the IP of the server instead (10.1.1.1)
>>>
>>> The backend is presenting a wildcard server certificate with a
>>> DNS-hostname looking like “*.foo.bar”
>>>
>>>
>>>
>>>
>>>
>>> In this configuration, one could assume that there is always a
>>> certificate name mismatch with the TLS handshake:
>>>
>>> Backend server will present its server certificate with a proper DNS
>>> hostname in it, and the HAProxy will find out that it doesn’t match the
>>> initially used connection name “10.1.1.1”.
>>>
>>>
>>>
>>
>> ​Just checking if the IP hasn't been by any chance included in the
>> certificate subjectAlternateNames ?
>> ​
>>
>>>
>>>
>>> Issue:
>>>
>>> In fact the connection to the backend works all the time, even when
>>> there is a name mismatch and even if we use the “verify required” option
>>> together with “verifyhost”.
>>>
>>> Seems as if HAProxy completely ignores the mismatch, as if we would use
>>> the option “verify none”.
>>>
>>>
>>>
>>>
>>>
>>> According to HAProxy documentation, this is clearly a not-expected
>>> behavior:
>>>
>>> http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#5.2-verify
>>>
>>>
>>>
>>>
>>>
>>> Can somebody please share some knowledge why this is working, or can
>>> confirm that this is a bug?
>>>
>>>
>>>
>>>
>>>
>>> #---------------------------------------------------------------------
>>>
>>> # Global settings
>>>
>>> #---------------------------------------------------------------------
>>>
>>> global
>>>
>>>     log         /dev/log local2
>>>
>>>     pidfile     /run/haproxy/haproxy.pid
>>>
>>>     maxconn     20000
>>>
>>>     ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES
>>> 256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!
>>> MD5:!DSS:!RC4
>>>
>>>     ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11
>>>
>>>     stats socket /var/lib/haproxy/stats
>>>
>>>
>>>
>>> #---------------------------------------------------------------------
>>>
>>> # common defaults that all the 'listen' and 'backend' sections will
>>>
>>> # use if not designated in their block
>>>
>>> #---------------------------------------------------------------------
>>>
>>> defaults
>>>
>>>     mode                    http
>>>
>>>     log                     global
>>>
>>>     option                  http-server-close
>>>
>>>     option                  redispatch
>>>
>>>     retries                 3
>>>
>>>     maxconn                 20000
>>>
>>>     errorfile 503           /etc/haproxy/errorpage.html
>>>
>>>     default-server          init-addr last,libc,none
>>>
>>>
>>>
>>> # ====================================================
>>>
>>> #  HAPROXY CONFIG WITH WILDCARD CERTIFICATE ON BACKEND
>>>
>>> # ====================================================
>>>
>>> # --- FRONTEND1 (TLS with mutual authentication) ---
>>>
>>> frontend FRONTEND1
>>>
>>>     option                  forwardfor except 127.0.0.0/8
>>>
>>>     acl authorizedClient ssl_c_s_dn(cn) -m str -f
>>> /etc/haproxy/authorized_clients.cfg
>>>
>>>     bind *:443 ssl crt /etc/haproxy/certs/frontend-server-certificate.pem
>>> ca-file /etc/haproxy/certs/frontend-ca-certificates.crt verify required
>>>
>>>     use_backend BACKEND1 if authorizedClient frontend
>>>
>>>
>>>
>>> # --- BACKEND1
>>>
>>> backend BACKEND1
>>>
>>>     option                  forwardfor except 127.0.0.0/8
>>>
>>>     server BACKEND1-server 10.1.1.1:443 check inter 30s  verify
>>> required ssl verifyhost *.foo.bar <http://www.foo.bar> ca-file
>>> /etc/haproxy/certs/backend-ca-certificates.crt crt
>>> /etc/haproxy/certs/frontend-server-certificate.pem
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> This message and any attachment ("the Message") are confidential. If you
>>> have received the Message in error, please notify the sender immediately
>>> and delete the Message from your system, any use of the Message is
>>> forbidden. Correspondence via e-mail is primarily for information purposes.
>>> RBI neither makes nor accepts legally binding statements via e-mail unless
>>> explicitly agreed otherwise. Information pursuant to § 14 Austrian
>>> Companies Code: Raiffeisen Bank International AG; Registered Office: Am
>>> Stadtpark 9
>>> <https://maps.google.com/?q=Am+Stadtpark+9&entry=gmail&source=g>, 1030
>>> Vienna,Austria; Company Register Number: FN 122119m at the Commercial Court
>>> of Vienna (Handelsgericht Wien).
>>>
>>
>>
>> ​Regards,
>> Igor​
>>
>> ​
> Ah, another thing I forgot to ask and might be relevant, are you using SNI
> enabled client for the testing or not?​
>
>
​Sorry to reply again but just noticed the "verifyhost *.foo.bar
<http://www.foo.bar>" in your server line which might explain it all​, see
http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#5.2-verifyhost

This setting is only available when support for OpenSSL was built in, and
only takes effect if 'verify required' is also specified. *This directive sets
a default static hostname to check the server's certificate against when no
SNI was used to connect to the server*. If SNI is not used, this is the only
way to enable hostname verification. This static hostname, when set, will
also be used for health checks (which cannot provide an SNI value). *If none
of the hostnames in the certificate match the specified hostname, the
handshake is aborted*. The hostnames in the server-provided certificate may
include wildcards. See also "verify
<http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#>", "sni
<http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#sni>"
and "no-verifyhost
<http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#no-verifyhost>"
options.


I guess, in combination with absence of SNI, this setting would cause the
hostname to always match your cert.

Reply via email to