{"id":20849786,"url":"https://github.com/ulfox/iptlb","last_synced_at":"2025-08-20T19:08:02.859Z","repository":{"id":57656689,"uuid":"441402256","full_name":"ulfox/iptlb","owner":"ulfox","description":"IPTables LB","archived":false,"fork":false,"pushed_at":"2021-12-31T20:38:01.000Z","size":32,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-15T20:09:47.036Z","etag":null,"topics":["golang","iptables","loadbalancer"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ulfox.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":"2021-12-24T07:47:33.000Z","updated_at":"2022-01-21T05:50:04.000Z","dependencies_parsed_at":"2022-08-26T05:51:17.504Z","dependency_job_id":null,"html_url":"https://github.com/ulfox/iptlb","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ulfox/iptlb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ulfox%2Fiptlb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ulfox%2Fiptlb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ulfox%2Fiptlb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ulfox%2Fiptlb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ulfox","download_url":"https://codeload.github.com/ulfox/iptlb/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ulfox%2Fiptlb/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271369755,"owners_count":24747800,"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-08-20T02:00:09.606Z","response_time":69,"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":["golang","iptables","loadbalancer"],"created_at":"2024-11-18T03:06:44.937Z","updated_at":"2025-08-20T19:08:02.829Z","avatar_url":"https://github.com/ulfox.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# IPTLB\n\nSimple IPTables loadbalancer app\n\n## Description\n\nIPTLB can be configured to apply rules that capture the traffic to a specific socket ipv4 address and redirect the packets to different addresses. When multiple addresses are given as destinations, a random loadbalance logic will be applied to split the traffic between the destinations.\n\n## Options\n\n### Run\n\nOption: `-run`\n\nIPTLB will not make any change to the iptables unless **-run** has been provided. Without run we essentially write the profile in the local state which we can use on the future by adding the run flag. This option can be used with **-use-state** \u0026\u0026 **-state-file=/path/to/state.db** to read a local state file and apply it.\n\n### Rules Backend (default)\n\nOption: `-rules-backend=[client/proxy/server]` \n\nThis option is by default \"client\". Set to `client` if you want to apply the rules in the client side. Set to `proxy` if you want to apply the rules in an intermediate server, and last set to `server` if you want to apply the rules in the server side.\n\nThe difference with the above 3 modes is the chain where we apply the jump before we apply our DNAT.\n- client: OUTPUT\n- proxy: PREROUTING\n- server: INPUT\n\nWhen we use \"client\", we are essentially applying a LB logic in the client host.\n\n### (UNIQUE) Source Addr\n\nOption: `-src-addr`\n\nThe source socket ipv4 address that you want to use as a loadbalancing ingress. If you are applying rules in the client side the IPV4 address could be any address. Even non-routable addresses will work because the rules will capture the OUTPUT chain (before it leaves the gw)\n\n**Note-1**: The source address is the address we are going to use to capture the packet stream that we want to redirect. This option is unique across all profiles (see profile option). We can not use the same source address because the first jump that will satisfy the condition will terminate the nat evaluation. Due to that reason, having multiple -src-addr with different destinations does not work. IPTLB allows to check the protocol also (see protocol option). While the protocol option can differentiate the jump rule, the functionality is not yet implemented, so for now a -src-addr=x:y is global and can not be used a second time. In the future we will allow this for different protocols\n\n### Destination Addresses\n\nOption: `-dest-addr`\n\nThis is a comma-separated string of destination ipv4 socket addresses (e.g. **ipv4_1:port1,ipv4_2:port2,...**). The destinations rules will have a random probability (Same logic as that used in kubernetes services) with the last rule being always 100% probable.\n\nFor example if we have 4 destination endpoints, then the probability will be as follows\n- First endpoint 1/4 chance\n- Second endpoint 1/3 chance\n- Third endpoint 1/2 chance\n- Last, always\n\n### Profile\n\nOption: `-profile=profileName`\n\nIPTLB uses profiles to keep track and apply rules for different **-src-addr**. For example we can have 1 profile to capture traffic from **-src-addr=someIPV4-0:somePort-0** and redirect it to a list of hostsA, and a different profile that captures traffic from **-src-addr=someIPV4-1:somePort-1** and redirects the traffic to a list of different hosts or even the same\n\n### Reset\n\nOption: `-reset`\n\nOnce a profile have been created (written to local state) and applied (actual iptable chains and rules created), we can not change that profile without adding **-reset**. Reset essentially allows you to do an update on the rules and profile. This works as follows:\n- IPTLB loads the profile from the state\n- Removes rules \u0026 chains for the specific profile\n- Writes the new input to local state\n- Creates new chain and inputs\n\n### Delete\n\nOption: `-delete`\n\nWe can remove a profile and the related chains and rules by applying **-delete** flag. \n- IPTLB loads the profile from the state\n- Removes rules \u0026 chains for the specific profile\n- Deletes profile from local state\n\n### State Path\n\nOption: `-state-file=/path/to/state.db`\n\nThis option allows us to instruct IPTLB to write state to a different location (**Default: ./local/state.db**)\n\n**Note**: If you use this option to create profiles and apply them, then you need to re-use it if you want to make changes or delete the profiles. If you do not pass the option the second time or some time later in the future, IPTLB will not be able to see the changes that were made on older invocations.\n\n### Chain Logging\n\nOption: `-log-custom-chain`\n\nWith this option we enable verbose logging for the created chains and jump rules. The logs will appear in **dmesg**. You can control the log verbosity by using the **-log-level=N** option (see option below)\n\n### Log Level\n\nOption: `-log-level=N`\n\nThe log level for the iptable rules (**Default: 4**). This requires **-log-custom-chain** enabled or it will not do anything.\n\n\n### Protocol\n\nOption: `-protocol=protocol`\n\nWe can control the protocol that will be used to filter the NAT jump rules (**Default: tcp**).\n\n### Use State\n\nOption: `-use-state`\n\nThis option has only one usage, to instruct IPTLB to use the profiles locally. We need to also provide the **-run** option to apply the local state in the iptables\n\n**Note**: Incompatible with **-src-addr** ||\u0026\u0026 **-dest-addr**\n\n## Example\n\n### Create profile\nLocally I have a 10.0.1.x network (with Host IP 10.0.1.4) and a service listening to port 8080. On this example I will use a different network (10.100.0.10) with different port (8081) as my source, the destination will be the actual host `10.0.1.4:8080` \n\nActual endpoint\n- 10.0.1.4:8080\n\nIngress endpoint\n- 10.100.0.10:8081 // This is not routable in my network but it will work since we are going to capture the packets in the OUTPUT chain and apply DNAT rules for 10.0.1.4\n\n```bash\n$\u003e sudo ./iptlb -run -profile=test -log-custom-chain -src-addr=10.100.0.10:8081 -dest-addr=10.0.1.4:8080\nINFO[0000] Initiating                                    Component=main Prog=iptlb\nINFO[0000] map[]                                         Component=main Prog=iptlb\nINFO[0000] db operator initiated                         Component=main Prog=iptlb\nINFO[0000] Inputs validated successfuly                  Component=Operator Stage=Configure\nINFO[0000] Chain [IPTLB_NAT_TEST] on table [nat] does not exist. Creating...  Stage=createChain\nINFO[0000] Enabled logging to chain IPTLB_NAT_TEST       Stage=createChain\nINFO[0000] [Append] Rule: [-p tcp -d 10.100.0.10 --dport 8081 -m statistic --mode random --probability 1.00000 -j DNAT --to-destination 10.0.1.4:8080] on table[nat]/chain[IPTLB_NAT_TEST]  Stage=AddRule\nINFO[0000] [Append] Rule: [-j RETURN] on table[nat]/chain[IPTLB_NAT_TEST]  Stage=AddRule\nINFO[0000] Done configuring table[nat]/chain[IPTLB_NAT_TEST]  Stage=NATLBRules\nINFO[0000] [Insert] Rule: [-p tcp -d 10.100.0.10 --dport 8081 -j IPTLB_NAT_TEST] at [1] on table[nat]/chain[OUTPUT]  Stage=InsertRule\nINFO[0000] [Insert] Rule: [-d 10.100.0.10 -p tcp -j LOG --log-prefix IPTLB:OUTPUT:ACCEPT: --log-level 4] at [1] on table[nat]/chain[OUTPUT]  Stage=InsertRule\nINFO[0000] Done configuring profile [test]               Stage=AddProfile\n\n```\n\nDoing a curl on the `10.100.0.10:8081`\n\n```bash\n$\u003e curl https://10.100.0.10:8081 -kLI\nHTTP/2 404 \ncontent-type: text/plain; charset=utf-8\nx-content-type-options: nosniff\ncontent-length: 19\ndate: Fri, 24 Dec 2021 08:12:46 GMT\n\n```\n\n### View state file\n\n**Note**: We can change the statefile manually only when have not applied it. If we make changes manually after we have applied it with **-run** then IPTLB probably will not delete/update old rules related with the change.\n\n```bash\n$\u003e sudo cat local/state.db \ntest:\n  destination:\n  - 10.0.1.4:8080\n  logEnabled: true\n  logLevel: \"4\"\n  protocol: tcp\n  rulesBackend: client\n  source: 10.100.0.10:8081\n```\n\n### Delete profile\n\nWe can delete a profile by issuing:\n\n```bash\n$\u003e sudo ./iptlb -run -profile=test --delete\nINFO[0000] Initiating                                    Component=main Prog=iptlb\nINFO[0000] map[]                                         Component=main Prog=iptlb\nINFO[0000] db operator initiated                         Component=main Prog=iptlb\nWARN[0000] Delete has been enabled. Deleting rules from profile [test]  Component=Operator Stage=Configure\nINFO[0000] [Deleted] Rule: [-p tcp -d 10.100.0.10 --dport 8081 -m statistic --mode random --probability 1.00000 -j DNAT --to-destination 10.0.1.4:8080] table[nat]/chain[IPTLB_NAT_TEST]  Stage=RemoveRule\nINFO[0000] [Deleted] Rule: [-j RETURN] table[nat]/chain[IPTLB_NAT_TEST]  Stage=RemoveRule\nINFO[0000] Done configuring table[nat]/chain[IPTLB_NAT_TEST]  Stage=NATLBRules\nINFO[0000] [Deleted] Rule: [-p tcp -d 10.100.0.10 --dport 8081 -j IPTLB_NAT_TEST] table[nat]/chain[OUTPUT]  Stage=RemoveRule\nINFO[0000] [Deleted] Rule: [-d 10.100.0.10 -p tcp -j LOG --log-prefix IPTLB:OUTPUT:ACCEPT: --log-level 4] table[nat]/chain[OUTPUT]  Stage=RemoveRule\nINFO[0000] Done cleaning profile [test]                  Stage=DeleteProfile\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fulfox%2Fiptlb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fulfox%2Fiptlb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fulfox%2Fiptlb/lists"}