2

I am trying to setup a local TCP connection cache to provide access to a remote HTTP server for multiple local applications.

I have started to configure haproxy to do this:

global
    log         /dev/log local0
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    daemon
    stats socket /var/lib/haproxy/stats

defaults
    log global
    mode http
    option http-keep-alive
    timeout http-keep-alive 60000ms
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

frontend  http-in
    option httplog
    bind  127.0.0.1:4443
    default_backend facebook

backend facebook
    server fb graph.facebook.com:443 maxconn 32 ssl verify none

which should allow me to use local proxy (http://localhost:4443) to talk to https://graph.facebook.com

And yes, it kind of works:

$ curl -4 -x http://127.0.0.1:4443 -vvv 'http://graph.facebook.com/v2.4/me?fields=id%2Cname&access_token=CAACEdEose0cBAPvPqQIAjacV1whsrRfcchVVOXZAgi9ZC56HBVOh5PfI9IZBA12nAmsu9Q9Pznv1e6iZBsnbr4u2nCASnvZBGimBjdWErUXTRQetn0fdV0HLZB68tS0idelR35ybiWnehK5oec9dM9LxjRvFwTpuHSUkeA9nBAyFZBrGf4FcZAXuhT2uj5vjbvYkzupyi4mBFlBGfBEIjpeb'

However, when I tcpdump my local interface to see what is going to graph.facebook.com, I see that everytime I execute the above, a new TCP connection is created:

19:06:34.409962 IP (tos 0x0, ttl 64, id 51970, offset 0, flags [DF], proto TCP (6), length 60)
    192.168.1.80.42560 > 31.13.64.1.https: Flags [S], cksum 0xc6fe (correct), seq 1868596651, win 29200, options [mss 1460,sackOK,TS val 37375657 ecr 0,nop,wscale 7], length 0
19:06:34.486631 IP (tos 0x0, ttl 86, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    31.13.64.1.https > 192.168.1.80.42560: Flags [S.], cksum 0xc226 (correct), seq 2991458091, ack 1868596652, win 13980, options [mss 1410,sackOK,TS val 3177564556 ecr 37375657,nop,wscale 8], length 0
19:06:34.486705 IP (tos 0x0, ttl 64, id 51971, offset 0, flags [DF], proto TCP (6), length 52)
    192.168.1.80.42560 > 31.13.64.1.https: Flags [.], cksum 0x262d (correct), seq 1, ack 1, win 229, options [nop,nop,TS val 37375733 ecr 3177564556], length 0
19:06:34.486852 IP (tos 0x0, ttl 64, id 51972, offset 0, flags [DF], proto TCP (6), length 569)
    192.168.1.80.42560 > 31.13.64.1.https: Flags [P.], cksum 0x2730 (correct), seq 1:518, ack 1, win 229, options [nop,nop,TS val 37375733 ecr 3177564556], length 517
19:06:34.578182 IP (tos 0x0, ttl 86, id 52940, offset 0, flags [DF], proto TCP (6), length 52)
    31.13.64.1.https > 192.168.1.80.42560: Flags [.], cksum 0x2474 (correct), seq 1, ack 518, win 59, options [nop,nop,TS val 3177564650 ecr 37375733], length 0
...

Hence, my question: what did I do wrong here ? I would like my local haproxy server to keep open the TCP connections to graph.facebook.com as long as possible to be able to reuse them across multiple clients and requests but it looks like haproxy is creating and tearing down the TCP connections as needed despite option http-keep-alive.

Any ideas ?

barlop
  • 25,198
mathieu
  • 113

1 Answers1

1

As per the HAproxy documentation, concretely in the 1.1. The HTTP transaction model section, says the following:

By default HAProxy operates in a tunnel-like mode with regards to persistent connections: for each connection it processes the first request and forwards everything else (including additional requests) to selected server. Once established, the connection is persisted both on the client and server sides. Use "option http-server-close" to preserve client persistent connections while handling every incoming request individually, dispatching them one after another to servers, in HTTP close mode. Use "option httpclose" to switch both sides to HTTP close mode. "option forceclose" and "option http-pretend-keepalive" help working around servers misbehaving in HTTP close mode.

You've defined the http-keep-alive directive and have used none of the above described parameters, thus, you must be operating in tunnel mode (additionally, I have several HAproxy configurations very similar to yours and I can assure you it's working as the documentation says).

I think the culprit is the way you're using curl to test your configuration. You're passing it the -x flag which means you want to use the next parameter as a proxy, however, HAproxy already acts like it. So the request should be something like this:

curl 'http://127.0.0.1:4443/v2.4/me?fields=id%2Cname&access_token=CAACEdEose0cBAPvPqQ‌​IAjacV1whsrRfcchVVOXZAgi9ZC56HBVOh5PfI9IZBA12nAmsu9Q9Pznv1e6iZBsnbr4u2nCASnvZBGim‌​BjdWErUXTRQetn0fdV0HLZB68tS0idelR35ybiWnehK5oec9dM9LxjRvFwTpuHSUkeA9nBAyFZBrGf4Fc‌​ZAXuhT2uj5vjbvYkzupyi4mBFlBGfBEIjpeb

This way you're sending the request directly to HAproxy and not using HAproxy as a proxy (because it will behave this way itself).

nKn
  • 5,832