Re: HTTPS(nbproc > 1) and HTTP/2 help

2019-01-09 Thread Willy Tarreau
Hi Jarno,

On Thu, Jan 03, 2019 at 10:31:41AM +0200, Jarno Huuskonen wrote:
> Hi,
> 
> I'm trying to convert "legacy" haproxy (haproxy 1.9.0) config that has
> mode tcp https listen (bind-process 2 ...) feeding bind-process 1
> frontend via abns socket. Something like this:
> 
>   listen HTTPS_in
>   # missing bind-process etc.
>   mode tcp
>   tcp-request inspect-delay 3s
>   bind 127.0.0.1:8443 ssl crt common.pem alpn h2,http/1.1
> 
> #use-server h2 if { ssl_fc_alpn h2 }
> #use-server h1 unless { ssl_fc_alpn h2 }
>   server h1 abns@proc1 send-proxy-v2
>   #server h2 abns@proc1h2 send-proxy-v2
> 
>   frontend fe
>   mode http
>   bind abns@proc1 accept-proxy
>   bind abns@proc1h2 accept-proxy proto h2
>   tcp-request inspect-delay 5s
>   tcp-request content track-sc1 src table table1
>   
>   # sc1_http_req_cnt(table1) gt 4 || 1 are just examples
>   tcp-request content reject if { sc1_http_req_cnt(table1) gt 4 }
>   http-request deny deny_status 429 if { sc1_http_req_cnt(table1) 
> gt 1 }
> 
>   default_backend be
>   
>   backend be
>   mode http
>   http-request deny deny_status 200 # or some real servers
> 
>   backend table1
>   stick-table type ipv6 size 100 expire 120s store 
> http_req_cnt,http_req_rate(30s)
> 
> This doesn't work with alpn h2,http/1.1 (HTTP/2 doesn't work(as expected)).

I don't understand why it doesn't work. I guess what you're trying to do
is to off-load TLS on multiple front processes and process only clear
traffic on a single process, right ?

> Changing HTTPS_in to "mode http" kind of works, client gets error 400 (HTTP/2)
> or 502 (HTTP/1.1) when (tcp-request content reject) reject's the connection.

Here H2 should indeed not work since the server mode defaults to H1.
However the H1 to H1 should theorically work.

> mode tcp and use-server with ssl_fc_alpn h2 also seems to work, but can the
> client choose not use HTTP/2 with alpn h2 (at least the ssl_fc_alpn
> documentation suggests this) ? 

The client can choose to speak whatever protocol it wants, it's just an
advertisement to indicate the intent. For example you can connect using
openssl s_client -alpn h2 -connect 127.0.0.1:8443 and emit what you want.
It's the H2 mux which will try to decode this traffic due to the "proto h2"
directive which will verify if the protocol is understood or not.

> So it seems that some/best alternatives are:
> - use "mode http" and use http-request deny instead of tcp-request content
> reject (sends response instead of silently closing connection -> no error
> 400/502)
> - use nbproc 1 / nbthread > 1 and move HTTPS_in functionality to fe frontend

It's true that nbthread makes such things so much easier that it's
worth a try, especially in 1.9 where they are more robust than in the
early 1.8, and much faster! With that said, I'm perplex about your
config, I'm interested in figuring why it doesn't work. Please test
it with 1.9.1 or 2.0-dev in case it's just caused by an already fixed
bug.

> Are there any more alternatives/tricks on using more than 1 core for
> SSL and enabling HTTP/2 ? Are there any gotchas etc. to look out for
> when converting nbproc to nbthread config ?

Turning nbproc to nbthread is rather easy since you remove some config.
This definitely is what I'd encourage you to do as it's a nice long
term investment. Even with latest 1.8, unless you really have many
threads, you should move to nbthread.

Regards,
Willy



HTTPS(nbproc > 1) and HTTP/2 help

2019-01-03 Thread Jarno Huuskonen
Hi,

I'm trying to convert "legacy" haproxy (haproxy 1.9.0) config that has
mode tcp https listen (bind-process 2 ...) feeding bind-process 1
frontend via abns socket. Something like this:

listen HTTPS_in
# missing bind-process etc.
mode tcp
tcp-request inspect-delay 3s
bind 127.0.0.1:8443 ssl crt common.pem alpn h2,http/1.1

#use-server h2 if { ssl_fc_alpn h2 }
#use-server h1 unless { ssl_fc_alpn h2 }
server h1 abns@proc1 send-proxy-v2
#server h2 abns@proc1h2 send-proxy-v2

frontend fe
mode http
bind abns@proc1 accept-proxy
bind abns@proc1h2 accept-proxy proto h2
tcp-request inspect-delay 5s
tcp-request content track-sc1 src table table1

# sc1_http_req_cnt(table1) gt 4 || 1 are just examples
tcp-request content reject if { sc1_http_req_cnt(table1) gt 4 }
http-request deny deny_status 429 if { sc1_http_req_cnt(table1) 
gt 1 }

default_backend be

backend be
mode http
http-request deny deny_status 200 # or some real servers

backend table1
stick-table type ipv6 size 100 expire 120s store 
http_req_cnt,http_req_rate(30s)

This doesn't work with alpn h2,http/1.1 (HTTP/2 doesn't work(as expected)).

Changing HTTPS_in to "mode http" kind of works, client gets error 400 (HTTP/2)
or 502 (HTTP/1.1) when (tcp-request content reject) reject's the connection.

mode tcp and use-server with ssl_fc_alpn h2 also seems to work, but can the
client choose not use HTTP/2 with alpn h2 (at least the ssl_fc_alpn
documentation suggests this) ? 

So it seems that some/best alternatives are:
- use "mode http" and use http-request deny instead of tcp-request content 
reject (sends response instead of silently closing connection -> no error 
400/502)
- use nbproc 1 / nbthread > 1 and move HTTPS_in functionality to fe frontend

Are there any more alternatives/tricks on using more than 1 core for
SSL and enabling HTTP/2 ? Are there any gotchas etc. to look out for
when converting nbproc to nbthread config ?

Thanks,
-Jarno
 
-- 
Jarno Huuskonen