{"id":17115555,"url":"https://github.com/dyxushuai/grpcdump","last_synced_at":"2025-04-13T04:10:50.817Z","repository":{"id":43510202,"uuid":"136314589","full_name":"dyxushuai/grpcdump","owner":"dyxushuai","description":"gRPC dump tool","archived":false,"fork":false,"pushed_at":"2020-09-30T08:49:21.000Z","size":10212,"stargazers_count":8,"open_issues_count":0,"forks_count":6,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-04T21:44:19.251Z","etag":null,"topics":["grpc","protobuf","tcpdump"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dyxushuai.png","metadata":{"files":{"readme":"README-zh.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-06-06T10:46:33.000Z","updated_at":"2022-10-09T11:29:50.000Z","dependencies_parsed_at":"2022-09-14T09:40:54.000Z","dependency_job_id":null,"html_url":"https://github.com/dyxushuai/grpcdump","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dyxushuai%2Fgrpcdump","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dyxushuai%2Fgrpcdump/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dyxushuai%2Fgrpcdump/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dyxushuai%2Fgrpcdump/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dyxushuai","download_url":"https://codeload.github.com/dyxushuai/grpcdump/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248661704,"owners_count":21141450,"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":["grpc","protobuf","tcpdump"],"created_at":"2024-10-14T17:45:11.410Z","updated_at":"2025-04-13T04:10:50.775Z","avatar_url":"https://github.com/dyxushuai.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gRPC dump tool\n\n\u003c!-- TOC --\u003e\n\n- [gRPC dump tool](#grpc-dump-tool)\n  - [示例](#)\n  - [需求](#)\n  - [[tcpdump][]工具简介](#tcpdump)\n  - [`grpcdump`设计目标](#grpcdump)\n  - [`grpcdump`设计细节](#grpcdump)\n    - [[AF_PACKET][]的golang实现[gopacket][]](#af-packetgolanggopacket)\n    - [TLS/SSL解密(暂未实现)](#tls-ssl)\n    - [动态加载[protobuf][]](#protobuf)\n    - [带缓存的格式化打印(readable)](#readable)\n\n\u003c!-- /TOC --\u003e\n\n## 示例\n\n```sh\n» sudo go run cmd/grpcdump/main.go -d lo0 -port 8085 -ip 127.0.0.1 -proto ./grpc_example/helloworld/helloworld/helloworld.proto\n2018/06/06 21:18:02 Starting capture on device \"lo0\"\n2018/06/06 21:18:02 reading in packets\n\nREQUEST(STREAM=1) \u003e 2018-06-06T21:18:04.921128144+08:00: 127.0.0.1:56327 ---\u003e 127.0.0.1:8085\n  HEADERS:\n    :method = \"POST\"\n    :scheme = \"http\"\n    :path = \"/helloworld.Greeter/SayHello\"\n    :authority = \"127.0.0.1:8085\"\n    content-type = \"application/grpc\"\n    user-agent = \"grpc-go/1.13.0-dev\"\n    te = \"trailers\"\n  BODY:\n    {\"name\":\"world\",\"i18\":\"zh\"}\n\nRESPONSE(STREAM=1) \u003e 2018-06-06T21:18:04.921691304+08:00: 127.0.0.1:56327 \u003c--- 127.0.0.1:8085\n  HEADERS:\n    :status = \"200\"\n    content-type = \"application/grpc\"\n  BODY:\n    {\"message\":\"Hello, 你好\"}\n\nRESPONSE(STREAM=1) \u003e 2018-06-06T21:18:04.921865543+08:00: 127.0.0.1:56327 \u003c--- 127.0.0.1:8085\n  HEADERS:\n    grpc-status = \"0\"\n    grpc-message = \"\"\n```\n\n## 需求\n\n设计一个类似[tcpdump][]的工具，用于[gRPC][]请求的数据包抓包。\n\n## [tcpdump][]工具简介\n\n\u003e TcpDump可以将网络中传送的数据包完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤，并提供and、or、not等逻辑语句来帮助你去掉无用的信息。 - 百度百科\n\n1. tcpdump工作于网络协议的IP层，使用[AF_PACKET][]套接字抓取所有进出的IP包。\n2. 通过解析IP包头过滤主机信息。\n3. 通过解析TCP包头过滤端口信息。\n\n## `grpcdump`设计目标\n\n1. [x] 使用[AF_PACKET][]原始套接字抓取并过滤IP包。\n2. [ ] 使用`keylog`解密TLS/SSL密文。\n3. [x] 使用HTTP2协议栈解码。\n4. [x] 动态加载[protobuf][]定义文件(.proto)，通过HTTP2 [:path][]头匹配对应Request和Response Message，解码body。\n5. [x] 带缓存的格式化打印(colorful?)。\n\n## `grpcdump`设计细节\n\n### [AF_PACKET][]的golang实现[gopacket][]\n\n[代码](pcap.go)\n\n使用[gopacket][]监听网卡，设置[BPF][]规则，为了能够串联请求和返回包，必须要求提供gPRC服务的IP和端口。并在头部打印流信息，如下：\n\n```sh\n127.0.0.1:50422 ---\u003e 127.0.0.1:8085\n127.0.0.1:50422 \u003c--- 127.0.0.1:8085\n```\n\n**1. http2包需要过滤掉[PRI][]/[代码](skip.go)** 相关[issue](https://github.com/golang/go/issues/14141)\n\n**2. 多路复用情况下需要根据strem id隔离数据包**\n\n### TLS/SSL解密(暂未实现)\n\n[gRPC][]客户端或者服务端需要使用[tls.Config.KeyLogWriter](tls.Config)记录[key_log][], grpcdump读取[key_log][]信息解密。\n\n**只推荐在debug模式下记录[key_log][]**\n\n### 动态加载[protobuf][]\n\n[代码](protobuf.go)\n\n指定[protobuf][]的定义文件,来实现运行时解析[protobuf][]编码的包。并打印序列化json，如下：\n\n```sh\n{\"name\":\"world\",\"i18\":\"zh\"}\n{\"message\":\"Hello, 你好\"}\n```\n\n**http2.DataFrame读出的body需要去空格！**\n　\n### 带缓存的格式化打印(readable)\n\n输出可读性比较好的格式, 如下：\n\n```sh\nREQUEST \u003e 2018-06-06T18:20:06.731710593+08:00: 127.0.0.1:53913 ---\u003e 127.0.0.1:8085\n  HEADERS:\n    :method = \"POST\"\n    :scheme = \"http\"\n    :path = \"/helloworld.Greeter/SayHello\"\n    :authority = \"127.0.0.1:8085\"\n    content-type = \"application/grpc\"\n    user-agent = \"grpc-go/1.13.0-dev\"\n    te = \"trailers\"\n  BODY:\n    {\"name\":\"world\",\"i18\":\"zh\"}\n\nRESPONSE \u003e 2018-06-06T18:20:06.73193703+08:00: 127.0.0.1:53913 \u003c--- 127.0.0.1:8085\n  HEADERS:\n    :status = \"200\"\n    content-type = \"application/grpc\"\n  BODY:\n    {\"message\":\"Hello, 你好\"}\n```\n\n\n[tcpdump]: http://www.tcpdump.org/\n[gRPC]: https://grpc.io/\n[AF_PACKET]: http://man7.org/linux/man-pages/man7/packet.7.html\n[protobuf]: https://developers.google.com/protocol-buffers/\n[gopacket]: https://github.com/google/gopacket\n[:path]: https://tools.ietf.org/html/rfc3986#section-3.3\n[BPF]: https://zh.wikipedia.org/wiki/BPF\n[PRI]: https://http2.github.io/http2-spec/#rfc.section.11.6\n[tls.Config]: https://godoc.org/crypto/tls#Config\n[key_log]: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format\n[http2]: https://godoc.org/golang.org/x/net/http2","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdyxushuai%2Fgrpcdump","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdyxushuai%2Fgrpcdump","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdyxushuai%2Fgrpcdump/lists"}