Skip to Content
Skip Breadcrumb

One of the difficult parts in the current container world is to debug the network communication. For a haproxy based setup can you use the solution described in this blog post.

First of all you will need a haproxy with lua compiled in. There are several images available on docker hub which have this feature enabled, for example my me2digital/haproxy18 .

In this image is the print_headers.lua included in the path /usr/local/etc/lua/print_headers.lua.

The default haproxy config in the Image will not load the lua file, therefore you will setup a custom haproxy config.

You can start with this one.

global

  log "${SYSLOG_ADDRESS}" local1 "${LOGLEVEL}"

  stats socket /tmp/sock1 mode 666 level admin
  stats timeout 1h
  
  tune.ssl.default-dh-param 2048
  ssl-server-verify none
  
  # Default ciphers to use on SSL-enabled listening sockets.
  # For more information, see ciphers(1SSL). This list is from:
  #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
  # An alternative list with additional directives can be obtained from
  #  https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
  ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
  ssl-default-bind-options no-sslv3
  tune.ssl.default-dh-param 2048
  
  lua-load /usr/local/etc/lua/print_headers.lua
  
defaults

  log     global
  mode    http
  option  httplog
  option forwardfor
  option  dontlognull

  timeout connect 5s
  timeout client 30s
  timeout server 30s
  # Long timeout for WebSocket connections.
  timeout tunnel 1h
  default-server resolve-prefer ipv4 inter 5s

resolvers mydns
  nameserver dns1 "${DNS_SRV001}":53
  nameserver dns2 "${DNS_SRV002}":53
  resolve_retries       3
  timeout retry         1s
  hold valid           10s

listen stats
    bind :"${STATS_PORT}"
    mode http
    # Health check monitoring uri.
    monitor-uri /healthz

    # Add your custom health check monitoring failure condition here.
    # monitor fail if <condition>
    stats enable
    stats hide-version
    stats realm Haproxy\ Statistics
    stats uri /
    stats auth "${STATS_USER}":"${STATS_PASSWORD}"

listen http_in
   bind *:"${SERVICE_TCP_PORT}"
   
  http-request lua.print-headers
  
  server "${SERVICE_NAME}" ${SERVICE_DEST_IP}:${SERVICE_DEST_PORT} check inter 5000ms
  

Docker

Now we can start a haproxy with this new config file.

docker run --rm -it --name my-running-haproxy \
    -p 13443:13443 \
    -v /home/al/haproxy.conf:/usr/local/etc/haproxy/haproxy.conf \
    -e TZ=Europe/Vienna \
    -e DEBUG=true \
    -e STATS_PORT=1999 \
    -e STATS_USER=aaa \
    -e STATS_PASSWORD=bbb \
    -e SERVICE_TCP_PORT=13443 \
    -e SERVICE_NAME=test-haproxy \
    -e SERVICE_DEST_PORT=80 \
    -e SERVICE_DEST='www.haproxy.org' \
    -e CONFIG_FILE=/usr/local/etc/haproxy/haproxy.conf \
    me2digital/haproxy18

output

A example output looks like this.

+ echo 'Current ENV Values'
Current ENV Values
+ echo ===================
===================
+ echo 'SERVICE_NAME        :test-haproxy'
SERVICE_NAME        :test-haproxy
+ echo 'SERVICE_DEST        :www.haproxy.org'
SERVICE_DEST        :www.haproxy.org
+ echo 'SERVICE_DEST_PORT   :80'
SERVICE_DEST_PORT   :80
+ echo 'TZ                  :Europe/Vienna'
TZ                  :Europe/Vienna
+ echo 'SYSLOG_ADDRESS      :/tmp/haproxy_syslog'
SYSLOG_ADDRESS      :/tmp/haproxy_syslog
+ echo 'CONFIG_FILE         :/usr/local/etc/haproxy/haproxy.conf'
CONFIG_FILE         :/usr/local/etc/haproxy/haproxy.conf
+ echo 'given DNS_SRV001    :'
given DNS_SRV001    :
+ echo 'given DNS_SRV002    :'
given DNS_SRV002    :
+ echo 'HAProxy Version:'
HAProxy Version:
+ /usr/local/sbin/haproxy -vv
HA-Proxy version 1.8.3-205f675 2017/12/30
Copyright 2000-2017 Willy Tarreau <willy@haproxy.org>

Build options :
  TARGET  = linux2628
  CPU     = generic
  CC      = gcc
  CFLAGS  = -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement -fwrapv -Wno-unused-label
  OPTIONS = USE_LINUX_SPLICE=1 USE_GETADDRINFO=1 USE_ZLIB=1 USE_REGPARM=1 USE_OPENSSL=1 USE_LUA=1 USE_PCRE=1 USE_PCRE_JIT=1 USE_TFO=1

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

