{"id":22140900,"url":"https://github.com/stealth/loaded","last_synced_at":"2025-07-25T23:31:55.062Z","repository":{"id":17084050,"uuid":"19849141","full_name":"stealth/loaded","owner":"stealth","description":"IPv4 and IPv6 load balancer","archived":false,"fork":false,"pushed_at":"2017-05-18T11:43:16.000Z","size":20,"stargazers_count":9,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2023-03-14T04:05:15.966Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stealth.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}},"created_at":"2014-05-16T08:08:17.000Z","updated_at":"2021-04-13T17:25:47.000Z","dependencies_parsed_at":"2022-08-26T13:00:19.119Z","dependency_job_id":null,"html_url":"https://github.com/stealth/loaded","commit_stats":null,"previous_names":[],"tags_count":2,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stealth%2Floaded","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stealth%2Floaded/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stealth%2Floaded/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stealth%2Floaded/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stealth","download_url":"https://codeload.github.com/stealth/loaded/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227629069,"owners_count":17796054,"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","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":[],"created_at":"2024-12-01T21:08:33.020Z","updated_at":"2024-12-01T21:08:33.658Z","avatar_url":"https://github.com/stealth.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"loaded - a IPv4/IPv6 load balancer for Linux\n=============================================\n\nPre\n---\n\nIt's under a BSDish license. For the source, see\n\nhttps://github.com/stealth/loaded\n\n\nRequirements\n------------\n\nLoaded requires _netfilter_ and the __NFQUEUE__ target enabled in kernel which is\ndefault on most Linux distros.\nUsually it's in the `nfnetlink_queue` LKM and loaded by the\n`loaded.config` script.\n\nFor Loaded to build, you need some netfilter/nfqueue libs. On my\nopenSUSE system they are found in these RPM's:\n\n\t* libnfnetlink-devel\n\t* libnfnetlink0\n\t* libnetfilter_queue-devel\n\t* libnetfilter_queue1\n\nand if building with `-DUSE_CAP` for the least privilege model:\n\n\t* libcap2 or libcap\n\t* libcap-devel\n\n\nSetup\n-----\n\n\nEdit `loaded.config` for your virtual IP etc, and run it\nbefore you start `loaded` itself.\nThe config file is self explaining and needs to be passed via the `-c` command\nline switch to Loaded, or it finds it by themself inside the current working\ndirectory if its named `loaded.conf`.\n\nLoaded supports CPU's with multiple cores (or SMP). In the config file you can\nedit `FIRST_CORE` and `LAST_CORE` which will handle the load balancing.\nBy default Loaded will run as root, but you can pass the '-U' switch to drop its\nprivilges to this user. Loaded will also chroot itself to the __/var/run/empty__\ndirectory for maximum safety, so be sure it exists. If you have a working SSH\nsetup, its probably already there.\n\nLoaded is currently supporting `weighted` and `rr` balancing strategy. `rr`\n(round robin) is less expensive than `weighted`. It is recommended to use `rr`\nsince for million of balanced clients, it is expensive to choose the least\nweighted backend for a new appearing client versus just picking the next\nvia RR. In the long run, `rr` should be the best balancing strategy anyways.\n\n    balancer# ip addr\n    [...]\n    balancer# ip route\n\nto see whether the addresses\nand routes are set up correctly by the config script. In order for the\nreturning packets to contain the VIP address, Loaded provides a `private_GW`\nwhich you need to set up as the default GW on the backend systems, so they\ntraverse the load balancer which takes care to mangle all packets properly.\nIf you get Direct Server Return working on the backends, you dont need that.\n\n\nTo run loaded for IPv6:\n\n    balancer6# ./loaded.config6\n    balancer6# ./loaded -6 -c loaded.config6\n\n\nDue to some weird kernel behavior which does not do Neighbor Discovery for\nIPv6 addresses it mangled into a packet (unlike for IPv4), you need to set\nstatic MAC entries for each backend node on the balancer:\n\n\n    balancer6# ip -6 neigh add \u003cIP6addr\u003e lladdr \u003cMAC\u003e dev \u003cPrivate NIC\u003e nud permanent\n\nfor each backend node. This will add a static entry in the neighbor table\nand the kernel will find which MAC address to use for the modified packet.\nEach time you call `./loaded.config6` you need to re-set the neigh addresses\nso you probably better write a script for it.\nYou can do it in a similar way for IPv4 as it would speed up balancing, since\nARP lookups are no longer done.\n\nIn particular if you balance IP6, make sure to disable automatic network\nconfiguration on your balancer and backend nodes, as this could mess with\nthe setup of your routing tables (remember: routes from the backend node\nhave the default gw of the private load balancer address).\n\nAnd thats it!\n\nFailover\n--------\n\nFor IPv4 there is also something implemented which is usually called automatic\nfailover. If you start Loaded with the `-f` switch, it will start a second thread\nwhich checks in a configured interval which nodes are still reachable. The\nnodes must answer to __ICMP_ECHO__ (ping) broadcasts:\n\n    backend# echo 0 \u003e /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts\n\nDead nodes will be removed from the list of available backends and new nodes\nare added respectively, so you have some kind of \"hotplugging\" with the\nbackends. Failover is experimental.\nEnsure that you do not run the service which you are testing (`port_alive`)\non the load balancers private GW address since it will add itself to the list\nof backend nodes otherwise.\nIPv6 failover is not yet done but would work the same way. I just lack the time\nto implement it. (Want to sponsor? :)\n\n\n\nBig picture\n-----------\n\n```\n                            +----+\n  [ backend1 ]o\u003e-------     |    |\n                        \u003e -o|  s |\n  [ backend2 ]o\u003e-------     |  w |\n                  ...   \u003e -o|  i |o-------\u003c private GW and NIC -o[ LOADED ]\n  [    ...   ]o\u003e------- ... |  t |                                   o\n                        \u003e -o|  c |                                   |\n  [ backendN ]o\u003e-------     |  h | ...                         \u003c pub NIC / VIP \u003e\n                            +----+    ..                             |\n                                         .... [ DNS ]o---------------+\n                                                                     |\n                                                                     |\n                                                             [ FW / public GW]\n\n\n```\n\n\nLoaded expects that it is only handling sane packets. That means there do not\nappear strange fragmentation offsets or header lenghts. Loaded is checking\nfor sanity, so that no overflows or such happen, but it will not track\nfragments. Therefore it is recommended to run a stateful firewall in front of\nLoaded, at the __FW__ point. Stateful firewalls will automatically normalize the\nTCP/IP traffic in order to track the TCP state engine and as a result no\nfragmented packets will leave the inbound interface.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstealth%2Floaded","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstealth%2Floaded","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstealth%2Floaded/lists"}