HTTP keep-alive reuse count & max-age

2016-02-19 Thread Michał Pasierb
Hi,

Is it possible to influence how HAProxy handles HTTP keep-alives to backend
servers ? I want it to close TCP connection after x many HTTP requests.
Also a max-age time for single TCP connection cloud be useful.

These features are available in F5 LTM OneConnect (
https://support.f5.com/kb/en-us/solutions/public/7000/200/sol7208.html)
as *Maximum
Reuse* and *Maximum Age*.

Goal is to move all TIME_WAITs to HAProxy host instead of creating them on
backend servers.

Thanks,
Michal


Re: Truncated captured request headers

2016-02-19 Thread Adam Renberg
Hi Cyril,

The documentation does indeed explain it, my bad. Changing to use req.fhdr
solves my problem.

Thank you very much for the swift and helpful response!

// Adam

On Thu, Feb 18, 2016 at 7:32 PM Cyril Bonté  wrote:

> Hi Adam,
>
> Le 18/02/2016 11:54, Adam Renberg a écrit :
> > Hi,
> >
> > Today I updated our HAProxy config to capture more request headers into
> > the logs. I added the following configuration to our frontends:
> >
> > ```
> > http-request capture hdr(Host) len 40
> > http-request capture hdr(X-Real-IP) len 15
> > http-request capture hdr(X-Forwarded-For) len 100
> > http-request capture hdr(User-Agent) len 160
> > ```
> >
> > I elected to use `http-request capture` and not `capture request header`
> > because the latter didn't seem to be able to capture request headers
> > that we generate from the same HAProxy frontend. Is this a known issue?
> >
> > Anyway, with this setup, something weird happened with the captured
> > User-Agent header. It is truncated. The captured request header part of
> > the logs looked like this:
> >
> > ```
> > {|192.168.9.1|192.168.9.1|like Gecko)
> > Chrome/48.0.2564.109 Safari/537.36}
> > ```
>
> Indeed, you should use req.fhdr() [1] instead, to capture the whole
> line, otherwise the comma is interpreted as a delimiter to distinguish
> values.
>
> Note that this is explained in the documentation [2] ;-)
>
> [1]
> http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#7.3.6-req.fhdr
> [2]
> http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#7.3.6-req.hdr
>
> --
> Cyril Bonté
>


Using operators in ACLs

2016-02-19 Thread Dmitry Sivachenko
Hello,

I want to define ACL which will evaluate to true if a current number of 
connections to a particular backend is greater than a number of usable servers 
in that backend multiplied on some constant:

be_conn(BACK) > nbsrv(BACK) * N

So far I came up with the following solution:

frontend FRONT
mode http  # can be either http or tcp here
tcp-request content set-var(sess.nb) nbsrv(BACK)  # I use tcp-request here 
(not http-request) so it works for both http and tcp mode backends
acl my_acl be_conn(BACK),div(sess.nb) gt 10  #  "N" in 10 here


So I must use set-var here because div() accepts either a number or a variable.

Is this a good sulution for my problem or it can be done better?

Thanks!


SSL Client Cert based Auth with Exceptions

2016-02-19 Thread Sebastian Schubert

Hi there,

we're in the process of migrating from citrix netscaler to haproxy and 
facing a configuration problem. in this scenario all requests have to 
use a ssl client cert, but for some urls and user-agents there's no cert 
needed.


i get a 403 "go away", but am not asked to show my client cert ...

here's what i did:
haproxy.conf

global
  uid 99
  gid 99
  daemon
  chroot /usr/share/haproxy
  spread-checks 5
  stats socket /var/run/haproxy/admin.sock mode 0600 level admin
  log   127.0.0.1  local2 warning
  log   loghost   local4 warning
  log-send-hostname lb-haproxy
  maxconn 2
  tune.ssl.default-dh-param 2048
  ssl-default-bind-ciphers  ... line too long :-/

defaults
  log global
  maxconn 2
  timeout connect 20s
  timeout server 120s
  timeout client 120s
  timeout check 10s
  retries 3
  mode http
  option log-separate-errors
  option log-health-checks

frontend host-with-clientcert
  mode http
  option forwardfor
  option http-server-close
  bind 195.30.x.y:80
  bind 195.30.x.y:443 ssl crt /home/conf/ssl/cert.pem no-sslv3 \
   ca-file /home/conf/ssl/myca.crt verify optional

  reqidel ^X-Forwarded-For:.*
  http-request set-header X-Forwarded-Proto https if  { ssl_fc }
  http-request set-header X-Forwarded-Proto http  if !{ ssl_fc }
  redirect scheme https if !{ ssl_fc }
  rspadd Strict-Transport-Security:\ max-age=31536000;
  acl nocert path /servlets or hdr_sub(User-Agent) java
  acl crtauth ssl_fc_has_crt ! { ssl_c_verify 10 }
  http-request deny unless nocert or crtauth
  use_backend cms-prod

