nftlb stands for nftables load balancer, the next generation linux firewall that will replace iptables is adapted to behave as a complete load balancer and traffic distributor.
nftlb is provided with a JSON API, so you can use your preferred health checker to enable/disable backends or virtual services and automate processed with it.
More info: What is nftlb?
In this repository is included:
- src/: main source code files
- include/: include files
- tests/: automated testbed suite with example configuration files and the script exec_tests.sh to run all of them.
nftlb uses a quite new technology that requires:
nf-next: Latest kernel with the new netfilter developments
nftables: Latest nftables developments, and its dependencies (libgmp, libmnl and libnftnl)
libev: Events library for the web service
libjansson: JSON parser for the API
To build nftlb, just execute:
root# autoreconf -fi
root# ./configure
root# make
Finally, install it:
root# make install
Check out the command help:
# ./nftlb -h
Here is the list of options:
[ -h | --help ]: Show the command help.
[ -l <LEVEL> | --log <LEVEL> ]: The logs will be shown in the syslog file and with this option you can change the loglevel from 0 to 7 (5 by default).
[ -c <FILE> | --config <FILE> ]: Initial configuration file, this argument is optional.
[ -k <KEY> | --key <KEY> ]: The authentication key for the web service can be set by command line, or automatically generated. If it's automatically generated, it'll be shown by command line.
[ -e | --exit ]: This option executes the configuration file into nftables rules and then exit, so the web server won't be available.
[ -d | --daemon ]: Run nftlb as a daemon in background.
[ -6 | --ipv6 ]: Enable IPv6 support for the web service listening port.
[ -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).
[ -S | --serial ]: Serialize nft commands.
Note 1: In order to use sNAT or dNAT modes, ensure you have activated the ip forwarding option in your system Note 2: Before executing nftlb, ensure you have empty nft rules by executing "nft flush ruleset"
The configuration files have the following format:
{
"farms" : [
{ <object farm 1> },
{ <object farm 2> },
{ ... }
],
"policies" : [
{ <object policy 1> },
{ <object policy 2> },
{ ... }
]
}
Where every farm object has the following attributes:
{
"name" : "<string>", *Name of the service (required)*
"family": "<ipv4 | ipv6 | dual>", *Family of the virtual service (ipv4 by default)*
"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*
"source-addr": "<ip address>", *Source IP address instead of masquerading*
"mode": "<snat | dnat | dsr | stlsdnat | local>", *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)*
"sched-param": "<srcip | dstip | srcport | dstport | srcmac | dstmac | none>", *Hash input parameters (none by default)*
"persistence": "<srcip | dstip | srcport | dstport | srcmac | dstmac | none>", *Configured stickiness between client and backend (none by default)*
"persist-ttl": "<number>", *Stickiness timeout in seconds (60 by default)*
"helper": "<none | amanda | ftp | h323 | irc | netbios-ns | pptp | sane | sip | snmp | tftp>", *L7 helper to be used (none by default)*
"log": "<none | input | forward | output>", *Enable logging (none by default)*
"log-prefix": "<string|KNAME|TYPE|FNAME>", *Farm log prefix (default "TYPE-FNAME")*
"mark": "<hexadecimal mark>", *Set mark mask for the farm (none by default)*
"priority": "<number>", *Priority availability for backends > 0 (1 by default)*
"new-rtlimit": "<number>", *Number of new connections per second per service (disabled by default)*
"new-rtlimit-burst": "<number>", *Number of burst packets (disabled by default)*
"new-rtlimit-log-prefix": "<string|KNAME|TYPE|FNAME>", *Farm new rtlimit log prefix (default "KNAME-TYPE-FNAME")*
"rst-rtlimit": "<number>", *Number of tcp resets per second allowed (disabled by default)*
"rst-rtlimit-burst": "<number>", *Number of burst RST packets (disabled by default)*
"rst-rtlimit-log-prefix": "<string|KNAME|TYPE|FNAME>", *Farm reset rtlimit log prefix (default "KNAME-TYPE-FNAME")*
"est-connlimit": "<number>", *Number of established connections allowed (disabled by default)*
"est-connlimit-log-prefix": "<string|KNAME|TYPE|FNAME>", *Farm established connlimit log prefix (default "KNAME-TYPE-FNAME")*
"tcp-strict": "<on | off>", *Option to avoid bogus TCP attacks (disabled by default)*
"tcp-strict-log-prefix": "<string|KNAME|TYPE|FNAME>", *Farm TCP strict log prefix (default "KNAME-TYPE-FNAME")*
"flow-offload": "<on | off>", *Option to enable flow offload (disabled by default)*
"queue": "<number>", *Number of the queue to send the packets to userspace (disabled 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>},
{...}
],
"sessions" : [ *List of static sessions. It requires persistence enabled.*
{
{<object session 1>},
{<object session 2>},
{...}
],
"policies" : [ *List of policies*
{
"name" : "<policy name>",
},
{...}
]
}
Where every backend object has the following attributes:
{
"name" : "<string>", *Name of the backend (required)*
"ip-addr": "<ip address>", *IP address for the backend (required, except for DSR)*
"port": "<number>", *Backend port to redirect the connections*
"source-addr": "<ip address>", *Source IP address for a certain backend instead of masquerading or virtual service source address*
"weight": "<number>", *Weight of the backend (1 by default)*
"priority": "<number>", *Priority availability for the backend > 0 (1 by default)*
"mark": "<hexadecimal mark>", *Set mark mask for the backend (none by default)*
"est-connlimit": "<number>", *Number of established connections allowed per backend (disabled by default)*
"est-connlimit-log-prefix": "<string|KNAME|TYPE|FNAME|BNAME>", *Backend established connections log prefix (default "KNAME-FNAME-BNAME")*
"state": "<up | down | off>", *Set the status of the backend (up by default)*
}
Where every session object has the following attributes:
{
"client" : "<backend>", *Client with the same format than persistence configuration*
"backend": "<ip address>", *Backend ID to set a stickyness between client and backend*
"expiration": "<time>" *Dynamic sessions timeout. Static sessions doesn't include this attribute*
}
Where every policy object has the following attributes:
{
"name" : "<string>", *Name of the policy (required)*
"type": "<blacklist | whitelist>", *Policy type*
"log-prefix": "<string|KNAME|TYPE|FNAME|PNAME>", *Policy established connections log prefix (default "KNAME-TYPE-PNAME-FNAME")*
"elements" : [ *List of IPs or networks*
{
"data" : "<ip or network>"
},
{...}
]
}
You can find some examples in the tests/ folder.
Once launched nftlb you can manage it through the API.
Virtual service listing.
curl -H "Key: <MYKEY>" http://<NFTLB IP>:5555/farms
Setup a new virtual service.
curl -H "Key: <MYKEY>" -X POST http://<NFTLB IP>:5555/farms -d "@tests/008_snat_ipv4_all_rr.json"
Add a new backend into a virtual service.
curl -H "Key: <MYKEY>" -X POST http://<NFTLB IP>:5555/farms -d '{"farms" : [ { "name" : "myfarm", "backends" : [ { "name" : "mynewbck", "ip-addr" : "192.168.0.150", "state" : "up" } ] } ] }'
Delete a virtual service.
curl -H "Key: <MYKEY>" -X DELETE http://<NFTLB IP>:5555/farms/lb01
Delete a backend of a virtual service.
curl -H "Key: <MYKEY>" -X DELETE http://<NFTLB IP>:5555/farms/lb01/backends/bck1
Get the static and dynamic sessions.
curl -H "Key: <MYKEY>" -X GET http://<NFTLB IP>:5555/farms/lb01/sessions
Please refer to the netfilter users mailing list