home > linux > sks-loadbalanced-with-haproxy-v2

SKS loadbalanced with haproxy v2

10 | 24 Sep 2016

Auto Failover for Master Node

The new config allows for one node to always act as master. Should the master node fail the failover node will kick in. During normal operations the failover node's recon traffic is routed to the master node and whilst the master is down recon is routed to external peers.

Haproxy tcp routing over NAT

Previously I was also NATing traffic via the lb node to external peers, i've now consolidated this requirement into haproxy.

During Normal Running

Outbound recon traffic from the failover is routed to master1

During Failover

Outbound traffic from the failover node is routed to the external peers

New HaProxy Config

global
    log 127.0.0.1    local2 debug
    maxconn 4096
    chroot /usr/share/haproxy
    uid 99
    gid 99
    daemon
    tune.ssl.default-dh-param 4096
    ssl-default-bind-options no-sslv3 no-tls-tickets
    stats socket /var/run/haproxy.stat mode 600 level operator
    stats timeout 5s
    ssl-default-bind-ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:ECDH-RSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-DES-CBC3-SHA"
    tune.ssl.maxrecord 2859
    tune.ssl.cachesize 100000
    tune.ssl.lifetime 600

defaults
    mode    http
    option    dontlognull
    retries    3
    maxconn    2000
    timeout connect        5000
    timeout client        50000
    timeout server        50000
    option abortonclose
    retries 2

##################################################
# frontends
##################################################

frontend http-sks
    mode http
    #log    global
    option forwardfor # set the client's IP in X-Forwarded-For.
    option    httplog
    option httpclose
    rspadd Via: lb1.mj2.uk
    rsprep    ^Server.* Server: Unix
    bind 178.32.66.144:80
    bind 178.32.66.144:11371
    bind 2001:41d0:2:a8b4::10:80
    bind 2001:41d0:2:a8b4::10:11371
    bind 10.0.0.19:11371
    bind 10.0.0.21:11371
    bind 10.0.0.22:11371
    bind 10.0.0.23:11371
    bind 10.0.0.24:11371
    bind 10.0.0.25:11371
    bind 10.0.0.36:11371

    # Security
    option http-buffer-request
    timeout http-request 60s

    # SKS
    acl apac_url path_beg /.well
    acl mast_url path_beg /pks/add /pks/hashquery
    acl mast_param urlp(op) stats
    acl sks_n2 urlp(go) n2
    acl sks_n3 urlp(go) n3
    acl sks_n4 urlp(go) n4
    acl sks_n5 urlp(go) n5
    acl sks_m1 urlp(go) m1
    acl sks_m2 urlp(go) m2
    use_backend http-sks-n3 if mast_param sks_n3
    use_backend http-sks-n4 if mast_param sks_n4
    use_backend http-sks-n5 if mast_param sks_n5
    use_backend http-sks-m1 if mast_param sks_m1
    use_backend http-sks-m2 if mast_param sks_m2

    #peer2
    acl host_p2 hdr_end(host) -i sks.srv.dumain.com
    acl ip_p2 dst 10.0.0.24
    use_backend http-sks-recon-peer2 if host_p2 or ip_p2

    #peer3
    acl host_p3 hdr_end(host) -i keyserver.opensuse.org
    acl ip_p3 dst 10.0.0.21
    use_backend http-sks-recon-peer3 if host_p3 or ip_p3

    #peer4
    acl host_p4 hdr_end(host) -i whippet.andrewg.com
    acl ip_p4 dst 10.0.0.22
    use_backend http-sks-recon-peer4 if host_p4 or ip_p4

    #peer5
    acl host_p5 hdr_end(host) -i skspub.ward.ie
    acl ip_p5 dst 10.0.0.23
    use_backend http-sks-recon-peer5 if host_p5 or ip_p5

    #peer6
    acl host_p6 hdr_end(host) -i keys.bonus-communis.eu
    acl ip_p6 dst 10.0.0.25
    use_backend http-sks-recon-peer6 if host_p6 or ip_p6

    #peer7
    acl host_p7 hdr_end(host) -i keyserver.garden-lan.com
    acl ip_p7 dst 10.0.0.36
    use_backend http-sks-recon-peer7 if host_p7 or ip_p7

    #peer8
    #acl host_p8 hdr_end(host) -i www.example.com
    #use_backend http-sks-recon-peer8 if host_p8 or ip_p8

    #peer9
    #acl host_p9 hdr_end(host) -i www.example.com
    #use_backend http-sks-recon-peer9 if host_p9 or ip_p9

    # No peer mast req
    use_backend http-sks-master-apache if apac_url
    use_backend http-sks-master if mast_url
    use_backend http-sks-master if mast_param

    # Default
    default_backend http-sks

frontend tcp-sks-recon
    mode tcp
    #log    global
    option tcplog
    bind 178.32.66.144:11370
    #bind 2001:41d0:2:a8b4::10:11370
    default_backend tcp-sks-recon

