golang net/http库在发送http请求时会通过调用net下的Dialer建立TCP连接, net.Dialer 会在发起连接前执行通过ControlContext字段传入的一个函数, 我们可以通过这个函数获取ip、端口和网络名等信息。
示例代码:
package main
import (
"fmt"
"io/ioutil"
"net"
"net/http"
"syscall"
)
func customControl(network string, address string, conn syscall.RawConn) error {
fmt.Printf("%s,%s\n", network, address)
return nil
}
func main() {
dialer := &net.Dialer{
Control: customControl,
}
t := http.DefaultTransport.(*http.Transport).Clone()
t.DialContext = dialer.DialContext
c := &http.Client{
Transport: t,
}
resp, _ := c.Get("https://www.baidu.com")
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("%s\n", body)
}
我们可以再这个函数里记录每个http请求的实际ip地址,也可以在这里对请求IP做一些策略和检查,比如防范SSRF等等。