几年前写过个工具 gospy, 用于从旁路 dump 一个 golang 进程的 runtime 信息(包括 goroutine, memory 等), 大致原理见以前的文章.
基本功能能用, 但没继续做下去, 除了没时间外, 其他还有几个问题:
不支持 MacOS (主要是没搞懂 MacOS 下怎么读取进程内存). DWARF 解析写的过于繁琐, golang 版本更新时, 解析逻辑很难调整. 对写 UI (包括 terminal UI 和前端) 实在没兴趣, 不写又没法暴露功能, 也懒得去做通过 http 接口暴露数据. 前阵子试了下通过 aider 来写代码, 效果非常惊艳, 对我来说, …
从 0.10.0 版本开始给 snet 加了 stats api 来暴露内部的一些统计数据.
设置 "enable-stats": true 开启, 默认监听 8810 端口, curl http://localhost:8810/stats
{ "Uptime": "26m42s", "Total": { "RxSize": 161539743, "TxSize": 1960171 }, "Hosts": [ { "Host": …
snet: 0.5 ~ 0.6.1, 整理从上一篇以来的一些更新.
新增选项 proxy-scope, 默认 bypassCN, 可选 global. bypassCN 会做国内外分流, global 直接让所有流量去往国外.
host-map, 为域名指定 ip. 之前在测试一个功能的时候需要在内网让手机对某个域名的解析切换到我的测试 ip 上, 坑爹的是公司的路由器竟然没这功能, 索性在 snet 里写了这个功能, 让我的台式机发射 wifi, 手机连上来, snet 的 mode 切换成 router, listen-host 改为 0.0.0.0 就好了.
block-hosts, 因 …
前文讲了下 gospy 的大致用法, 这篇记录具体实现和过程中碰到的一些问题.
原理 要从外部获取 golang 进程的 runtime 信息, 需要做得是从进程的 binary 中的 debug 信息里 parse 出需要的一些变量的虚拟内存地址, 读取目标进程的内存, 得到相应的数据, 将两者映射起来就好了.只支持了 linux 上的 ELF 格式 binary, debug 信息是 go 在编译时候弄进去的, 格式是通用的 DWARF.
ELF 和 DWARF 格式本身不细究(汗, 文档几百页也实在看不动), go 标准库里自带相应的 parser: debug/elf, …
go 自带的 profiling 工具很强大(pprof, trace, GODEBUG …), 但有时我还是想不修改目标进程的源码获取它的一些 runtime 信息, 最近研究了一下 py-spy 和 delve, 发现还是可实现的, 就做了个小东西gospy.
用法 目前就两个命令: gospy summary 和 gospy top
sudo ./gospy summary --pid 1234, 可以 dump 目标进程的一些信息和当前活动 goroutine 正在执行的函数信息, 比如对一个 prometheus 进程做一次 snapshot:
bin: …
这两天得了空, 让 snet 支持了下 MacOS.
snet 的大致原理是通过系统防火墙的流量重定向功能,将所有去往国外的流量导到 snet 监听的端口, 在程序内部 将流量传递给上游的 proxy server(ss, http), 拿到响应后再回给客户端.
实现关键是要在 snet 内部获取到流量的原目标地址, 因为重定向之后 tcp connnection 的目标地址变成了 snet 监听 的地址.
Linux 上的实现,以前讲过: https://blog.monsterxx03.com/2019/03/31/snet-transparent-ss-proxy-on-linux/ 是 …
完成 SNET 初版后又做了些后续更新, 记录一点.
支持 http tunnel 配置文件里增加一个 proxy-type 选项, 默认为 ss, 可改成 http, 这样可以将 支持 http tunnel 的代理服务器作为 upstream(例如 squid). 填上 http-proxy- 开头 的选项就行.
实现上 client 端要对接 http tunnel 非常简单:
client 发送请求: Connect tgt-host:tgt-port HTTP/1.1 server response: HTTP/1.1 200, 即表示 server 端支持 http tunnel …
日常使用 Linux 工作, Linux 下实现全局透明代理可以用 iptables + ss-redir, 要有比较好的上网体验还需要 ChinaDNS 配合 dnsmasq, 这一整套在路由器上搞一遍就算了, 在本地太麻烦了. 仔细想想这几个加起来的功能实现起来也并不复杂, 前阵子就写了个小东西, 用一个进程完成全局透明代理 + ChinaDNS + 国内外分流: https://github.com/monsterxx03/snet
目前的限制:
不支持 ipv6 只支持 tcp (因为我的测试服务器不支持 udp, 以后再加上吧) 上游 server 只支持 ss 目的是一个进程 + …
A few notes taken when reading