{"id":24737458,"url":"https://github.com/engineersbox/tcp-proxy","last_synced_at":"2026-06-30T02:32:02.184Z","repository":{"id":109328138,"uuid":"341162608","full_name":"EngineersBox/TCP-Proxy","owner":"EngineersBox","description":"A TCP proxy with ingress/egress filtering","archived":false,"fork":false,"pushed_at":"2021-02-26T13:16:11.000Z","size":73,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-22T17:44:51.824Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/EngineersBox.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2021-02-22T10:31:22.000Z","updated_at":"2021-02-26T13:16:13.000Z","dependencies_parsed_at":"2023-03-26T16:20:40.642Z","dependency_job_id":null,"html_url":"https://github.com/EngineersBox/TCP-Proxy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/EngineersBox/TCP-Proxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EngineersBox%2FTCP-Proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EngineersBox%2FTCP-Proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EngineersBox%2FTCP-Proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EngineersBox%2FTCP-Proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EngineersBox","download_url":"https://codeload.github.com/EngineersBox/TCP-Proxy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EngineersBox%2FTCP-Proxy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34950328,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-30T02:00:05.919Z","response_time":92,"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":[],"created_at":"2025-01-27T22:08:24.695Z","updated_at":"2026-06-30T02:32:02.177Z","avatar_url":"https://github.com/EngineersBox.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TCP-Proxy\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/EngineersBox/TCP-Proxy/Rust?style=for-the-badge)\n\n\nTCP-Proxy is a Rust based proxy and traffic filtering service. It's built around an allocator-acceptor model to serve, collate and forward requests/responses.\nConnections are defined via a JSON file describing:\n\n* Source and destination endpoints\n* Egress/Ingress rule sets to apply to requests and responses selectively\n* Type of rules and associated parameters or configurations to use as a basis for the rules\n\n## Basc Schema\n\n```json\n{\n\t\"bindings\": [\n\t\t{\n\t\t\t\"name\": \"\u003cSTRING\u003e\",\n\t\t\t\"from\": \"\u003cADDR:PORT\u003e\",\n\t\t\t\"to\": \"\u003cADDR:PORT\u003e\",\n\t\t\t\"rules\": {\n\t\t\t\t\"ingress\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"kind\": \"\u003cHEADER | URL | METHOD | VERSION\u003e\",\n\t\t\t\t\t\t\"header_mappings\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"key\": \"\u003cSTRING\u003e\",\n\t\t\t\t\t\t\t\t\"value\": \"\u003cSTRING\u003e\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n                        \"url_wildcard\": \"\u003cREGEX\u003e\",\n                        \"method_enum\": \"\u003cGET | POST | PATCH | PUT | OPTIONS | UPDATE\u003e\",\n                        \"version_float\": \"\u003cFLOAT\u003e\"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"egress\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"kind\": \"\u003cHEADER | URL | METHOD | VERSION\u003e\",\n\t\t\t\t\t\t\"header_mappings\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"key\": \"\u003cSTRING\u003e\",\n\t\t\t\t\t\t\t\t\"value\": \"\u003cSTRING\u003e\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"url_wildcard\": \"\u003cREGEX\u003e\",\n\t\t\t\t\t\t\"method_enum\": \"\u003cGET | POST | PATCH | PUT | OPTIONS | UPDATE\u003e\",\n\t\t\t\t\t\t\"version_float\": \"\u003cFLOAT\u003e\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t]\n}\n```\n\nIt is important to note that different fields in the rules are required depending on the kind of rule. They are as follows:\n\n| **Kind**  | **Required Field**|\n|---------\t|-----------------\t|\n| `HEADER`  | `header_mappings` |\n| `URL`     | `url_wildcard`    |\n| `METHOD`  | `method_enum`     |\n| `VERSION`\t| `version_float`   |\n\n## Example Rule Binding JSON\n\n```json\n{\n\t\"bindings\": [\n\t\t{\n\t\t\t\"name\": \"test1\",\n\t\t\t\"from\": \"localhost:3000\",\n\t\t\t\"to\": \"google.com:80\",\n\t\t\t\"rules\": {\n\t\t\t\t\"ingress\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"kind\": \"HEADER\",\n\t\t\t\t\t\t\"header_mappings\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"key\": \"content-type\",\n\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"egress\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"kind\": \"VERSION\",\n\t\t\t\t\t\t\"version_float\": 1.1\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"kind\": \"URL\",\n\t\t\t\t\t\t\"url_wildcard\": \"https://.*\\\\.instaclustr\\\\.com\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t]\n}\n```\n\n## Service Configuration\n\nThere are a few configuration properties that can be set to change the way resources are used and what types of handler are used with the service.\nThese are specified via a `config.properties` in the `config` directory:\n\n| **Property**                 \t| **Type**  \t| **Description**                                                                                                                                                            \t| **Default Value** \t|\n|------------------------------\t|-----------\t|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------\t|-------------------\t|\n| `allocator_thread_pool_size` \t| `INTEGER` \t| Set the amount of threads to reserve in a pool to act as allocators for threads to handle connections                                                                      \t| `10`              \t|\n| `handler_thread_pool_size`   \t| `INTEGER` \t| Set the amount of threads to reserve in a pool to handle connections with                                                                                                  \t| `50`              \t|\n| `thread_handler_type`        \t| `ENUM`    \t| What method of packet handling should be used:\u003cbr\u003e* `PROGRESSIVE` = Forward packets as they come in\u003cbr\u003e* `CAPTURE` = Buffer all packets and then forward once all collated \t| `PROGRESSIVE`     \t|\n\n## Example Logging\n\nTCP-Proxy logs all the activity from within to stdout via the `slog` library. Utilising the above example rule bindings, we can see the output to stdout is as follows:\n```log\nFeb 26 23:59:47.477 INFO Logging directory already exists, skipping\nFeb 26 23:59:47.478 DEBG Creating proxy thread pool of size: 50\nFeb 26 23:59:47.479 INFO Initializing proxy 2 binding(s)\nFeb 26 23:59:47.482 INFO Multiple SocketAddr resolutions [localhost:3000] -\u003e [127.0.0.1:3000, [::1]:3000], defaulting to [127.0.0.1:3000]\nFeb 26 23:59:47.516 DEBG Binding listener [0] to connection: localhost:3000 \u003c-\u003e google.com:80 \nFeb 26 23:59:47.516 DEBG Invoked acceptor thread for listener [0] using hadler type [PROGRESSIVE]\nFeb 26 23:59:47.517 INFO Starting main listener loop\nFeb 26 23:59:59.604 DEBG New connection\nFeb 26 23:59:59.621 INFO TRAFFIC LOG [EGRESS] [96750fe7-80be-4789-810c-fea6fc951808]\nFeb 26 23:59:59.637 DEBG REQUEST CONTENT [EGRESS]:\n\nGET / HTTP/1.1\nHost: 127.0.0.1:3000\nUser-Agent: curl/7.64.1\nAccept: */*\nX-Test-Header: somevalue\n\nFeb 26 23:59:59.637 INFO TRAFFIC LOG [INGRESS] [96750fe7-80be-4789-810c-fea6fc951808]\nFeb 26 23:59:59.794 DEBG RESPONSE CONTENT [INGRESS] [96750fe7-80be-4789-810c-fea6fc951808]:\n\nHTTP/1.1 301 Moved Permanently\nLocation: http://www.google.com:3000/\nContent-Type: text/html; charset=UTF-8\nDate: Fri, 26 Feb 2021 12:59:59 GMT\nExpires: Sun, 28 Mar 2021 12:59:59 GMT\nCache-Control: public, max-age=2592000\nServer: gws\nContent-Length: 224\nX-XSS-Protection: 0\nX-Frame-Options: SAMEORIGIN\n\n\u003cHTML\u003e\u003cHEAD\u003e\u003cmeta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\"\u003e\n\u003cTITLE\u003e301 Moved\u003c/TITLE\u003e\u003c/HEAD\u003e\u003cBODY\u003e\n\u003cH1\u003e301 Moved\u003c/H1\u003e\nThe document has moved\n\u003cA HREF=\"http://www.google.com:3000/\"\u003ehere\u003c/A\u003e.\n\u003c/BODY\u003e\u003c/HTML\u003e\n\nFeb 26 23:59:59.794 DEBG Client closed connection [96750fe7-80be-4789-810c-fea6fc951808]\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fengineersbox%2Ftcp-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fengineersbox%2Ftcp-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fengineersbox%2Ftcp-proxy/lists"}