Re: [PATCH 1/2] BUG/MINOR: lua: Fix Server.get_addr() port values

2017-07-23 Thread Willy Tarreau
Hi Nenad,

On Sun, Jul 23, 2017 at 10:04:58PM -0400, Nenad Merdanovic wrote:
> The get_addr() method of the Lua Server class was using the
> 'sockaddr_storage addr' member to get the port value. HAProxy does not
> store ports in this member as it uses a separate member, called
> 'svc_port'.

Hmmm good catch. I was the one changing this with commit 04276f3 ("MEDIUM:
server: split the address and the port into two different fields") to fix
a DNS problem, and it was backported into 1.7.2. Too bad I didn't spot this
use case :-/

Both patches merged, thanks!
Willy



Re: Odd behaviour with option forwardfor.

2017-07-23 Thread Willy Tarreau
Hi Aleks,

On Sun, Jul 23, 2017 at 09:50:41AM +0200, Aleksandar Lazic wrote:
> >  Personally I use 2 rules similar to the following to append to   
> > X-Forwarded-For:
> >   
> >    http-request set-header X-Forwarded-For
> > %[req.fhdr(X-Forwarded-For)],\ %[src] if { req.fhdr(X-Forwarded-For)   -m 
> > found }
> >    http-request set-header X-Forwarded-For %[src] if !{
> > req.fhdr(X-Forwarded-For) -m found }
> >   
> >  -Patrick
> 
> But doesn't haproxy do this already?
> 
> http://git.haproxy.org/?p=haproxy-1.7.git;a=blob;f=src/proto_http.c;h=94c8d639f6f777241109f605e1e1742f9a39bf33;hb=HEAD#l4639

It always adds a new header field. But this is strictly equivalent to
adding a new value to an existing entry, it's just much less expensive
(no need to scan the list to find one, nor to move bytes around to insert
a new value).

Willy



Re: Passing SNI value ( ssl_fc_sni ) to backend's verifyhost.

2017-07-23 Thread Willy Tarreau
Hi Kevin,

On Fri, Jul 21, 2017 at 02:06:52PM -0700, Kevin McArthur wrote:
> Further... the odd/broken behavior might be being caused related to no sni
> indication on the health checks...
> 
> This config sort of works:
> 
> 
> *server app2 ssltest.example.ca:443 ssl verify required /verifyhost
> ssltest.example.ca/ sni ssl_fc_sni ca-file
> /etc/ssl/certs/ca-certificates.crt check check-ssl*
> 
> This lets me load ssltest.example.ca via the proxy.
> 
> 
> *server app2 anotherdomain.example.ca:443 ssl verify required /verifyhost
> anotherdomain.example.ca/ sni ssl_fc_sni ca-file
> /etc/ssl/certs/ca-certificates.crt check check-ssl*
> 
> Jul 21 20:57:55 haproxy1 haproxy[8371]: Health check for server
> www-backend-https/app2 failed, reason: Layer6 invalid response, info: "SSL
> handshake failure", check duration: 3ms, status: 0/2 DOWN.
> 
> Fails health check (no sni) verifyhost match (anotherdomain.example.ca isnt
> the default on the backend server). So ends up in "No server is available to
> handle this request."
> 
> 
> *server app2 ssltest.example.ca:443 ssl verify required /verifyhost
> ssl_fc_sni/ sni ssl_fc_sni ca-file /etc/ssl/certs/ca-certificates.crt check
> check-ssl*
> 
> Jul 21 20:57:55 haproxy1 haproxy[8371]: Health check for server
> www-backend-https/app2 failed, reason: Layer6 invalid response, info: "SSL
> handshake failure", check duration: 3ms, status: 0/2 DOWN.
> 
> This fails health check.
> 
> 
> *server app2 ssltest.example.ca:443 ssl verify required sni ssl_fc_sni
> ca-file /etc/ssl/certs/ca-certificates.crt check check-ssl*
> 
> This works, but without verifying the host properly. Can load
> anotherdomain.example.ca and the sni is passed along properly.
> 
> 
> Perhaps its the host checks sni support and not this patch that are not
> working correctly?

The "verifyhost" directive *forces* the host name to be checked and ignores
the SNI. By just removing it from your "server" lines, it must be OK. Your
last example above suggests it works. Why do you say that the host is not
properly verified ? Have you checked that you can connect to a server
presenting the wrong cert ? For me it refuses it and only accepts the
correct cert (the one having the same name as asked in the SNI).

Willy



[PATCH 1/2] BUG/MINOR: lua: Fix Server.get_addr() port values

2017-07-23 Thread Nenad Merdanovic
The get_addr() method of the Lua Server class was using the
'sockaddr_storage addr' member to get the port value. HAProxy does not
store ports in this member as it uses a separate member, called
'svc_port'.

This fix should be backported to 1.7.
---
 src/hlua_fcn.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/hlua_fcn.c b/src/hlua_fcn.c
index 8406bfe5..0df9025c 100644
--- a/src/hlua_fcn.c
+++ b/src/hlua_fcn.c
@@ -545,8 +545,7 @@ int hlua_server_get_addr(lua_State *L)
  addr, INET_ADDRSTRLEN);