Built with OpenSSL version : OpenSSL 1.0.2k-fips  26 Jan 2017
Running on OpenSSL version : OpenSSL 1.0.2k-fips  26 Jan 2017
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : SSLv3 TLSv1.0 TLSv1.1 TLSv1.2
Built with Lua version : Lua 5.3.4
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Encrypted password support via crypt(3): yes
Built with multi-threading support.
Built with PCRE version : 8.32 2012-11-30
Running on PCRE version : 8.32 2012-11-30
PCRE library supports JIT : yes
Built with zlib version : 1.2.7
Running on zlib version : 1.2.7
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with network namespace support.

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.

Available filters :
        [SPOE] spoe
        [COMP] compression
        [TRACE] trace

+ [[ -z www.haproxy.org ]]
+ [[ -z test-haproxy ]]
+ [[ -z 80 ]]
+ [[ -z /tmp/haproxy_syslog ]]
+ [[ -z '' ]]
+ dns_counter=1
++ awk '{print $2}'
++ egrep '^nameserver' /etc/resolv.conf
+ for i in '$( egrep ^nameserver /etc/resolv.conf|awk '\''{print $2}'\'' )'
+ export DNS_SRV001=8.8.8.8
+ DNS_SRV001=8.8.8.8
+ let dns_counter++
+ for i in '$( egrep ^nameserver /etc/resolv.conf|awk '\''{print $2}'\'' )'
+ export DNS_SRV002=8.8.4.4
+ DNS_SRV002=8.8.4.4
+ let dns_counter++
+ [[ -z 8.8.8.8 ]]
+ [[ -z 8.8.4.4 ]]
+ [[ -n true ]]
+ echo ===================
===================
+ echo 'compute DNS_SRV001  :8.8.8.8'
compute DNS_SRV001  :8.8.8.8
+ echo 'compute DNS_SRV002  :8.8.4.4'
compute DNS_SRV002  :8.8.4.4
+ [[ -z /usr/local/etc/haproxy/haproxy.conf ]]
+ echo 'using CONFIG_FILE   :/usr/local/etc/haproxy/haproxy.conf'
using CONFIG_FILE   :/usr/local/etc/haproxy/haproxy.conf
+ echo 'starting socklog'
starting socklog
+ echo 'wait for socklog to come up'
wait for socklog to come up
+ sleep 5
+ /usr/local/bin/socklog unix /tmp/haproxy_syslog
listening on /tmp/haproxy_syslog, starting.
+ [[ -n true ]]
+ exec /usr/local/sbin/haproxy -f /usr/local/etc/haproxy/haproxy.conf -d
Note: setting global.maxconn to 2000.
Available polling systems :
      epoll : pref=300,  test result OK
       poll : pref=200,  test result OK
     select : pref=150,  test result FAILED
Total: 3 (2 usable), will use epoll.

Available filters :
        [SPOE] spoe
        [COMP] compression
        [TRACE] trace
Using epoll() as the polling mechanism.
local1.notice: Jan 11 13:32:14 haproxy[1]: Proxy stats started.
local1.notice: Jan 11 13:32:14 haproxy[1]: Proxy http_in started.
00000000:http_in.accept(0007)=000a from [MY_CLIENT:57360] ALPN=<none>
00000000:http_in.clireq[000a:ffffffff]: GET / HTTP/1.1
00000000:http_in.clihdr[000a:ffffffff]: Host: MY_HOST
00000000:http_in.clihdr[000a:ffffffff]: User-Agent: curl/7.47.0
00000000:http_in.clihdr[000a:ffffffff]: Accept: */*
00000000:http_in.clihdr[000a:ffffffff]: Accept-Encoding: deflate, gzip
[info] 010/133222 (1) : host: MY_HOST
[info] 010/133222 (1) : accept-encoding: deflate, gzip
[info] 010/133222 (1) : accept: */*
[info] 010/133222 (1) : user-agent: curl/7.47.0
00000001:http_in.accept(0007)=000c from [172.17.0.2:33822] ALPN=<none>
00000001:http_in.clireq[000c:ffffffff]: GET / HTTP/1.1
00000001:http_in.clihdr[000c:ffffffff]: Host: MY_HOST
00000001:http_in.clihdr[000c:ffffffff]: User-Agent: curl/7.47.0
00000001:http_in.clihdr[000c:ffffffff]: Accept: */*
00000001:http_in.clihdr[000c:ffffffff]: Accept-Encoding: deflate, gzip
00000001:http_in.clihdr[000c:ffffffff]: X-Forwarded-For: MY_CLIENT
[info] 010/133222 (1) : user-agent: curl/7.47.0
[info] 010/133222 (1) : host: MY_HOST
[info] 010/133222 (1) : accept-encoding: deflate, gzip
[info] 010/133222 (1) : x-forwarded-for: MY_CLIENT
[info] 010/133222 (1) : accept: */*

You can contact me for any further questions and orders