编译getaddrinfo钩子 LD_PRELOAD加载 钩Python程序 钩Go程序 GODEBUG=netdns=cgo
这样的钩子技术可以应用在很多其它情况下.
并不会因为钩子的源代码是C, 就只能钩C写的程序 (curl 是 C写的).
编译钩子请参考上一篇, 略.
钩子文件是 /root/hook_getaddrinfo.so
钩 Python 程序
感谢 Debian中文群的群友的 python 代码 https://t.me/c/1039975886/766756
python3 -c 'import sys, socket; [print(res) for res in socket.getaddrinfo(sys.argv[1], int(sys.argv[2] if len(sys.argv) > 2 else 80))]' api.myip.la
上面的代码是python调用系统 getaddrinfo. 我们在开头加上钩子, 得到
LD_PRELOAD=/root/hook_getaddrinfo.so python3 -c 'import sys, socket; [print(res) for res in socket.getaddrinfo(sys.argv[1], int(sys.argv[2] if len(sys.argv) > 2 else 80))]' api.myip.la
日志如下
钩 Go 程序
让GPT写一个Go程序, 实现简单的功能:
访问一个域名, 打印HTTP结果. 看起来就像curl
代码如下, gurl.go
package mainimport ("fmt""io/ioutil""log""net/http""os""strings" // 导入 strings 包用于字符串操作"time")func main() {// --- 1. 处理命令行参数 ---if len(os.Args) < 2 {log.Fatalf("❌ 缺少参数。用法: gurl <URL/Domain>")}url := os.Args[1]// --- 2. 检查并补全协议头(核心修改部分) ---// 检查 URL 是否以 "http://" 或 "https://" 开头if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {// 如果没有协议头,默认加上 "http://"// 注意:如果访问的网站强制使用 HTTPS,这里可能需要手动改为 "https://"url = "http://" + url}// 3. 创建 HTTP 客户端client := http.Client{Timeout: time.Second * 10, // 设置 10 秒的请求超时}// 4. 发送 GET 请求resp, err := client.Get(url)if err != nil {// 如果请求失败(例如网络错误、DNS 解析失败等)log.Fatalf("❌ 发送请求失败: %v", err)}// 5. 确保在函数结束时关闭响应体defer resp.Body.Close()// 6. 检查 HTTP 状态码if resp.StatusCode != http.StatusOK {log.Fatalf("⚠️ 访问失败,状态码: %d %s", resp.StatusCode, resp.Status)}// 7. 读取响应体内容body, err := ioutil.ReadAll(resp.Body)if err != nil {log.Fatalf("❌ 读取响应体失败: %v", err)}// 8. 打印结果fmt.Println(string(body))}
在vps上编译一下
go build gurl.go
得到可执行文件 gurl
简单测试一下, 功能正常
加上钩子测试
LD_PRELOAD=/root/hook_getaddrinfo.so ./gurl api.myip.la
奇怪, 结果中没有钩子的打印.
一开始我还以为是钩子的 .so 文件名写错了还是目录搞错了还是用户没权限,... 各种查了半天
最后去问GPT, 原来 Go 的函数底层不一定使用系统的 getaddrinfo 接口. 默认是调用Go自己的DNS解析实现.
如果要指定使用系统的 getaddrinfo, 需要设置环境变量 GODEBUG=netdns=cgo
也就是这样
GODEBUG=netdns=cgo LD_PRELOAD=/root/hook_getaddrinfo.so ./gurl api.myip.la
* 上面这是1整行.
结果有钩子的打印了, 而且 gai.conf 也确实能控制 IPv4 / IPv6





评论
发表评论