{"id":13775762,"url":"https://github.com/praetorian-inc/trudy","last_synced_at":"2026-01-14T11:21:49.315Z","repository":{"id":57610604,"uuid":"44784557","full_name":"praetorian-inc/trudy","owner":"praetorian-inc","description":"A transparent proxy that can modify and drop traffic for arbitrary TCP connections.","archived":true,"fork":false,"pushed_at":"2019-09-16T19:26:11.000Z","size":105,"stargazers_count":276,"open_issues_count":12,"forks_count":47,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-05-11T08:35:44.420Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/praetorian-inc.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":"2015-10-23T01:55:34.000Z","updated_at":"2025-05-10T14:25:35.000Z","dependencies_parsed_at":"2022-08-27T08:21:37.997Z","dependency_job_id":null,"html_url":"https://github.com/praetorian-inc/trudy","commit_stats":null,"previous_names":["praetorian-code/trudy","kelbyludwig/trudy"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/praetorian-inc/trudy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/praetorian-inc%2Ftrudy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/praetorian-inc%2Ftrudy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/praetorian-inc%2Ftrudy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/praetorian-inc%2Ftrudy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/praetorian-inc","download_url":"https://codeload.github.com/praetorian-inc/trudy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/praetorian-inc%2Ftrudy/sbom","scorecard":{"id":743370,"data":{"date":"2025-08-11","repo":{"name":"github.com/praetorian-inc/trudy","commit":"619d25bba2820157ec9f76d888131f5361493d14"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":3,"reason":"Found 3/9 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"project is archived","details":["Warn: Repository is archived."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 24 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-22T18:06:45.908Z","repository_id":57610604,"created_at":"2025-08-22T18:06:45.908Z","updated_at":"2025-08-22T18:06:45.908Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28418277,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":"2024-08-03T17:01:48.794Z","updated_at":"2026-01-14T11:21:49.292Z","avatar_url":"https://github.com/praetorian-inc.png","language":"Go","funding_links":[],"categories":["\u003ca id=\"d03d494700077f6a65092985c06bf8e8\"\u003e\u003c/a\u003e工具"],"sub_categories":["\u003ca id=\"0ff94312f3ab4898f5996725133ea9d1\"\u003e\u003c/a\u003e未分类"],"readme":"## Trudy\n\nTrudy is a transparent proxy that can modify and drop traffic for arbitrary TCP connections. Trudy can be used to programmatically modify TCP traffic for proxy-unaware clients. Trudy creates a 2-way \"pipe\" for each connection it proxies. The device you are proxying (the \"client\") connects to Trudy (but doesn't know this) and Trudy connects to the client's intended destination (the \"server\"). Traffic is then passed between these pipes. Users can create Go functions to mangle data between pipes.  [See it in action!](https://asciinema.org/a/7zkywm0biuz1wa64az3tmox8v) For a practical overview, check out [@tsusanka](https://twitter.com/tsusanka)'s very good [blog post](https://blog.susanka.eu/how-to-modify-general-tcp-ip-traffic-on-the-fly-with-trudy) on using Trudy to analyze Telegram's MTProto. \n\nTrudy can also proxy TLS connections. Obviously, you will need a valid certificate or a client that does not validate certificates.\n\nTrudy was designed for monitoring and modifying proxy-unaware devices that use non-HTTP protocols. If you want to monitor, intercept, and modify HTTP traffic, Burp Suite is probably the better option. \n\n## Author\n\nWritten by Kelby Ludwig ([@kelbyludwig](https://twitter.com/kelbyludwig))\n\n### Why I Built This\nI have done security research that involved sitting between a embedded device and a server and modifying some custom binary protocol on the fly. This usually is a slow process that involves sniffing legitimate traffic, and then rebuilding packets programmatically. Trudy enables Burp-like features for generalized TCP traffic.\n\n### Simple Setup\n\n0. Configure a virtual machine (Trudy has been tested on a 64-bit Debian 8 VM) to shove all traffic through Trudy. I personally use a Vagrant VM that sets this up for me. The Vagrant VM is available [here](https://github.com/praetorian-inc/mitm-vm). If you would like to use different `--to-ports` values, you can use Trudy's command line flags to change Trudy's listening ports.\n\n    `iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 8888 -m tcp -j REDIRECT --to-ports 8080`\n\n    `iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 443 -m tcp -j REDIRECT --to-ports 6443`\n\n    `iptables -t nat -A PREROUTING -i eth1 -p tcp -m tcp -j REDIRECT --to-ports 6666`\n\n    `ip route del 0/0`\n\n    `route add default gw 192.168.1.1 dev eth1`\n\n    `sysctl -w net.ipv4.ip_forward=1`\n\n1. Clone the repo on the virtual machine and build the Trudy binary.\n\n    `git clone https://github.com/kelbyludwig/trudy.git`\n\n    `cd trudy`\n\n    `go install`\n\n2. Run the Trudy binary as root. This starts the listeners. If you ran the `iptables` commands above, `iptables` will forward traffic destined for port 443 to port 6443. Trudy listens on this port and expects traffic coming into this port to be TLS. All other TCP connections will be forwarded through port 6666. \n\n    `sudo $GOPATH/bin/trudy`\n\n3. Setup your host machine to use the virtual machine as its router. You should see connections being made in Trudy's console but not notice any traffic issues on the host machine (except TLS errors).\n\n4. In order to manipulate data, just implement whatever functions you might need within the `module` package. The default implementations for these functions are hands-off, so if they do not make sense for your situation, feel free to leave them as they are. More detailed documentation is in the `module` package and the data flow is detailed below.\n\n\n5. To access the interceptor, visit `http://\u003cIP ADDRESS OF VM\u003e:8888/` in your web browser. The only gotcha here is you must visit the interceptor after starting Trudy but before Trudy receives a packet that it wants to intercept. \n\n## Data Flow\n\nModule methods are called in this order. Downward arrows indicate a branch if the `Do*` function returns true.\n\n```\nDeserialize -\u003e Drop -\u003e DoMangle -\u003e  DoIntercept -\u003e DoPrint -\u003e Serialize -\u003e BeforeWriteTo(Server|Client) -\u003e AfterWriteTo(Server|Client)\n                         |         /                |        /\n                         |_\u003e Mangle                 |_\u003e PrettyPrint\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpraetorian-inc%2Ftrudy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpraetorian-inc%2Ftrudy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpraetorian-inc%2Ftrudy/lists"}