Re: SNI spoofing in HAproxy?

2021-07-05 Thread Joao Morais



> Em 5 de jul. de 2021, à(s) 09:30, Froehlich, Dominik 
>  escreveu:
> 
> 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 }

The last line doesn’t make sense to me if you use mTLS. Using this 
configuration you’d let the client choose to not inform the SNI extension and 
use whatever header he want to use. You should either block the request if SNI 
and Host header differs despite the use of the SNI extension (which will lead 
to block due to the match failing) or ignore the SNI at all. The former should 
be used on multi site deployments, the later should be used when you have only 
one single domain per ip+port. You cannot mix both, you cannot optionally use 
the SNI extension and also use mTLS on multi site deployments for security 
reason.

~jm




Re: SNI spoofing in HAproxy?

2021-07-05 Thread Tim Düsterhus

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/haproxy@formilux.org/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



Re: Proposal about new default SSL log format

2021-07-05 Thread Tim Düsterhus

Remi,

On 7/5/21 5:15 PM, Remi Tricot-Le Breton wrote:

1) tab separated is better for any log import tool (mixing spaces and
"/" is terrible for import)


I don't have any problems with that apart from inconsistency with the
other default formats. If switching to tabs for this format only does
not bother anyone I'll do it.


This inconsistency bothers me. Tabs also bother me in general, because 
they make it hard for a human to parse the log format, whereas one can 
simply teach a program to understand the HAProxy format. With 'halog' 
there already is a dedicated log parser that works with HAProxy's format.


Regarding my suggestion of %ID: I also don't think it is useful to put 
%ID into the SSL log when it is not in the HTTP log. Please don't do 
this, unless you also introduce an updated 'option httplog2' or 
something like this.


Best regards
Tim Düsterhus



Re: Proposal about new default SSL log format

2021-07-05 Thread Remi Tricot-Le Breton

Hello,

On 02/07/2021 16:52, Илья Шипицин wrote:

I worked with log formats a lot, couple of thoughts

1) tab separated is better for any log import tool (mixing spaces and 
"/" is terrible for import)


I don't have any problems with that apart from inconsistency with the 
other default formats. If switching to tabs for this format only does 
not bother anyone I'll do it.



2) time should be iso8601


For now the "format" field of the "log" option only applies to the log 
line header (containing the timestamp and process_name/pid). It could be 
nice that it applies also to all time related fields of the log format. 
I'll try to see if it is easily feasible.


Thanks

Rémi



Re: SNI spoofing in HAproxy?

2021-07-05 Thread Froehlich, Dominik
Hi Tim,

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
- It fails if the client adds a port to the host header

So to my understanding, it is perfectly fine for a client to not use SNI if 
there is only one certificate to be used.
HAproxy should deny requests only if SNI and host header don't match AND there 
is a value in SNI set.

As for the second part, I've come across some clients that set the port number 
in the host header, even if it is a well-known port.
HAproxy should accept that and compare SNI and host header based on name only, 
since SNI will never contain a port.

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
- I only deny requests that actually use SNI

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.

Best regards,
Dominik

On 25.06.21, 11:07, "Tim Düsterhus"  wrote:

Dominik,