luaL_addstring(, addr);
luaL_addstring(, ":");
-   snprintf(addr, INET_ADDRSTRLEN, "%d",
-ntohs(((struct sockaddr_in *)>addr)->sin_port));
+   snprintf(addr, INET_ADDRSTRLEN, "%d", srv->svc_port);
luaL_addstring(, addr);
break;
case AF_INET6:
@@ -554,8 +553,7 @@ int hlua_server_get_addr(lua_State *L)
  addr, INET_ADDRSTRLEN);
luaL_addstring(, addr);
luaL_addstring(, ":");
-   snprintf(addr, INET_ADDRSTRLEN, "%d",
-ntohs(((struct sockaddr_in6 *)>addr)->sin6_port));
+   snprintf(addr, INET_ADDRSTRLEN, "%d", srv->svc_port);
luaL_addstring(, addr);
break;
case AF_UNIX:
-- 
2.11.0




[PATCH 2/2] BUG/MINOR: lua: Correctly use INET6_ADDRSTRLEN in Server.get_addr()

2017-07-23 Thread Nenad Merdanovic
The get_addr() method of the Lua Server class incorrectly used
INET_ADDRSTRLEN for IPv6 addresses resulting in failing to convert
longer IPv6 addresses to strings.

This fix should be backported to 1.7.
---
 src/hlua_fcn.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/hlua_fcn.c b/src/hlua_fcn.c
index 0df9025c..420c7664 100644
--- a/src/hlua_fcn.c
+++ b/src/hlua_fcn.c
@@ -550,7 +550,7 @@ int hlua_server_get_addr(lua_State *L)
break;
case AF_INET6:
inet_ntop(AF_INET6, &((struct sockaddr_in6 
*)>addr)->sin6_addr,
- addr, INET_ADDRSTRLEN);
+ addr, INET6_ADDRSTRLEN);
luaL_addstring(, addr);
luaL_addstring(, ":");
snprintf(addr, INET_ADDRSTRLEN, "%d", srv->svc_port);
-- 
2.11.0




Re: Odd behaviour with option forwardfor.

2017-07-23 Thread Aleksandar Lazic
Hi Claus,

Claus Strommer wrote on 23.07.2017:

> Hi Aleks,
>
> Patrick's solution is correct.  What I was expecting was that HAProxy would 
> take
>
> X-Forwarded-For: 1.1.1.1
>
> and produce
>
> X-Forwarded-For: 1.1.1.1,2.2.2.2
>
> but what it actually does is produce
>
> X-Forwarded-For: 1.1.1.1
> X-Forwarded-For: 2.2.2.2
>
> The backend concatenates the lines and treats them like what I was
> expecting, but when I do a header capture in the second HAProxy it only reads 
> the second line.

Thanks for clarification.
I thought that haproxy produce the concated header.

Best regards
Aleks

> And yes, my snippet is missing the header capture on the http
> frontend, thanks for spotting that. 
>
> On Jul 23, 2017 03:50, "Aleksandar Lazic"  wrote:

> Hi Patrick Hemmer,


