{"id":13617576,"url":"https://github.com/bparli/convey","last_synced_at":"2026-01-02T09:06:22.899Z","repository":{"id":49432108,"uuid":"163129577","full_name":"bparli/convey","owner":"bparli","description":"Layer 4 load balancer with dynamic configuration loading","archived":false,"fork":false,"pushed_at":"2021-06-17T17:43:56.000Z","size":478,"stargazers_count":345,"open_issues_count":5,"forks_count":45,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-11-08T02:33:42.712Z","etag":null,"topics":["load-balancer","rust","tcp","tokio"],"latest_commit_sha":null,"homepage":"","language":"Rust","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/bparli.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":"2018-12-26T02:57:12.000Z","updated_at":"2024-11-02T18:29:43.000Z","dependencies_parsed_at":"2022-09-08T00:11:40.370Z","dependency_job_id":null,"html_url":"https://github.com/bparli/convey","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bparli%2Fconvey","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bparli%2Fconvey/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bparli%2Fconvey/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bparli%2Fconvey/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bparli","download_url":"https://codeload.github.com/bparli/convey/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248835406,"owners_count":21169212,"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":["load-balancer","rust","tcp","tokio"],"created_at":"2024-08-01T20:01:44.085Z","updated_at":"2026-01-02T09:06:22.820Z","avatar_url":"https://github.com/bparli.png","language":"Rust","funding_links":[],"categories":["Rust","Libraries","库 Libraries","rust"],"sub_categories":["Cloud","云 Cloud"],"readme":"# Convey\nLayer 4 load balancer with dynamic configuration loading featuring proxy, passthrough and direct server return modes\n\n## Features\n- Stats page (at /stats) with basic connection/bytes counters and backend server pool statuses\n- Dynamic configuration re-loading of backend servers and associated weights.  Configuration is loaded via a .toml file (see sample.toml for a full example).\n- Tcp-based health checking of backend servers at a configured interval.  If a server fails its health check it will be automatically removed from selection and added back once its health checks are successful.\n\n### Proxy Features\n- Event-driven TCP load balancer built on [tokio].\n- Weighted round-robin load balancing.  For uniform round robin simply leave out the weights or set them to be equal.\n- TCP connection termination\n\n### Passthrough and Direct Server Return (DSR) Features\n- Packet forwarding (no TCP termination)\n- Minimal internal connection tracking\n- NAT\n\n## Usage\n```\nConvey 0.3.5\n\nUsage:\n  convey\n  convey --config=\u003cconfig_file\u003e\n  convey (-p | --passthrough) --config=\u003cconfig_file\u003e\n  convey (-d | --dsr) --config=\u003cconfig_file\u003e\n  convey (-p | --passthrough)\n  convey (-d | --dsr)\n  convey (-h | --help)\n  convey (-v | --version)\n\nOptions:\n  -h, --help               Show this screen.s\n  -p, --passthrough        Run load balancer in passthrough mode (instead of default proxy mode)\n  -d, --dsr                Run load balancer in direct server mode (instead of default proxy mode)\n  --config=\u003cconfig_file\u003e   Config file location [default config.toml].\n  -v, --version            Show version.\n  ```\n\n### Passthrough mode\nFor passthrough mode we need a couple iptables rules on the convey load balancer to handle ingress packets from the client and responses from the backend load balanced servers.  Since TCP is not terminating we need to ensure the OS does not send a RST in response to any packets destined for a port that does not have a process bound to it.  We need to do the same for any packets came back through from a backend server.  Convey internally assigns ephemeral ports 32768-61000 to map connections to clients.\n\n![passthrough](https://docs.google.com/drawings/d/e/2PACX-1vS1umK8iY4EryR0hV4s1lad2r5BrO4_nbFTCua9jqkPP7fSQXodXCZ8XD7kvkfeXxdphtMFczIij-K1/pub?w=581\u0026h=326)\n\nFor passthrough mode on the convey load balancer\n```\nsudo iptables -t raw -A PREROUTING -p tcp --dport \u003cLOAD_BALANCER_PORT\u003e -j DROP\nsudo iptables -t raw -A PREROUTING -p tcp --sport \u003cBACKEND_SERVER_PORT\u003e --dport 33768:61000 -j DROP\n```\n\nTo run\n```\nsudo ./target/release/convey --passthrough --config=sample-passthrough.toml\n```\n\n### DSR Mode\nFor dsr mode we need the same iptables rule for ingress packets.  Responses from the backend load balanced servers will be going directly to the clients.  The \"listening\" port on the convey load balancer must match the backend load balanced servers listening ports in this mode.\n\n![dsr](https://docs.google.com/drawings/d/e/2PACX-1vTkBC0326E1hZwRw_KBbdiP3npNL_2KGq2QdUiS2J05xX1y5uhKIDegpEmviyvBWz4NmHbgVTB6jmsq/pub?w=581\u0026h=326)\n\nFor dsr mode on the convey load balancer\n```\nsudo iptables -t raw -A PREROUTING -p tcp --dport \u003cLOAD_BALANCER_PORT\u003e -j DROP\n```\n\nIn dsr mode the backend servers \"participate\" in that their response packets must be sent directly to the client.  Convey does not do any encapsulation so, for example, a gre tunnel is not an option.  Instead, [Traffic Control] can be used as an egress nat.\n\nFor dsr mode on backend servers\n```\nsudo tc qdisc add dev \u003cLOCAL_INTERFACE\u003e root handle 10: htb\n\nsudo tc filter add dev \u003cLOCAL_INTERFACE\u003e parent 10: protocol ip prio 1 u32 match ip src \u003cLOCAL_SERVER_IP\u003e match ip sport \u003cLISTEN_PORT\u003e 0xffff match ip dst \u003cLOAD_BALANCER_IP\u003e action ok\n\nsudo tc filter add dev \u003cLOCAL_INTERFACE\u003e parent 10: protocol ip prio 10 u32 match ip src \u003cLOCAL_SERVER_IP\u003e match ip sport \u003cLISTEN_PORT\u003e 0xffff action nat egress \u003cLOAD_BALANCER_IP\u003e\n```\n\nTo run\n```\nsudo ./target/release/convey --dsr --config=sample-passthrough.toml\n```\n\n### Proxy\nNo special setup neccessary\n\n![proxy](https://docs.google.com/drawings/d/e/2PACX-1vQC7fAvVEs0Xb0kcAFfCLIVukhkIrlu-DS_tbrtgpRonmsHO9STpnXvI7NogXiBVUON9gS-L4MLqYV2/pub?w=581\u0026h=326)\n\nTo run\n```\nsudo ./target/release/convey --config=sample-proxy.toml\n```\n\n## Tests\nThe easiest way to run tests is to run them as superuser.  This is because some of the tests spin up test servers as well as a convey load balancer instance.\n```\nsudo ~/.cargo/bin/cargo test\n```\n\n## AF_XDP\nThe `feature/xdp` branch is a WIP using AF_XDP to loadbalance in passthrough and DSR modes.  For now it will be maintained in a separate branch since it requires kernel versions 5.4 or greater.\n\n## Build\n```cargo build --release```\n\n\u003c!-- references --\u003e\n[tokio]: https://tokio.rs\n[Traffic Control]: http://tldp.org/HOWTO/Traffic-Control-HOWTO/index.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbparli%2Fconvey","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbparli%2Fconvey","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbparli%2Fconvey/lists"}