backend cms-prod
  balance roundrobin
  option httpchk
  server cms ...:443 rise 1 fall 1 inter 3s check ssl verify none

--8<---

haproxy -vv
HA-Proxy version 1.5.14 2015/07/02
Copyright 2000-2015 Willy Tarreau 

Build options :
  TARGET  = linux26
  CPU = generic
  CC  = gcc
  CFLAGS  = -O2 -g -fno-strict-aliasing
  OPTIONS = USE_LINUX_TPROXY=1 USE_ZLIB=yes USE_REGPARM=1 USE_OPENSSL=1 
USE_PCRE=1


Default settings :
  maxconn = 2000, bufsize = 16384, maxrewrite = 8192, maxpollevents = 200

Encrypted password support via crypt(3): yes
Built with zlib version : 1.2.3
Compression algorithms supported : identity, deflate, gzip
Built with OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013
Running on OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports prefer-server-ciphers : yes
Built with PCRE version : 7.8 2008-09-05
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with transparent proxy support using: IP_TRANSPARENT 
IPV6_TRANSPARENT IP_FREEBIND


Available polling systems :
  epoll : pref=300,  test result OK
   poll : pref=200,  test result OK
 select : pref=150,  test result OK
Total: 3 (3 usable), will use epoll.


any ideas, how to configure such a scenario?

cheers
 basti schubert



[BUG] core.msleep yields forever

2016-02-19 Thread Robert Samuel Newson
Hi,

I think I've found a bug in core.msleep (and core.sleep);

foo.lua;

core.register_service("foo", "http", function(applet)
  core.msleep(1)
  local body = "hello"
  applet:set_status(200)
  applet:add_header("Content-Length", string.len(body))
  applet:start_response()
  applet:send(body)
end)

haproxy.cfg

global
  lua-load foo.lua

defaults
  mode http
  timeout client 15
  timeout server 360
  timeout connect 5000
  timeout queue 5000

listen l
  bind 127.0.0.1:6000
  http-request use-service lua.foo

--

steps to reproduce;

curl 127.0.0.1:6000

this will not respond at all.

If you comment out the core.msleep(1) line, you get the expected 200 response.

This seems to occurs wherever core.msleep is used but I've only confirmed this 
behaviour in register_service and register_action functions.

Regards,
Robert Newson.







Re: [BUG] core.msleep yields forever

2016-02-19 Thread Cyril Bonté

Hi Robert,

I add Thierry to the discussion (see below for the details).

Le 19/02/2016 20:15, Robert Samuel Newson a écrit :

Hi,

I think I've found a bug in core.msleep (and core.sleep);

foo.lua;

core.register_service("foo", "http", function(applet)
   core.msleep(1)
   local body = "hello"
   applet:set_status(200)
   applet:add_header("Content-Length", string.len(body))
   applet:start_response()
   applet:send(body)
end)

haproxy.cfg

global
   lua-load foo.lua

defaults
   mode http
   timeout client 15
   timeout server 360
   timeout connect 5000
   timeout queue 5000

listen l
   bind 127.0.0.1:6000
   http-request use-service lua.foo

--

steps to reproduce;

curl 127.0.0.1:6000

this will not respond at all.

If you comment out the core.msleep(1) line, you get the expected 200 response.

This seems to occurs wherever core.msleep is used but I've only confirmed this 
behaviour in register_service and register_action functions.


I'm not expert in the lua code area, but after some tests, I wonder if 
the calls to hlua_yieldk() shoudln't provide the HLUA_CTRLYIELD flag in 
this functions :

- hlua_sleep_yield
- hlua_sleep
- hlua_msleep

Giving something like :
diff --git a/src/hlua.c b/src/hlua.c
index 5cf2320..022c107 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -4983,7 +4983,7 @@ __LJMP static int hlua_sleep_yield(lua_State *L, 
int status, lua_KContext ctx)

 {
int wakeup_ms = lua_tointeger(L, -1);
if (now_ms < wakeup_ms)
-   WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
+		WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 
HLUA_CTRLYIELD));

return 0;
 }

@@ -4998,7 +4998,7 @@ __LJMP static int hlua_sleep(lua_State *L)
wakeup_ms = tick_add(now_ms, delay);
lua_pushinteger(L, wakeup_ms);

-   WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
+	WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 
HLUA_CTRLYIELD));

return 0;
 }

@@ -5013,7 +5013,7 @@ __LJMP static int hlua_msleep(lua_State *L)
wakeup_ms = tick_add(now_ms, delay);
lua_pushinteger(L, wakeup_ms);

-   WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
+	WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 
HLUA_CTRLYIELD));

return 0;
 }

Also, I'm not sure about the wake_time type in "struct lua" : shouldn't 
it be declared as an unsigned int ?
Which then implies some type changes in other parts of the code, for 
example :

- in hlua_sleep_yield() : unsigned int wakeup_ms
- or in hlua_yieldk() : shouldn't "int timeout" be declared as an 
unsigned int also ?


Sorry, I can't have a more longer look on this tonight.

--
Cyril Bonté