package main import ( "flag" "io" "log" "net" "net/http" "os" "syscall" ) var ( uri = flag.String("target", "https://google.com", "target url") netInterface = flag.String("interface", "eth0", "") ) func main() { flag.Parse() client := &http.Client{ Transport: Transport(*netInterface), } rc, err := client.Get(*uri) if err != nil { log.Fatal(err) } defer rc.Body.Close() if _, err := io.Copy(os.Stdout, rc.Body); err != nil { log.Fatal(err) } } func Transport(interfaceName string) *http.Transport { return &http.Transport{ DialContext: (&net.Dialer{ Control: func(network, address string, c syscall.RawConn) (err error) { err1 := c.Control(func(fd uintptr) { // need setcap cap_net_raw+ep err = syscall.SetsockoptString(int(fd), syscall.SOL_SOCKET, syscall.SO_BINDTODEVICE, interfaceName) if err != nil { return } }) if err != nil { return err } return err1 }, }).DialContext, } }