HAProxy Fodder

What is FoDDeR
Fodder is a slightly opinionated fiddler for FoD-go - Firewall on Demand (Go).
The application has dependencies, some of which are strict requirements while others are optional or bypassable.
IPv6 is enforced if IPv6 is not in use, it's possible to add a Link-local address which will never be hit by external connections.
It is conceived to work with a two nodes cluster If you don't have a cluster, you can use the IP of the HAProxy server as the VIP.
It integrates a PoW at this stage PoW (Proof of Work) is not part of this project. To exclude the PoW it's possible to set a very high value for global_medium_threshold
it works only with HAProxy it relies on stick-tables which are available with HAProxy
it requires FoD-go it does not interact with BGP Flowspec, but with FoD-go.
How does FoDDer work
Fodder consists of two applications: a Web application written in Go, a connection monitoring script written in Python.
The Connection monitoring operates as detection layer: haproxy_conn_monitor.py
HAProxy fodder is the Web UI, operating as enforcement layer: haproxy-fodder
Configuration files
The informations are are read and stored in the following order:
stick-table. The stick tablefod_varsis used as a KV store. With a two nodes cluster, there should be a peer section inhaproxy.cfgto enable synchronization of the stick-table./etc/fodder/fod-vars.yaml. The filefod-vars.yamlis used by the Web App to store the information from the stick-table, and as a backup source of truth, when the stick-table is missing (i.e.: if both haproxy go down the data will be missing)./etc/fodder/fod-vars-defaults.yaml. This file is used to bootstrap the application and provides the initial values.
Stick tables
The following stick-tables must be created on HAProxy
backend ip_rate
stick-table type ipv6 size 400k expire 10m store http_req_rate(10s) peers test_geant_haproxy
backend pow_state
stick-table type ipv6 size 400k expire 720m store gpc0,http_req_rate(10s) peers test_geant_haproxy
backend fod_vars
stick-table type string size 1k store gpc0 peers test_geant_haproxy
The tables ip_rate and pow_state must be tracked in the configuration file:
http-request track-sc0 src table pow_state
http-request track-sc1 src table ip_rate
The table fod_vars is used only as a KV store and should not be tracked.
fod_vars
FoD vars are scattered as following
fod_vars stick-table
the stick table fod_vars contains the following information, with different values for the key gpc0:
# echo "show table fod_vars" | socat stdio /run/haproxy.sock
# table: fod_vars, type: string, size:1024, used:7
0x7e3b7a85c988: key=sleep_time use=0 exp=0 shard=0 gpc0=30
0x7e3b7a85c7c8: key=ip_rate_medium use=0 exp=0 shard=0 gpc0=5000
0x7e3b7a85ca68: key=fod_ip_threshold use=0 exp=0 shard=0 gpc0=150
0x7e3b7a85c8a8: key=ip_rate_high use=0 exp=0 shard=0 gpc0=10000
0x7e3b7a85cc28: key=fod_rule_expiration use=0 exp=0 shard=0 gpc0=10
0x7e3b7a85c6e8: key=ip_rate_low use=0 exp=0 shard=0 gpc0=1000
0x7e3b7a85cb48: key=fod_subnet_threshold use=0 exp=0 shard=0 gpc0=1000
haproxy-conn-monitor.yaml
The file haproxy-conn-monitor.yaml contains the information to connect to Fod, as well as actions to trigger.
The first key is country-ip-blocks.tar.gz. This file is pulled daily from this repository: country-ip-blocks (at a later stage I'll share a script to pull this artifact).
---
country_tarball: "/etc/fodder/country-ip-blocks.tar.gz"
haproxy_socket: "/run/haproxy.sock"
fod_api_endpoint: https://fod-go.example.org/api/v1
fod_token: "<fod-secret-token>"
rate_table: ip_rate
pow_table: pow_state
fod_network_id: "<fod-network-id>"
rule_description: "FoD rule created by haproxy-conn-monitor"
fod_dict_v4:
protocols:
- TCP
action: discard
status: active
destination: 192.168.1.1
destination_mask: 32
destination_ports:
- begin: 443
end: 443
- begin: 80
end: 80
fod_dict_v6:
protocols:
- TCP
action: discard
status: active
destination: 2001:db8::1
destination_mask: 128
destination_ports:
- begin: 443
end: 443
- begin: 80
end: 80
fod-vars.yaml
this file is empty and it's handled by haproxy-fodder
fod-vars-defaults.yaml
this file contains the information to bootstrap the application.
---
ip_rate_low: 1000
ip_rate_medium: 5000
ip_rate_high: 10000
fod_ip_threshold: 150
fod_subnet_threshold: 1000
fod_rule_expiration: 10
sleep_time: 30