>  Patrick Hemmer wrote on 22.07.2017:

 >> On 2017/7/22 11:11, Claus Strommer wrote:
 >>
 >> Hi all, I'm seeing some odd behaviour with our
 >> haproxy balancer and am looking for some insights.
 >>
 >>                        The setup:
 >>
 >>                        I have a webserver that is behind two haproxy
 >> balancers (version 1.5.18 on EL7), which are
 >> behind CloudFlare.   In effect the request goes
 >>
 >>                           
 >> client->CF->haproxy1->haproxy2->server. 
 >>
 >>                        On both haproxy balancers I have "option
 >> forwardfor" and "capture request header
 >> X-Forwarded-For len 128" set.
 >> On the server I also capture X-Forwarded-For
 >>
 >> Now here is where the odd behaviour
 >> (highlighted)                     happens:
 >>
 >>              * haproxy1 logs the full X-Forwarded-For header.
 >>              * haproxy2 only logs the IP of the CF proxy (the   last 
 >>address in X-Forwarded-For)
 >>              * server logs the full X-Forwarded-For header.
 >>              * If I turn off "option forwardfor" on haproxy1, then
 >> haproxy2 logs the full header as received by CF. 
 >>              * Changing the length of the capture request does not
 >> seem to   make a difference.
 >>
 >> * I noticed that haproxy uses spaces after the comma
 >> between the header entries, but CF does not.  I tried
 >> replicating this issue with a direct curl request to haproxy2
 >> replicating the x-forwarded-for header that haproxy1 would
 >> have sent, and I cannot reproduce the issue.
 >>
 >> The only thing that I notice is that CF
 >>
 >>
 >>            Am I missing something obvious here?  Below are the full
 >> options         I'm using on haproxy1 and haproxy2.  Everything after that 
 >> is         ACLs
 >>
 >>   defaults
 >>                mode    http
 >>                log global
 >>                option  httplog
 >>                option  dontlognull
 >>                option http-server-close
 >>                option forwardfor   except 127.0.0.0/8
 >>                option  redispatch
 >>                retries 3
 >>
 >>            frontend  http *:80
 >>                mode http
 >>                reqadd X-Forwarded-Proto:\ https

> I miss here the

>  capture request header X-Forwarded-For len 15


 >>                redirect scheme https code 301
 >>
 >>            frontend https
 >>                bind *:443 ssl crt /etc/pki/tls/certs/hacert.pem
 >>                mode http
 >>                capture request header Host len 50

> I miss here the

>  capture request header X-Forwarded-For len 15

>  Can you try to run haproxy for a short time in debug mode?

> http://cbonte.github.io/haproxy-dconv/1.7/management.html#3

>  -d


 >>      The "option forwardfor" setting appends a complete new header,
 >> not     appends the value to an existing header. From the docs on "option   
 >>   forwardfor":
 >>      > Enable insertion of the X-Forwarded-For header to requests sent     
 >>to servers
 >>      ...
 >>      > this header is always appended at the end of the existing     header 
 >>list
 >>
 >>      Your header capture is grabbing the last X-Forwarded-For header.
 >>      On issues like this, you should perform a packet capture. It
 >> would     make the issue immediately apparent.
 >>
 >>      Personally I use 2 rules similar to the following to append to   
 >>X-Forwarded-For:
 >>
 >>        http-request set-header X-Forwarded-For
 >> %[req.fhdr(X-Forwarded-For)],\ %[src] if { req.fhdr(X-Forwarded-For)   -m 
 >> found }
 >>        http-request set-header X-Forwarded-For %[src] if !{
 >> req.fhdr(X-Forwarded-For) -m found }
 >>
 >>      -Patrick

> But doesn't haproxy do this already?

> http://git.haproxy.org/?p=haproxy-1.7.git;a=blob;f=src/proto_http.c;h=94c8d639f6f777241109f605e1e1742f9a39bf33;hb=HEAD#l4639


>  --
>  Best Regards
>  Aleks






-- 
Best Regards
Aleks




Re: Odd behaviour with option forwardfor.

2017-07-23 Thread Claus Strommer
Hi Aleks,

Patrick's solution is correct.  What I was expecting was that HAProxy would
take

X-Forwarded-For: 1.1.1.1

and produce

X-Forwarded-For: 1.1.1.1,2.2.2.2