On 6/25/21 10:42 AM, Froehlich, Dominik wrote:
> Your code sends a 421 if the SNI and host header don't match.
> Is this the recommended behavior? The RFC is pretty thin here:
> 
> "   Since it is possible for a client to present a different server_name
> in the application protocol, application server implementations that
> rely upon these names being the same MUST check to make sure the
> client did not present a different name in the application protocol."
> (from https://datatracker.ietf.org/doc/html/rfc6066#section-11.1 )

Indeed it is. See the HTTP/2 RFC: 
https://datatracker.ietf.org/doc/html/rfc7540#section-9.1.1.

Additionally I would recommend using single-domain certificates (if 
possible), then a regular browser will never see a 421, because it will 
not perform connection reuse.

> My initial idea was to simply pave over any incoming headers with the SNI:
> 
>>  http-request set-header Host %[ssl_fc_sni] if { ssl_fc_has_sni }
> 
> This wouldn't abort the request with a 421 but I am not sure if I MUST 
abort it to be compliant.

This is equivalent to routing based off the SNI directly and it's as 
unsafe. If a browser reuses a TCP connection for an unrelated host you 
will send the request to the wrong backend.

> Regarding domain fronting, I thought I might be able to have the cake and 
eat it, too if I still allowed it but only prevented it for mTLS
> Requests. Maybe like this:
> 
>>  http-request set-header Host %[ssl_fc_sni] if { ssl_c_used }
> 
> 

Only performing checks when `ssl_c_used` is true should be safe. But I 
*strongly* recommend sending a 421 instead of attempting to fiddle 
around with the 'host' header. It's just too easy to accidentally 
perform incorrect routing. It would then look like this:

> http-request   set-var(txn.host)hdr(host)
> http-request   deny deny_status 400 unless { req.hdr_cnt(host) eq 1 }
> # Verify that SNI and Host header match if a client certificate is 
sent
> http-request   deny deny_status 421 if { ssl_c_used } ! { 
ssl_fc_sni,strcmp(txn.host) eq 0 }

Best regards
Tim Düsterhus



Re: proposed enhancement to mysql-check - accept account locked/password expired errors

2021-07-05 Thread Christopher Faulet

Le 7/1/21 à 7:14 AM, Daniel Black a écrit :

It seems users are still disturbed at creating passwordless users in
mysql for mysql-check.
https://discourse.haproxy.org/t/haproxy-mysql-check-user-removal/6685

I certainly understand not wanting to implement the truly ugly
implementation that is the protocol to support multiple password
mechanisms ( mysql_native_password, mysql_caching_sha256_password
etc).

As a middle ground, would you be willing to take a haproxy patch that:
* accepts an account locked error on the client as a valid state?; and/or
* offer the CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS client capability and
accept the password expired error ( 1820) as a valid state?

This would enable users to deploy a user account for MySQL and MariaDB
that is truly unusable and make the assessment to use this
functionality easier from a risk management point of view.

On the mysql/mariadb server side both of these are Notes like below:

2021-07-01T04:41:03.144498Z 4554 [Note] Your password has expired. To
log in you must change it using a client that supports expired
passwords.
2021-07-01T04:57:30.706593Z 5056 [Note] Access denied for user
'haproxy'@'10.0.2.100'. Account is locked.

This has the consequences that:
* these aren't counted as connection errors therefore reaching the
default 100 max_connect_errors isn't hit because of this.
* dropping MySQL's log_error_verbosity=2 from 3(default) will hide
these informational messages from the logs that would otherwise be
quite noisy while not hiding anything else too significant.

In the same area of code, dropping the MySQL-4.0 protocol support is
probably called for given the MySQL-5.0 was end of support in January
9, 2012 https://endoflife.software/applications/databases/mysql . 4.1
protocol is still in use.



Hi,

First of all, it is a good idea to remove support of "pre-41" option. It is not 
the default option anymore and I guess it is old enough to be removed. It is now 
on my todo list.


About the MySQL check itself and the way it works, I'm open to any suggestion. 
From the check point of view, your proposal seems reasonable. Of course, the 
actual behavior must still be supported (passwordless account). However, from 
the MySQL administration point of view, I don't know if it is acceptable or not. 
I'm not a MySQL admin and I don't know if it is acceptable or not to change the 
log level.


I guess that if no one has a better idea or any objections about this change, 
you can provide a patch.


--
Christopher Faulet



Re: [PATCH] DOC: use CREATE USER for mysql-check

2021-07-05 Thread Christopher Faulet

Le 7/1/21 à 4:09 AM, Daniel Black a écrit :

CREATE USER has been the standard way of creating users since
MySQL-5.0 (2005).

The current syntax of INSERT INTO mysql.user won't actually work
on MariaDB-10.4+.

Because haproxy doesn't use any resources the MySQL executable comment
syntax provides resource contraints to make it more palatable
to risk adverse users.

/*!50701 is a syntax recognised by MySQL and MariaDB 5.7.1+ when
resource contraints where added.

/*M!100201 is a MariaDB executable comment syntax recognised for MariaDB
for the 10.2.1 where the MAX_STATEMENT_TIME was added.

This patch may be backported as far as 2.0.
---
  doc/configuration.txt | 11 ++-
  1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 5d1c97bd3..a9bbf6fa4 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -8982,12 +8982,13 @@ option mysql-check [ user  [ { post-41 | 
pre-41 } ] ]
one Client Authentication packet, and one QUIT packet, to correctly close
MySQL session. We then parse the MySQL Handshake Initialization packet 
and/or
Error packet. It is a basic but useful test which does not produce error nor
-  aborted connect on the server. However, it requires adding an authorization
-  in the MySQL table, like this :
+  aborted connect on the server. However, it requires an unlocked authorised
+  user without a password. To create a basic limited user in MySQL with
+  optional resource limits:
  
-  USE mysql;

-  INSERT INTO user (Host,User) values ('','');
-  FLUSH PRIVILEGES;
+  CREATE USER ''@''
+  /*!50701 WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 0 */
+  /*M!100201 MAX_STATEMENT_TIME 0.0001 */;
  
If you don't specify a username (it is deprecated and not recommended), the

check only consists in parsing the Mysql Handshake Initialization packet or



Merged now, thanks !

--
Christopher Faulet



Re: [PATCH]: BUILD/MEDIUM: set-mark openbsd support

2021-07-05 Thread Christopher Faulet

Le 7/3/21 à 10:22 AM, David CARLIER a écrit :

Hi here a follow-up of the previous patch but this time for OpenBSD.



Thanks, applied now !

--
Christopher Faulet



Re: Proposal about new default SSL log format

2021-07-05 Thread Remi Tricot-Le Breton

Hello,

On 02/07/2021 16:56, Илья Шипицин wrote:
also, "process name" is something that is prior knowledge. no need to 
log it every time (for millions of requests)


This process name part does not seem to come from the log format line, 
it is never mentioned in the HTTP log-format string. If it is a prefix 
appended to all the haproxy logs it will also be added to SSL ones, 
regardless of the new log format.


Rémi



Re: Proposal about new default SSL log format

2021-07-05 Thread Remi Tricot-Le Breton

Hello Tim,

On 02/07/2021 16:34, Tim Düsterhus wrote:

Remi,

On 7/2/21 4:26 PM, Remi Tricot-Le Breton wrote:

But if anybody sees a missing information that could be
beneficial for everybody, feel free to tell it, nothing is set in 
stone yet.

[…]
Feel free to suggest any missing data, which could come from log-format
specific fields or already existing sample fetches.



Not sure whether the HTTP format will also be updated then, but: Put 
%ID somewhere by default, please.


I won't touch the HTTP format yet because it would bring too much 
trouble for now since some people might already have dedicated parsers 
they can't change whenever they want but I can easily add this ID field 
to the SSL format.


Thanks

Rémi



Re: Hey! I want to partner with you.

2021-07-05 Thread Nova Meyer
Hello,



Making sure my last message reached your inbox. I know gmail can get pretty
chaotic and things get lost all the time, so I was wondering how I can get
back on your radar.

To reiterate it, I work for Geonode  , the leading
unmetered residential proxy services for developers and I noticed that you
have content that touch base our site's focus.

With that, I am following up for your response if you could feature our
site in your site.

I will wait for your response and I am looking forwards to our
collaboration.



Thanks,

Nova


-Original Message-

Hey Team,

I'm Nova from Geonode  . We're the leading unmetered
residential proxy services for developers.

I've been looking for content related to *Residential Proxies *and I
noticed that on your site, you write and link to a lot of content relevant
to it, just like this  https://www.haproxy.org, and it caught my eye.

The reason I wanted to reach out is because I think there might be some
mutually beneficial collaboration opportunities.

If you are open to linking to our site, we would be happy to collaborate
with you.

I thought your readers might find it as a useful resource and it would make
a nice addition to your page.

Let me know what you think about it.

Thank you and keep up the great work at  haproxy.org!



All the best,

N