frontend tcp-sks-recon-outbound
    mode tcp
    #log    global
    option tcplog
    bind 10.0.0.19:11370
    bind 10.0.0.21:11370
    bind 10.0.0.22:11370
    bind 10.0.0.23:11370
    bind 10.0.0.24:11370
    bind 10.0.0.25:11370
    bind 10.0.0.36:11370
    acl p2 dst 10.0.0.24
    acl p3 dst 10.0.0.21
    acl p4 dst 10.0.0.22
    acl p5 dst 10.0.0.23
    acl p6 dst 10.0.0.25
    acl p7 dst 10.0.0.36
    #acl p8 dst ?
    #acl p9 dst ?
    acl master_alive nbsrv(tcp-sks-recon) gt 0
    acl failover_src src 10.0.0.42
    use_backend tcp-sks-recon if master_alive failover_src
    use_backend tcp-sks-recon-peer2 if p2
    use_backend tcp-sks-recon-peer3 if p3
    use_backend tcp-sks-recon-peer4 if p4
    use_backend tcp-sks-recon-peer5 if p5
    use_backend tcp-sks-recon-peer6 if p6
    use_backend tcp-sks-recon-peer7 if p7
    #use_backend tcp-sks-recon-peer8 if p8
    #use_backend tcp-sks-recon-peer9 if p9
    default_backend tcp-sks-recon

frontend https-sks
    mode http
    option forwardfor # set the client's IP in X-Forwarded-For.
    option    httplog
    option httpclose
    rspadd Via: lb1.mj2.uk
    rsprep    ^Server.* Server: Unix
    bind 178.32.66.144:443 ssl crt /etc/haproxy/ssl/sks.mj2.uk.pem crt /etc/haproxy/ssl/pgp.mj2.uk.pem # strict-sni
    bind 2001:41d0:2:a8b4::10:443 ssl crt /etc/haproxy/ssl/sks.mj2.uk.pem crt /etc/haproxy/ssl/pgp.mj2.uk.pem # strict-sni

    http-request set-header X-Forwarded-Port %[dst_port]
    http-request add-header X-Forwarded-Proto https #if { ssl_fc }

    acl mast_url path_beg /pks/add /pks/hashquery
    acl mast_param urlp(op) stats
    use_backend https-sks-master if mast_url
    use_backend https-sks-master if mast_param
    use_backend https-sks if { ssl_fc_sni cert1 } # content switching based on SNI
    default_backend https-sks

    # Security
    option http-buffer-request
    timeout http-request 60s

##################################################
# Backends
##################################################

backend http-sks-master-apache
    mode http
    option httpchk GET /test.html HTTP/1.1rnHost: sks.mj2.uk
    http-check expect string OK
    option forwardfor

    server m1 10.0.0.43:11371 weight 1 maxconn 1000 check port 11371 inter 30s rise 1 fall 2
    server m2 10.0.0.42:11371 weight 1 maxconn 1000 check port 11371 inter 30s rise 1 fall 2 backup

backend http-sks-master
    mode http
    option httpchk GET /test.html HTTP/1.1rnHost: sks.mj2.uk
    http-check expect string OK
    option forwardfor

    server m1 10.0.0.43:11371 maxconn 1000 check port 11371 inter 30s rise 1 fall 2
    server m2 10.0.0.42:11371 maxconn 1000 check port 11371 inter 30s rise 1 fall 2 backup

backend http-sks-n3
    mode http
    option forwardfor
    server node3 10.0.0.39:11371 maxconn 1000

backend http-sks-n4
    mode http
    option forwardfor
    server node4 10.0.0.40:11371 maxconn 1000

backend http-sks-n5
    mode http
    option forwardfor
    server node5 10.0.0.41:11371 maxconn 1000

backend http-sks-m1
    mode http
    option forwardfor
    server node5 10.0.0.43:11371 maxconn 1000

backend http-sks-m2
    mode http
    option forwardfor
    server node5 10.0.0.42:11371 maxconn 1000

backend http-sks
    mode http
    option httpchk GET /test.html HTTP/1.1rnHost: sks.mj2.uk
    http-check expect string OK
    balance leastconn
    hash-type consistent
    option forwardfor

    # Stick Table
    stick-table type ip size 1m expire 1m

    # Sticky Session
    stick on src

    # No Cookie Version
    server node3 10.0.0.39:11371 weight 20 maxconn 1000 check port 11371 inter 20s rise 2 fall 3
    server node4 10.0.0.40:11371 weight 20 maxconn 1000 check port 11371 inter 20s rise 2 fall 3
    server node5 10.0.0.41:11371 weight 20 maxconn 1000 check port 11371 inter 20s rise 2 fall 3