but what it actually does is produce

X-Forwarded-For: 1.1.1.1
X-Forwarded-For: 2.2.2.2

The backend concatenates the lines and treats them like what I was
expecting, but when I do a header capture in the second HAProxy it only
reads the second line.

And yes, my snippet is missing the header capture on the http frontend,
thanks for spotting that.



On Jul 23, 2017 03:50, "Aleksandar Lazic"  wrote:

Hi Patrick Hemmer,

Patrick Hemmer wrote on 22.07.2017:

> On 2017/7/22 11:11, Claus Strommer wrote:
>
> Hi all, I'm seeing some odd behaviour with our
> haproxy balancer and am looking for some insights.
>
>The setup:
>
>I have a webserver that is behind two haproxy
> balancers (version 1.5.18 on EL7), which are
> behind CloudFlare.   In effect the request goes
>
>
> client->CF->haproxy1->haproxy2->server.
>
>On both haproxy balancers I have "option
> forwardfor" and "capture request header
> X-Forwarded-For len 128" set.
> On the server I also capture X-Forwarded-For
>
> Now here is where the odd behaviour
> (highlighted) happens:
>
>  * haproxy1 logs the full X-Forwarded-For header.
>  * haproxy2 only logs the IP of the CF proxy (the   last
address in X-Forwarded-For)
>  * server logs the full X-Forwarded-For header.
>  * If I turn off "option forwardfor" on haproxy1, then
> haproxy2 logs the full header as received by CF.
>  * Changing the length of the capture request does not
> seem to   make a difference.
>
> * I noticed that haproxy uses spaces after the comma
> between the header entries, but CF does not.  I tried
> replicating this issue with a direct curl request to haproxy2
> replicating the x-forwarded-for header that haproxy1 would
> have sent, and I cannot reproduce the issue.
>
> The only thing that I notice is that CF
>
>
>Am I missing something obvious here?  Below are the full
> options I'm using on haproxy1 and haproxy2.  Everything after
that is ACLs
>
>   defaults
>modehttp
>log global
>option  httplog
>option  dontlognull
>option http-server-close
>option forwardfor   except 127.0.0.0/8
>option  redispatch
>retries 3
>
>frontend  http *:80
>mode http
>reqadd X-Forwarded-Proto:\ https

I miss here the

capture request header X-Forwarded-For len 15

>redirect scheme https code 301
>
>frontend https
>bind *:443 ssl crt /etc/pki/tls/certs/hacert.pem
>mode http
>capture request header Host len 50

I miss here the

capture request header X-Forwarded-For len 15

Can you try to run haproxy for a short time in debug mode?

http://cbonte.github.io/haproxy-dconv/1.7/management.html#3

-d

>  The "option forwardfor" setting appends a complete new header,
> not appends the value to an existing header. From the docs on
"option forwardfor":
>  > Enable insertion of the X-Forwarded-For header to requests sent
 to servers
>  ...
>  > this header is always appended at the end of the existing
 header list
>
>  Your header capture is grabbing the last X-Forwarded-For header.
>  On issues like this, you should perform a packet capture. It
> would make the issue immediately apparent.
>
>  Personally I use 2 rules similar to the following to append to
 X-Forwarded-For:
>
>http-request set-header X-Forwarded-For
> %[req.fhdr(X-Forwarded-For)],\ %[src] if { req.fhdr(X-Forwarded-For)   -m
found }
>http-request set-header X-Forwarded-For %[src] if !{
> req.fhdr(X-Forwarded-For) -m found }
>
>  -Patrick

But doesn't haproxy do this already?

http://git.haproxy.org/?p=haproxy-1.7.git;a=blob;f=src/proto_http.c;h=
94c8d639f6f777241109f605e1e1742f9a39bf33;hb=HEAD#l4639


--
Best Regards
Aleks


Re: Odd behaviour with option forwardfor.

2017-07-23 Thread Aleksandar Lazic
Hi Patrick Hemmer,

Patrick Hemmer wrote on 22.07.2017:

