NFTLB(8)

πŸ’– NFTLB β€” nftables load balancer πŸ’–

okay bestie, gather round, because this is the nftlb(8) page from the System Manager's Manual and it's genuinely iconic. no cap. 🫢


✨ NAME ✨

nftlb β€” the nftables load balancer. that's it, that's the whole vibe. πŸ‘‘


🌸 SYNOPSIS 🌸

nftlb [option]

πŸ¦‹ DESCRIPTION πŸ¦‹

so like, nftlb is a nftables(8) rules manager, and what it does is create virtual services for load balancing at layer 2, layer 3 and layer 4. the way it does that is by keeping the number of rules tiny and using structures to match packets super efficiently. not me being obsessed with efficiency. πŸ’…

it also ships with an easy JSON API service so you have the flexibility to talk to nftlb programmatically and to meet automation head-on. translation: you can plug in whatever health checker you already love, and integrating it with nftlb is genuinely so easy. slay. ✨

and the philosophy? okay this part is lowkey the most main character thing about it:

  • it keeps the data path in the kernel, so you get the most performance possible πŸ”₯
  • but it keeps the control plane and the health checks in user space, so you have the flexibility to change behaviour easily, and it stays compatible with the rest of the linux stack 🌈

periodt.


πŸŽ€ USAGE πŸŽ€

these are the options you may use when running nftlb, bestie:

  • -h | --help β€” show the command help. that's it. that's the whole thing. πŸ™ˆ
  • -l <LEVEL> | --log <LEVEL> β€” verbosity of the logs, and they get sent to syslog. valid values are from 0 to 7, and the default is 5. πŸ“
  • -c <FILE> | --config <FILE> β€” initial configuration file.
  • -k <KEY> | --key <KEY> β€” the authentication key for the web service can be set with this option. if you don't specify it, it will be automatically generated and printed to stdout. cute of it tbh. πŸ”‘
  • -e | --exit β€” this option results in nftlb loading the generated ruleset into nftables(8) and then exiting. the web server won't be available. so like, it does one job and then dips. πŸ’€
  • -6 | --ipv6 β€” enable IPv6 support for the web server. 🌐
  • -H <HOST> | --host <HOST> β€” set the host for the web service (all interfaces by default).
  • -P <PORT> | --port <PORT> β€” set the TCP port for the web service (5555 by default).

🌟 API USAGE 🌟

once nftlb is launched you can manage it through the API. here's the whole menu of moves:

listing virtual services

curl -H "Key: <MYKEY>" http://<NFTLB IP>:5555/farms

setting up a new virtual service

curl -H "Key: <MYKEY>" -X POST http://<NFTLB IP>:5555/farms -d "@tests/008_snat_ipv4_all_rr.json"

deleting a virtual service

curl -H "Key: <MYKEY>" -X DELETE http://<NFTLB IP>:5555/farms/lb01

deleting a backend of a virtual service

curl -H "Key: <MYKEY>" -X DELETE http://<NFTLB IP>:5555/farms/lb01/backends/bck1

πŸ’œ CONFIGURATION πŸ’œ

configuration files have this format (JSON), and yes it's giving very structured queen:

{
     "farms" : [
          { <object farm 1> },
          { <object farm 2> },
          { ... }
     ]
}

the farm objects have the following attributes:

{
     "name" : "<string>",                    *Name of the service (required)*
     "iface"   : "<interface name>",              *Input interface (only required for DSR)*
     "oface"   : "<interface name>",              *Output interface (only required for DSR)*
     "family": "<ipv4 | ipv6 | dual>",       *Family of the virtual service (ipv4 by default)*
     "ether-addr": "<mac address>",               *Physical address of the virtual service (only required for DSR)*
     "virtual-addr": "<ip address>",              *IP address for the virtual service (required)*
     "virtual-ports": "<port list>",              *Port list separated by commas or ranges separated by a hyphen*
     "mode": "<snat | dnat | dsr>",               *Topology to be implemented (required)*
     "protocol": "<tcp | udp | sctp | all>",      *Protocol to be used by the virtual service (tcp by default)*
     "scheduler": "<weight | rr | hash | symhash>",    *Scheduler to be used (round robin by default)*
     "priority": "<number>",                 *Priority availability for backends > 0 (1 by default)*
     "state": "<up | down | off>",           *Set the status of the virtual service (up by default)*
     "backends" : [                     *List of backends*
          {<object backend 1>},
          {<object backend 2>},
          {...}
     ]
}

and the backend objects have these attributes, bestie:

{
     "name" : "<string>",                    *Name of the backend (required)*
     "ether-addr": "<mac address>",               *Physical address of the backend (only required for DSR)*
     "ip-addr": "<ip address>",              *IP address for the backend (required, except for DSR)*
     "weight": "<number>",                   *Weight of the backend (1 by default)*
     "priority": "<number>",                 *Priority availability for the backend > 0 (1 by default)*
     "state": "<up | down | off>",           *Set the status of the backend (up by default)*
}

πŸ“ CONFIG EXAMPLES πŸ“

TCP IPv4 SNAT with weights

{
    "farms" : [
        {
            "name" : "lb01",
            "family" : "ipv4",
            "virtual-addr" : "192.168.0.100",
            "virtual-ports" : "80",
            "mode" : "snat",
            "protocol" : "tcp",
            "scheduler" : "weight",
            "state" : "up",
            "backends" : [
                {
                    "name" : "bck0",
                    "ip-addr" : "192.168.0.10",
                    "weight" : "5",
                    "priority" : "1",
                    "state" : "up"
                },
                {
                    "name" : "bck1",
                    "ip-addr" : "192.168.0.11",
                    "weight" : "5",
                    "priority" : "1",
                    "state" : "up"
                }
            ]
        }
    ]
}

TCP IPv4 with DSR using symhash

{
    "farms" : [
        {
            "name" : "lb01",
            "family" : "ipv4",
            "iface" : "enp0s3",
            "oface" : "enp0s8",
            "virtual-addr" : "192.168.0.100",
            "ether-addr" : "01:01:01:01:01:01",
            "virtual-ports" : "80-88",
            "mode" : "dsr",
            "protocol" : "tcp",
            "scheduler" : "symhash",
            "state" : "up",
            "backends" : [
                {
                    "name" : "bck0",
                    "ip-addr" : "192.168.0.10",
                    "ether-addr" : "02:02:02:02:02:02",
                    "weight" : "5",
                    "priority" : "1",
                    "state" : "up"
                },
                {
                    "name" : "bck1",
                    "ip-addr" : "192.168.0.11",
                    "ether-addr" : "03:03:03:03:03:03",
                    "weight" : "5",
                    "priority" : "1",
                    "state" : "up"
                }
            ]
        }
    ]
}

🌈 SEE ALSO 🌈


πŸ‘‘ AUTHORS πŸ‘‘

nftlb was written by Laura GarcΓ­a @ Zevenet (https://www.zevenet.com). iconic behaviour, truly.

this manual page was written by Arturo Borrero Gonzalez <arturo@debian.org> for the Debian project (but may be used by others). 🫢


okay that's the whole page, bestie, you ate it. go forth and load balance. and just so you know, this manual page is dated May 9, 2018 and it comes from the NFTLB(8) System Manager's Manual β€” so if you cite it, cite it right. mwah. πŸ’…πŸ’–βœ¨

πŸ“¦ where this page comes from