backend tcp-sks-recon
    mode tcp
    option tcp-check
    tcp-check connect
    tcp-check expect string bitquantum
    balance leastconn

    server m1 10.0.0.43:11370 weight 1 maxconn 1000 check inter 60s rise 1 fall 2
    server m2 10.0.0.42:11370 weight 1 maxconn 1000 check inter 60s rise 1 fall 2 backup

backend tcp-sks-recon-peer2
    mode tcp
    #server remote1 sks.srv.dumain.com:11370 maxconn 100
    server remote1 85.119.82.209:11370 maxconn 100

backend http-sks-recon-peer2
    mode http
    #server remote1 sks.srv.dumain.com:11370 maxconn 100
    server remote1 85.119.82.209:11371 maxconn 100

backend tcp-sks-recon-peer3
    mode tcp
    server remote1 keyserver.opensuse.org:11370 maxconn 100

backend http-sks-recon-peer3
    mode http
    server remote1 keyserver.opensuse.org:11371 maxconn 100

backend tcp-sks-recon-peer4
    mode tcp
    server remote1 whippet.andrewg.com:11370 maxconn 100

backend http-sks-recon-peer4
    mode http
    server remote1 whippet.andrewg.com:11371 maxconn 100

backend tcp-sks-recon-peer5
    mode tcp
    server remote1 skspub.ward.ie:11370 maxconn 100

backend http-sks-recon-peer5
    mode http
    server remote1 skspub.ward.ie:11371 maxconn 100

backend tcp-sks-recon-peer6
    mode tcp
    server remote1 keys.bonus-communis.eu:11370 maxconn 100

backend http-sks-recon-peer6
    mode http
    server remote1 keys.bonus-communis.eu:11371 maxconn 100

backend tcp-sks-recon-peer7
    mode tcp
    server remote1 keyserver.garden-lan.com:11370 maxconn 100

backend http-sks-recon-peer7
    mode http
    server remote1 keyserver.garden-lan.com:11371 maxconn 100

#backend tcp-sks-recon-peer8
#    mode tcp
#    server remote1 www.example.com:11370 maxconn 100

#backend http-sks-recon-peer8
#    mode http
#    server remote1 www.example.com:11371 maxconn 100

#backend tcp-sks-recon-peer9
#    mode tcp
#    server remote1 www.example.com:11370 maxconn 100

#backend http-sks-recon-peer9
#    mode http
#    server remote1 www.example.com:11371 maxconn 100

backend https-sks-master
    mode http
    option httpchk GET /test.html HTTP/1.1rnHost: sks.mj2.uk
    http-check expect string OK
    option forwardfor

    # HSTS
    # http://blog.haproxy.com/2015/06/09/haproxy-and-http-strict-transport-security-hsts-header-in-http-redirects/
    #http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"

    #server node1 10.0.0.9:11371 weight 1 maxconn 1000 check port 80 inter 30s rise 1 fall 2
    server m1 10.0.0.43:11371 weight 1 maxconn 1000 check port 11371 inter 30s rise 1 fall 2
    server m2 10.0.0.42:11371 weight 1 maxconn 1000 check port 11371 inter 30s rise 1 fall 2 backup

backend https-sks
    mode http
    option httpchk GET /test.html HTTP/1.1rnHost: sks.mj2.uk
    http-check expect string OK
    balance leastconn
    #option httpclose
    option forwardfor

    # HSTS
    # http://blog.haproxy.com/2015/06/09/haproxy-and-http-strict-transport-security-hsts-header-in-http-redirects/
    #http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"

    # Stick Table
    stick-table type ip size 1m expire 1m

    # Sticky Session
    stick on src

    # No Cookie Version
    server node3 10.0.0.39:11371 weight 20 maxconn 1000 check port 11371 inter 30s rise 2 fall 3
    server node4 10.0.0.40:11371 weight 20 maxconn 1000 check port 11371 inter 30s rise 2 fall 3
    server node5 10.0.0.41:11371 weight 20 maxconn 1000 check port 11371 inter 30s rise 2 fall 3

backend capasity-limit-http
    mode http
    errorfile 503 /etc/haproxy/errors/rate-http.html

backend capasity-limit-https
    mode http
    errorfile 503 /etc/haproxy/errors/rate-https.html

listen stats
    # disabled
    bind :8888
    stats uri /
    mode http
    stats enable
    stats hide-version
    stats realm Haproxy Statistics
    stats auth ???:???

Update 27th Sep

I've swapped the health check on "tcp-sks-recon" and "tcp-sks-recon-outbound" from a http check on sks-db to a tcp check on sks-recon. This ensures recon is routed correctly ignoring the state of sks-db.

Update 1st Oct

I've updated the tcp check to check for the string "bitquantum", Changed the recon on external peers back to using individual ip as ports did not work (the recon on port would work but then all requests for missing keys would land on the same ip with the same request hostname).

Post a Comment