> On 2017/7/22 11:11, Claus Strommer wrote:
>   
> Hi all, I'm seeing some odd behaviour with our  
> haproxy balancer and am looking for some insights.
>   
>The setup:
>   
>I have a webserver that is behind two haproxy 
> balancers (version 1.5.18 on EL7), which are  
> behind CloudFlare.   In effect the request goes
>   
>     
> client->CF->haproxy1->haproxy2->server.   
>   
>On both haproxy balancers I have "option  
> forwardfor" and "capture request header  
> X-Forwarded-For len 128" set.
> On the server I also capture X-Forwarded-For
>   
> Now here is where the odd behaviour
> (highlighted) happens:
>   
>  * haproxy1 logs the full X-Forwarded-For header. 
>  * haproxy2 only logs the IP of the CF proxy (the   last address 
> in X-Forwarded-For)
>  * server logs the full X-Forwarded-For header.
>  * If I turn off "option forwardfor" on haproxy1, then 
> haproxy2 logs the full header as received by CF.  
>  * Changing the length of the capture request does not
> seem to   make a difference.
> 
> * I noticed that haproxy uses spaces after the comma  
> between the header entries, but CF does not.  I tried  
> replicating this issue with a direct curl request to haproxy2 
> replicating the x-forwarded-for header that haproxy1 would  
> have sent, and I cannot reproduce the issue. 
> 
> The only thing that I notice is that CF 
> 
>
>Am I missing something obvious here?  Below are the full
> options I'm using on haproxy1 and haproxy2.  Everything after that is 
> ACLs
>   
>   defaults
>    mode    http
>    log global
>    option  httplog
>    option  dontlognull
>    option http-server-close
>    option forwardfor   except 127.0.0.0/8
>    option  redispatch
>    retries 3
>   
>frontend  http *:80
>    mode http
>    reqadd X-Forwarded-Proto:\ https

I miss here the

capture request header X-Forwarded-For len 15

>    redirect scheme https code 301
>   
>frontend https
>    bind *:443 ssl crt /etc/pki/tls/certs/hacert.pem
>    mode http
>    capture request header Host len 50

I miss here the

capture request header X-Forwarded-For len 15

Can you try to run haproxy for a short time in debug mode?

http://cbonte.github.io/haproxy-dconv/1.7/management.html#3

-d
   
>  The "option forwardfor" setting appends a complete new header,
> not appends the value to an existing header. From the docs on "option 
> forwardfor":
>  > Enable insertion of the X-Forwarded-For header to requests sent to 
> servers
>  ...
>  > this header is always appended at the end of the existing header 
> list
>   
>  Your header capture is grabbing the last X-Forwarded-For header.
>  On issues like this, you should perform a packet capture. It
> would make the issue immediately apparent.
>   
>  Personally I use 2 rules similar to the following to append to   
> X-Forwarded-For:
>   
>    http-request set-header X-Forwarded-For
> %[req.fhdr(X-Forwarded-For)],\ %[src] if { req.fhdr(X-Forwarded-For)   -m 
> found }
>    http-request set-header X-Forwarded-For %[src] if !{
> req.fhdr(X-Forwarded-For) -m found }
>   
>  -Patrick

But doesn't haproxy do this already?

http://git.haproxy.org/?p=haproxy-1.7.git;a=blob;f=src/proto_http.c;h=94c8d639f6f777241109f605e1e1742f9a39bf33;hb=HEAD#l4639


-- 
Best Regards
Aleks




Re: AWS ELB as a backend

2017-07-23 Thread Aleksandar Lazic
Hi DHAVAL JAISWAL,

DHAVAL JAISWAL wrote on 21.07.2017:

> I have used ELB (public) as a front of Haproxy and ELB (internal) as a 
> backend for the apps server.
>
> so structure is like as follows. Currently using Haproxy 1.7.
> However, request is not going to the backend server. 
>
> ELB ->> HAPROXY -> ELB -> APPS server. 
>
> Following config in my haproxy.  Let me know what i am doing wrong. 
>
> backend mybackend
>
> server server1
> internal-testinelbtomcat-193184.ap-southeast-1.elb.amazonaws.com

Do you have set a resolver?

http://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.3

Please post also the following data, thanks.

haproxy -vv
anonymized haproxy conf
some error and access logs

-- 
Best Regards
Aleks