强制代理服务器将域名解析为自定义IP。

huangapple go评论106阅读模式
英文:

Force proxy server to resolve a domain to a custom Ip

问题

我有一个在本地运行的goproxy服务器(github.com/elazarl/goproxy)。

proxy := goproxy.NewProxyHttpServer()
http.ListenAndServe(":4242", proxy)

我通过它代理我的请求,对于某些域名,我希望将它们解析为自定义IP,适用于HTTP和HTTPS请求。

我尝试了以下代码:

proxy.OnRequest().HandleConnectFunc(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
    // 允许特定主机的连接
    if host == "mydomain.com" {
        host = "myip:443"
        ctx.Req.URL.Host = host
        ctx.Req.Host = host
    }
    return goproxy.MitmConnect, host
})

这会导致使用curl时出现以下错误(不使用--insecure标志):

curl failed to verify the legitimacy of the server and therefore could not 
establish a secure connection to it. To learn more about this situation and 
how to fix it, please visit the web page mentioned above.

并且在浏览器中无法工作。

是否有其他方法可以使其工作?

编辑1:
尝试对于一个由我的证书存储信任的服务器,浏览器中显示如下:
强制代理服务器将域名解析为自定义IP。

编辑2:
尝试修改net.DefaultResolver并将DNS解析器更改为自定义服务器:

net.DefaultResolver = &net.Resolver{
    PreferGo: true,
    Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
        // 对于其他主机使用默认地址解析
        fmt.Println("domaIN", network, address)
        return (&net.Dialer{}).DialContext(ctx, network, "127.0.0.1:53")
    },
}

但这仅适用于HTTP请求。我可以更改代理的传输的DialContext,但这也仅适用于HTTP请求,而DialTLSContext对于代理请求不起作用。

我想知道是否可以使其适用于代理的HTTPS请求,或者修改/etc/hosts是我唯一的选择。

英文:

I have a goproxy (github.com/elazarl/goproxy) server running locally

proxy := goproxy.NewProxyHttpServer()
http.ListenAndServe(":4242", proxy)

I'm proxying my requests through it, for some domains i'd like to resolve them to a custom IP for both http & https requests

I tried

proxy.OnRequest().HandleConnectFunc(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
	// Allow the connection to proceed for specific hosts
	if host == "mydomain.com" {
		host = "myip:443"
		ctx.Req.URL.Host = host
		ctx.Req.Host = host
	}
	return goproxy.MitmConnect, host
})

which would give me this error with curl (without the --insecure flag)

curl failed to verify the legitimacy of the server and therefore could not 
establish a secure connection to it. To learn more about this situation and 
how to fix it, please visit the web page mentioned above.

and not work with browser.

Any other approaches to make this work

Edit 1.
Tried this for a server whose certificate would be trusted by my certificate store, got this in browser
强制代理服务器将域名解析为自定义IP。

Edit 2.
Tried modifying net.DefaultResolver and change dns resolver to a custom server

net.DefaultResolver = &net.Resolver{
	PreferGo: true,
	Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
		// Use the default address resolution for other hosts
		fmt.Println("domaIN", network, address)
		return (&net.Dialer{}).DialContext(ctx, network, "127.0.0.1:53")
	},
}

but this also only works for http requests
I can change the DialContext of the proxy's transport but that too only would work for http requests & DialTLSContext doesn't work for proxied requests.

I would like to know if i can make this work for proxied https requests too, or is a change to /etc/hosts is my only option.

答案1

得分: 1

您在标题中提到的问题并不是您所说的,即设置另一个目标IP地址。相反,您遇到的问题是主机返回的证书无法被客户端验证,可能是因为它不是由客户端信任的CA颁发的。

这是一个需要在每个客户端上解决的问题(信任颁发CA的CA)或在服务器上解决的问题(使用客户端信任的CA颁发的证书),而不能在代理服务器上解决。否则,中间人攻击将变得容易。

英文:

You don't have the problem claimed in the title, i.e. set another target IP address. Instead you have the problem that the certificate this host then returns can not be validated by the client - likely because it is not issued by a CA trusted by the client.

This is a problem which need to be solved at each client (trust the CA which issued the CA) or on the server (use a certificate issued by a CA trusted by the client) but cannot be solved at the proxy. Otherwise man in the middle attacks would be easy.

答案2

得分: 0

对于https请求,我通过向代理添加https处理程序使其正常工作。

proxy.OnRequest().HandleConnectFunc(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
	
	if host == "mycustomdomain.com:443" {
		newIp := fmt.Sprintf("%v:443", myCustomIP)

		host = newIp
		ctx.Req.URL.Host = newIp
		ctx.Req.Host = newIp
	}

	return goproxy.OkConnect, host
})
英文:

For https requests I made it work by adding a https handler to the proxy

proxy.OnRequest().HandleConnectFunc(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
	
	if host == "mycustomdomain.com:443" {
		newIp := fmt.Sprintf("%v:443", myCustomIP)

		host = newIp
		ctx.Req.URL.Host = newIp
		ctx.Req.Host = newIp
	}

	return goproxy.OkConnect, host
})

huangapple
  • 本文由 发表于 2023年6月14日 00:00:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76466755.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定