{"id":13464627,"url":"https://github.com/zevenet/nftlb","last_synced_at":"2025-10-21T10:57:21.929Z","repository":{"id":37406034,"uuid":"119864287","full_name":"zevenet/nftlb","owner":"zevenet","description":"nftables load balancer by RELIANOID","archived":false,"fork":false,"pushed_at":"2025-01-02T15:00:37.000Z","size":2588,"stargazers_count":231,"open_issues_count":4,"forks_count":28,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-10-21T10:56:55.188Z","etag":null,"topics":["backends","balancer","dsr","ipv4","ipv6","kernel","nat","nftables","virtual-services"],"latest_commit_sha":null,"homepage":"https://www.relianoid.com","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zevenet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-02-01T16:45:57.000Z","updated_at":"2025-08-21T22:43:02.000Z","dependencies_parsed_at":"2025-03-25T11:42:30.682Z","dependency_job_id":null,"html_url":"https://github.com/zevenet/nftlb","commit_stats":{"total_commits":500,"total_committers":4,"mean_commits":125.0,"dds":"0.040000000000000036","last_synced_commit":"795e14af30009d78af5bbc3e5bcfb26d23a887da"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/zevenet/nftlb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zevenet%2Fnftlb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zevenet%2Fnftlb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zevenet%2Fnftlb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zevenet%2Fnftlb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zevenet","download_url":"https://codeload.github.com/zevenet/nftlb/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zevenet%2Fnftlb/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280248571,"owners_count":26297925,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-21T02:00:06.614Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backends","balancer","dsr","ipv4","ipv6","kernel","nat","nftables","virtual-services"],"created_at":"2024-07-31T14:00:47.640Z","updated_at":"2025-10-21T10:57:21.922Z","avatar_url":"https://github.com/zevenet.png","language":"C","funding_links":[],"categories":["C","kernel"],"sub_categories":[],"readme":"# [nftlb](https://www.relianoid.com/knowledge-base/nftlb)\n**This repository has moved to [https://github.com/relianoid/nftlb](https://github.com/relianoid/nftlb)**\n\n**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.\n\nnftlb is provided with a JSON API, so you can use your preferred health checker to enable/disable backends or virtual services and automate processes with it.\n\nMore info: [What is nftlb?](https://www.relianoid.com/knowledge-base/nftlb/what-is-nftlb/)\n\n## Repository Contents\nIn this repository is included:\n- **src/**: main source code files.\n- **include/**: include files.\n- **tests/**: automated testbed suite with example configuration files and the script *exec_tests.sh* to run all of them.\n- **tests/api**: automated testbed suite for API interactionand the script *api_tests.sh* to run all of them.\n\n## Requirements\nnftlb depends on:\n\n- **linux-kernel**: Kernel version 4.19 or higher with nftables modules enabled (iptables, ebtables, etc not required).\n- **nftables**: nftables package with **libnftables** included and its dependencies (**libgmp**, **libmnl** and **libnftnl**).\n- **libev**: Events library for the web service.\n- **libjansson**: JSON parser for the API.\n\n## Installation\nTo build nftlb, just execute:\n```\nroot# autoreconf -fi\nroot# ./configure\nroot# make\n```\nFinally, install it:\n```\nroot# make install\n```\n\nAlso, [deb packages](https://repology.org/project/nftlb/versions) are available.\n\n## Usage\nCheck out the command help:\n```\n# ./nftlb -h\n```\nHere is the list of options:\n\n**[ -h | --help ]**: Show the command help.\u003cbr /\u003e\n**[ -l \u0026lt;LEVEL\u0026gt; | --log \u0026lt;LEVEL\u0026gt; ]**: 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).\u003cbr /\u003e\n**[ -L \u0026lt;OUTPUT\u0026gt; | --log-output \u0026lt;OUTPUT\u0026gt; ]**: Set the daemon logs output (0: syslog - default, 1: stdout, 2: stderr, 3: syslog+stdout, 4: syslog+stderr).\u003cbr /\u003e\n**[ -c \u0026lt;FILE\u0026gt; | --config \u0026lt;FILE\u0026gt; ]**: Initial configuration file, this argument is optional.\u003cbr /\u003e\n**[ -k \u0026lt;KEY\u0026gt; | --key \u0026lt;KEY\u0026gt; ]**: 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.\u003cbr /\u003e\n**[ -e | --exit ]**: This option executes the configuration file into nftables rules and then exit, so the web server won't be available.\u003cbr /\u003e\n**[ -d | --daemon ]**: Run nftlb as a daemon in background.\u003cbr /\u003e\n**[ -6 | --ipv6 ]**: Enable IPv6 support for the web service listening port.\u003cbr /\u003e\n**[ -H \u0026lt;HOST\u0026gt; | --host \u0026lt;HOST\u0026gt; ]**: Set the host for the web service (all interfaces by default).\u003cbr /\u003e\n**[ -P \u0026lt;PORT\u0026gt; | --port \u0026lt;PORT\u0026gt; ]**: Set the TCP port for the web service (5555 by default).\u003cbr /\u003e\n**[ -S | --serial ]**: Serialize nft commands.\u003cbr /\u003e\n**[ -m \u0026lt;MARK\u0026gt; | --masquerade-mark \u0026lt;MARK\u0026gt; ]**: Set masquerade mark in hex (80000000 by default).\u003cbr /\u003e\n\n\nNote: In order to use sNAT or dNAT modes, ensure you have activated the ip forwarding option in your system.\n\n### Controlling the server behaviour using environment variables\nYou can also specify a custom server key via the `NFTLB_SERVER_KEY` environment variable. Zero length keys will be ignored.\n\n```\nroot# NFTLB_SERVER_KEY=\"changeme\" nftlb -d\n```\n\n### JSON configuration file\nThe configuration files have the following format:\n```\n{\n\t\"farms\" : [\n\t\t{ \u003cobject farm 1\u003e },\n\t\t{ \u003cobject farm 2\u003e },\n\t\t{ ... }\n\t],\n\t\"addresses\" : [\n\t\t{ \u003cobject address 1\u003e },\n\t\t{ \u003cobject address 2\u003e },\n\t\t{ ... }\n\t],\n\t\"policies\" : [\n\t\t{ \u003cobject policy 1\u003e },\n\t\t{ \u003cobject policy 2\u003e },\n\t\t{ ... }\n\t]\n}\n```\nWhere every farm object has the following attributes:\n```\n{\n\t\"name\" : \"\u003cstring\u003e\",\t\t\t\t*Name of the service (required)*\n\t\"family\": \"\u003cipv4 | ipv6 | dual\u003e\",\t\t*Family of the virtual service (ipv4 by default)*\n\t\"virtual-addr\": \"\u003cip address\u003e\",\t\t\t*IP address for the virtual service (OBSOLETE)*\n\t\"virtual-ports\": \"\u003cport list\u003e\",\t\t\t*Port list separated by commas or ranges separated by a hyphen*\n\t\"source-addr\": \"\u003cip address\u003e\",\t\t\t*Source IP address instead of masquerading*\n\t\"mode\": \"\u003csnat | dnat | dsr | stlsdnat | local\u003e\",\t*Topology to be implemented (required)*\n\t\"protocol\": \"\u003ctcp | udp | sctp | all\u003e\",\t\t*Protocol to be used by the virtual service (tcp by default)*\n\t\"scheduler\": \"\u003cweight | rr | hash | symhash\u003e\",\t*Scheduler to be used (round robin by default)*\n\t\"sched-param\": \"\u003csrcip | dstip | srcport | dstport | srcmac | dstmac | none\u003e\",\t*Hash input parameters (none by default)*\n\t\"persistence\": \"\u003csrcip | dstip | srcport | dstport | srcmac | dstmac | none\u003e\",\t*Configured stickiness between client and backend (none by default)*\n\t\"persist-ttl\": \"\u003cnumber\u003e\",\t*Stickiness timeout in seconds (60 by default)*\n\t\"helper\": \"\u003cnone | ftp | pptp | sip | snmp | tftp\u003e\",\t*L7 helper to be used (none by default)*\n\t\"log\": \"\u003cnone | input | forward | output\u003e\",\t*Enable logging (none by default)*\n\t\"log-prefix\": \"\u003cstring|KNAME|TYPE|FNAME|ANAME\u003e\",\t*Farm log prefix (default \"TYPE-FNAME\")*\n\t\"log-rtlimit\": \"\u003cnumber\u003e[/\u003csecond | minute | hour | day | week \u003e]\",\t\t\t*Security logs rate limit (0/second by default)*\n\t\"mark\": \"\u003chexadecimal mark\u003e\",\t\t\t*Set mark mask for the farm (none by default)*\n\t\"priority\": \"\u003cnumber\u003e\",\t\t\t\t*Priority availability for backends \u003e 0 (1 by default)*\n\t\"limits-ttl\": \"\u003cnumber\u003e\",\t\t\t\t*Timeout of banned client due to limit protections (120 seconds by default)*\n\t\"new-rtlimit\": \"\u003cnumber\u003e[/\u003csecond | minute | hour | day | week \u003e]\",\t\t\t\t*Number of new connections per service (0/second by default)*\n\t\"new-rtlimit-burst\": \"\u003cnumber\u003e\",\t\t\t*Number of burst packets (disabled by default)*\n\t\"new-rtlimit-log-prefix\": \"\u003cstring|KNAME|TYPE|FNAME\u003e\",\t*Farm new rtlimit log prefix (default \"KNAME-TYPE-FNAME\")*\n\t\"rst-rtlimit\": \"\u003cnumber\u003e[/\u003csecond | minute | hour | day | week \u003e]\",\t\t\t\t*Number of tcp resets allowed (0/second by default)*\n\t\"rst-rtlimit-burst\": \"\u003cnumber\u003e\",\t\t\t*Number of burst RST packets (disabled by default)*\n\t\"rst-rtlimit-log-prefix\": \"\u003cstring|KNAME|TYPE|FNAME\u003e\",\t*Farm reset rtlimit log prefix (default \"KNAME-TYPE-FNAME\")*\n\t\"est-connlimit\": \"\u003cnumber\u003e\",\t\t\t\t*Number of established connections allowed (disabled by default)*\n\t\"est-connlimit-log-prefix\": \"\u003cstring|KNAME|TYPE|FNAME\u003e\",\t*Farm established connlimit log prefix (default \"KNAME-TYPE-FNAME\")*\n\t\"tcp-strict\": \"\u003con | off\u003e\",\t\t\t\t*Option to avoid bogus TCP attacks (disabled by default)*\n\t\"tcp-strict-log-prefix\": \"\u003cstring|KNAME|TYPE|FNAME\u003e\",\t*Farm TCP strict log prefix (default \"KNAME-TYPE-FNAME\")*\n\t\"verdict\": \"\u003clog | drop | accept\u003e\",\t\t\t*Verdict to apply when a limit or blacklist/whitelist matches (log and default verdict per list type by default)*\n\t\"flow-offload\": \"\u003con | off\u003e\",\t\t\t\t*Option to enable flow offload (disabled by default)*\n\t\"intra-connect\": \"\u003con | off\u003e\",\t\t\t\t*Option to enable connectivity from the local machine (disabled by default)*\n\t\"queue\": \"\u003cnumber\u003e\",\t\t\t\t*Number of the queue to send the packets to userspace (disabled by default)*\n\t\"state\": \"\u003cup | down | off | config_error\u003e\",\t\t\t*Set the status of the virtual service (up by default)*\n\t\"addresses\" : [\t\t\t\t\t*List of addresses*\n\t\t{\u003cobject address 1\u003e},\n\t\t{\u003cobject address 2\u003e},\n\t\t{...}\n\t],\n\t\"backends\" : [\t\t\t\t\t*List of backends*\n\t\t{\u003cobject backend 1\u003e},\n\t\t{\u003cobject backend 2\u003e},\n\t\t{...}\n\t],\n\t\"sessions\" : [\t\t\t\t\t*List of static sessions. It requires persistence enabled.*\n\t\t{\n\t\t{\u003cobject session 1\u003e},\n\t\t{\u003cobject session 2\u003e},\n\t\t{...}\n\t],\n\t\"policies\" : [\t\t\t\t\t*List of policies*\n\t\t{\n\t\t\t\"name\" : \"\u003cpolicy name\u003e\",\n\t\t},\n\t\t{...}\n\t]\n}\n```\nWhere every address object has the following attributes:\n```\n{\n\t\"name\" : \"\u003cstring\u003e\",\t\t\t\t*Name of the address (required)*\n\t\"family\": \"\u003cipv4 | ipv6 | dual\u003e\",\t\t*Family of the address (ipv4 by default)*\n\t\"ip-addr\": \"\u003cip address\u003e\",\t\t\t*IP address*\n\t\"ports\": \"\u003cport list\u003e\",\t\t\t\t*Port list separated by commas or ranges separated by a hyphen*\n\t\"protocol\": \"\u003ctcp | udp | sctp | all\u003e\",\t\t*Protocol to be used by the address (tcp by default)*\n\t\"verdict\": \"\u003clog | drop | accept\u003e\",\t\t\t*Verdict to apply when a limit or blacklist/whitelist matches (log and default verdict per list type by default)*\n\t\"log-prefix\": \"\u003cstring|KNAME|TYPE|FNAME|ANAME\u003e\",\t*Address log prefix (default \"TYPE-FNAME\")*\n\t\"log-rtlimit\": \"\u003cnumber\u003e[/\u003csecond | minute | hour | day | week \u003e]\",\t\t\t*Security logs rate limit per second (0/second by default)*\n}\n```\nWhere every backend object has the following attributes:\n```\n{\n\t\"name\" : \"\u003cstring\u003e\",\t\t\t\t*Name of the backend (required)*\n\t\"ip-addr\": \"\u003cip address\u003e\",\t\t\t*IP address for the backend (required)*\n\t\"port\": \"\u003cnumber\u003e\",\t\t\t\t*Backend port to redirect the connections*\n\t\"source-addr\": \"\u003cip address\u003e\",\t\t\t*Source IP address for a certain backend instead of masquerading or virtual service source address*\n\t\"weight\": \"\u003cnumber\u003e\",\t\t\t\t*Weight of the backend (1 by default)*\n\t\"priority\": \"\u003cnumber\u003e\",\t\t\t\t*Priority availability for the backend \u003e 0 (1 by default)*\n\t\"mark\": \"\u003chexadecimal mark\u003e\",\t\t\t*Set mark mask for the backend (none by default)*\n\t\"est-connlimit\": \"\u003cnumber\u003e\",\t\t\t*Number of established connections allowed per backend (disabled by default)*\n\t\"est-connlimit-log-prefix\": \"\u003cstring|KNAME|TYPE|FNAME|BNAME\u003e\",\t*Backend established connections log prefix (default \"KNAME-FNAME-BNAME\")*\n\t\"state\": \"\u003cup | down | off | available | config_error\u003e\",\t\t\t*Set the status of the backend (up by default)*\n}\n```\nWhere every session object has the following attributes:\n```\n{\n\t\"client\" : \"\u003cip address\u003e\",\t\t\t*Client with the same format than persistence configuration*\n\t\"backend\": \"\u003cbackend id\u003e\",\t\t\t*Backend ID to set a stickyness between client and backend*\n\t\"expiration\": \"\u003ctime\u003e\"\t\t\t\t*Dynamic sessions timeout. Static sessions doesn't include this attribute*\n}\n```\nWhere every policy object has the following attributes:\n```\n{\n\t\"name\" : \"\u003cstring\u003e\",\t\t\t\t*Name of the policy (required)*\n\t\"type\": \"\u003cblacklist | whitelist\u003e\",\t\t\t*Policy type*\n\t\"family\": \"\u003cipv4 | ipv6\u003e\",\t\t\t*Family of the policy (ipv4 by default)*\n\t\"log-prefix\": \"\u003cstring|KNAME|TYPE|FNAME|PNAME\u003e\",\t*Policy established connections log prefix (default \"KNAME-TYPE-PNAME-FNAME\")*\n\t\"elements\" : [\t\t\t\t\t*List of IPs or networks*\n\t\t{\n\t\t\t\"data\" : \"\u003cip or network\u003e\"\n\t\t},\n\t\t{...}\n\t]\n}\n```\n\nYou can find some examples in the *tests/* folder.\n\n### API examples\nOnce launched nftlb you can manage it through the API.\n\nVirtual service listing.\n```\ncurl -H \"Key: \u003cMYKEY\u003e\" http://\u003cNFTLB IP\u003e:5555/farms\n```\nSetup a new virtual service.\n```\ncurl -H \"Key: \u003cMYKEY\u003e\" -X POST http://\u003cNFTLB IP\u003e:5555/farms -d \"@tests/008_snat_ipv4_all_rr.json\"\n```\nAdd a new backend into a virtual service.\n```\ncurl -H \"Key: \u003cMYKEY\u003e\" -X POST http://\u003cNFTLB IP\u003e:5555/farms -d '{\"farms\" : [ { \"name\" : \"myfarm\", \"backends\" : [ { \"name\" : \"mynewbck\", \"ip-addr\" : \"192.168.0.150\", \"state\" : \"up\" } ] } ] }'\n```\nDelete a virtual service.\n```\ncurl -H \"Key: \u003cMYKEY\u003e\" -X DELETE http://\u003cNFTLB IP\u003e:5555/farms/lb01\n```\nDelete a backend of a virtual service.\n```\ncurl -H \"Key: \u003cMYKEY\u003e\" -X DELETE http://\u003cNFTLB IP\u003e:5555/farms/lb01/backends/bck1\n```\nGet the static and dynamic sessions.\n```\ncurl -H \"Key: \u003cMYKEY\u003e\" -X GET http://\u003cNFTLB IP\u003e:5555/farms/lb01/sessions\n```\nAddresses listing.\n```\ncurl -H \"Key: \u003cMYKEY\u003e\" http://\u003cNFTLB IP\u003e:5555/addresses\n```\nAddresses listing.\n```\ncurl -H \"Key: \u003cMYKEY\u003e\" http://\u003cNFTLB IP\u003e:5555/addresses\n```\nCreate a new address.\n```\ncurl -H \"Key: \u003cMYKEY\u003e\" -X POST http://\u003cNFTLB IP\u003e:5555/addresses -d '{ \"addresses\" : [ { \"name\" : \"myaddr\", \"family\": \"ipv4\", \"ip-addr\" : \"192.168.0.150\", \"ports\": \"8080\", \"protocol\": \"tcp\" } ] }'\n```\nAssign an address to a farm.\n```\ncurl -H \"Key: \u003cMYKEY\u003e\" -X POST http://\u003cNFTLB IP\u003e:5555/farms -d '{ \"farms\" : [ { \"name\" : \"myfarm\", \"addresses\" : [ { \"name\" : \"myaddr\" } ] } ] }'\n```\nDelete an address.\n```\ncurl -H \"Key: \u003cMYKEY\u003e\" -X DELETE http://\u003cNFTLB IP\u003e:5555/addresses/myaddr\n```\nDelete an assigned address.\n```\ncurl -H \"Key: \u003cMYKEY\u003e\" -X DELETE http://\u003cNFTLB IP\u003e:5555/farms/myfarm/addresses/myaddr\n```\nDelete an address.\n```\ncurl -H \"Key: \u003cMYKEY\u003e\" -X DELETE http://\u003cNFTLB IP\u003e:5555/addresses/myaddr\n```\n\n\n## How it works\n\nnftlb uses the nftables infrastructure to build virtual services, from user to kernel side. In that regard, the expressions **numgen** (with its **random** and **inc** modes) and **hash** (say **jhash** and **symhash**) allows to distribute traffic among several backends among other properties. More information:\n\n[https://wiki.nftables.org/wiki-nftables/index.php/Load_balancing](https://wiki.nftables.org/wiki-nftables/index.php/Load_balancing)\n[https://www.netfilter.org/projects/nftables/manpage.html](https://www.netfilter.org/projects/nftables/manpage.html)\n\nThis software creates the required tables named **nftlb** which are exclusive to the nftlb service and should not be managed manually. Ex: ip nftlb, ip6 nftlb, netdev nftlb...\n\nThe integration of nftlb with custom firewall rules are possible creating separated tables and playing with chain priorities. More information:\n\n[https://www.relianoid.com/resources/knowledge-base/nftlb/](https://www.relianoid.com/resources/knowledge-base/nftlb/)\n## Support\nPlease refer to the [netfilter users mailing list](http://netfilter.org/mailinglists.html#ml-user)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzevenet%2Fnftlb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzevenet%2Fnftlb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzevenet%2Fnftlb/lists"}