Skip to content

Instantly share code, notes, and snippets.

@haproxytechblog
Last active May 14, 2021 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save haproxytechblog/52cd538ec5410ccf19ffea8486addbae to your computer and use it in GitHub Desktop.
Save haproxytechblog/52cd538ec5410ccf19ffea8486addbae to your computer and use it in GitHub Desktop.
Announcing HAProxy 2.4
tcp-request content reject unless { req.payload(0,0),mqtt_is_valid }
frontend fe_mqtt
mode tcp
bind :1993
# Reject connections that have an invalid MQTT packet
tcp-request content reject unless { req.payload(0,0),mqtt_is_valid }
default_backend be_mqtt
backend be_mqtt
mode tcp
# Create a stick table for session persistence
stick-table type string len 32 size 100k expire 30m
# Use ClientID / client_identifier as persistence key
stick on req.payload(0,0),mqtt_field_value(connect,client_identifier)
server mosquitto1 10.1.0.6:1883
server mosquitto2 10.1.0.7:1883
backend be_mqtt
mode tcp
# Deny a request unless it matches
# the client identifier "mosquitto_1234"
tcp-request content reject unless { req.payload(0,0),mqtt_field_value(connect,client_identifier) mosquitto_1234 }
server mosquitto1 10.1.0.6:1883
server mosquitto2 10.1.0.7:1883
resolvers mydns
# recommend value for UDP is 4096
# tcp can go up to 65535
accepted_payload_size 65535
nameserver dns1 tcp@10.0.0.3:53
backend serviceA
# Create storage for tracking client info
stick-table type string size 1 expire 30s store http_req_rate(10s),http_fail_rate(10s),gpc1
# Is the circuit broken?
acl circuit_open be_name,table_gpc1 gt 0
# Reject request if circuit is broken
http-request return status 503 content-type "application/json" string "{ \"message\": \"Circuit Breaker tripped\" }" if circuit_open
# Begin tracking requests
http-request track-sc0 be_name
# Store the HTTP request rate and error rate in variables
http-response set-var(res.req_rate) sc_http_req_rate(0)
http-response set-var(res.err_rate) sc_http_fail_rate(0)
# Check if error rate is greater than 50% using some math
http-response sc-inc-gpc1(0) if { int(100),mul(res.err_rate),div(res.req_rate) gt 50 }
server s1 192.168.0.10:80 check
# Get loaded certificates
$ echo "show ssl cert" |socat /var/run/haproxy/api.sock -
# filename
/etc/haproxy/cert/haproxy-client.pem
# Update HAProxy's client certificate
$ echo -e -n "set ssl cert /etc/haproxy/cert/haproxy-client.pem <<\n$(cat /etc/haproxy/cert/haproxy-client.pem)\n\n" |socat /var/run/haproxy/api.sock -
Transaction created for certificate /etc/haproxy/cert/haproxy-client.pem!
# Commit the SSL transaction
$ echo "commit ssl cert /etc/haproxy/cert/haproxy-client.pem" |socat /var/run/haproxy/api.sock -
Committing /etc/haproxy/cert/haproxy-client.pem.
Success!
$ PKG_CONFIG_PATH=/opt/lib/pkgconfig \
make -j $(nproc) \
TARGET=linux-glibc \
USE_LUA=1 \
USE_OPENSSL=1 \
USE_PCRE=1 \
USE_SYSTEMD=1 \
USE_OT=1
$ make TARGET=linux-glibc \
USE_LUA=1 \
USE_OPENSSL=1 \
USE_PCRE=1 \
USE_SYSTEMD=1 \
EXTRA_OBJS="contrib/prometheus-exporter/service-prometheus.o"
$ make TARGET=linux-glibc \
USE_LUA=1 \
USE_OPENSSL=1 \
USE_PCRE=1 \
USE_SYSTEMD=1 \
USE_PROMEX=1
frontend stats
bind :8404
stats enable
stats uri /
stats refresh 10s
stats show-modules
no log
.if version_atleast(2.4)
# include configuration lines
.endif
frontend fe_main
.if version_atleast(2.4)
.if feature(OT)
# enable OpenTracing
filter opentracing config tracing.conf
.endif
.endif
.if version_atleast(2.4)
.diag "Bob Smith, 2021-05-07: replace 'redirect' with 'return' after switch to 2.4"
# configuration snippet
.endif
$ printf "listen f\nbind :8000 tcut\n" | haproxy -c -f /dev/stdin
[ALERT] 070/101358 (25146) : parsing [/dev/stdin:2] : 'bind :8000' unknown keyword 'tcut'; did you mean 'tcp-ut' maybe ?
[ALERT] 070/101358 (25146) : Error(s) found in configuration file : /dev/stdin
[ALERT] 070/101358 (25146) : Fatal errors found in configuration.
defaults
<tcp settings here>
frontend fe_tcp
...
backend be_tcp
...
-------------------
defaults
<http settings here>
frontend fe_http
...
backend be_http
...
defaults tcp-defaults
...
defaults http-defaults
...
frontend fe_tcp from tcp-defaults
...
frontend fe_http from http-defaults
...
backed be_tcp from tcp-defaults
...
backend be_http from http-defaults
...
defaults tcp-defaults
mode tcp
timeout connect 5s
timeout client 5s
timeout server 5s
default http-defaults from tcp-defaults
mode http
frontend fe_main
timeout server 5s
http-request set-timeout server 30s if { path -m beg /slow/ }
# host.map
www.example.com 3000
api.example.com 1000
websockets.example.com 60000
frontend fe_main
http-request set-timeout server req.hdr(host),map_int(host.map)
frontend fe_main
mode tcp
tcp-request inspect-delay 5s
tcp-request content switch-mode http if HTTP
...
http-request del-header X-Forwarded -m beg
http-request wait-for-body time 1s at-least 1k if METH_POST
http-response wait-for-body time 1s at-least 10k
http-request normalize-uri <normalizer> [ { if | unless } <condition> ]
$ echo "help add" |socat /var/run/haproxy/api.sock -
The following commands are valid at this level:
add acl [@<ver>] <acl> <pattern> : add an acl entry
add map [@<ver>] <map> <key> <val> : add a map entry (payload supported instead of key/val)
add server <bk>/<srv> : create a new server (EXPERIMENTAL)
add ssl crt-list <list> <cert> [opts]* : add to crt-list file <list> a line <cert> or a payload
help [<command>] : list matching or all commands
prompt : toggle interactive mode with prompt
quit : disconnect
$ echo "show state" |socat /var/run/haproxy/api.sock -
Unknown command, but maybe one of the following ones is a better match:
show stat [desc|json|no-maint|typed|up]*: report counters for each proxy and server
show servers state [<backend>] : dump volatile server information (all or for a single backend)
help : full commands list
prompt : toggle interactive mode with prompt
quit : disconnect
$ echo "set server be_main/srv1 ssl on" | socat /var/run/haproxy/api.sock -
$ echo "prepare acl /etc/haproxy/acl/denylist.acl" | socat /var/run/haproxy/api.sock -
New version created: 1
$ echo "add acl @1 /etc/haproxy/acl/denylist.acl 4.4.4.4" | socat /var/run/haproxy/api.sock -
$ echo "add acl @1 /etc/haproxy/acl/denylist.acl 5.5.5.5" | socat /var/run/haproxy/api.sock -
$ echo "add acl @1 /etc/haproxy/acl/denylist.acl 6.6.6.6" | socat /var/run/haproxy/api.sock -
$ echo "commit acl @1 /etc/haproxy/acl/denylist.acl" | socat /var/run/haproxy/api.sock -
$ echo "experimental-mode on; add server be_app/app4 192.168.1.22:80" | socat /var/run/haproxy/api.sock -
New server registered.
$ echo "experimental-mode on; del server be_app/app4" | socat /var/run/haproxy/api.sock -
Server deleted.
global
set-var proc.myapp_version str(blue)
frontend fe_main
mode http
bind :::80
bind :::443 ssl crt /etc/haproxy/certs/cert.pem alpn h2,http/1.1
use_backend be_myapp_green if { var(proc.myapp_version) -m str green }
use_backend be_myapp_blue if { var(proc.myapp_version) -m str blue }
$ echo "experimental-mode on; get var proc.myapp_version" |socat /var/run/haproxy/api.sock -
proc.myapp_version: type=str value=<blue>
$ echo "experimental-mode on; set var proc.myapp_version str(green)" | socat /var/run/haproxy/api.sock -
$ echo "experimental-mode on; get var proc.myapp_version" | socat /var/run/haproxy/api.sock -
proc.myapp_version: type=str value=<green>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment