Заставить прокси-сервер преобразовать домен в пользовательский 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) {
// 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
})
что выдаст мне эту ошибку с помощью 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. Попробовал это для сервера, сертификату которого будет доверять мое хранилище сертификатов, получил это в браузере.
Изменить 2. Попробовал изменить net.DefaultResolver и изменить преобразователь DNS на собственный сервер.
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")
},
}
но это также работает только для http-запросов. Я могу изменить DialContext транспорта прокси-сервера, но это тоже будет работать только для http-запросов, а DialTLSContext не работает для прокси-запросов.
Я хотел бы знать, смогу ли я выполнить эту работу и для прокси-запросов https, или изменение /etc/hosts - мой единственный вариант.
2 ответа
Для запросов 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
})
У вас нет заявленной в заголовке проблемы, т.е. установлен другой целевой IP-адрес. Вместо этого у вас возникает проблема: сертификат, который затем возвращает этот хост, не может быть проверен клиентом - вероятно, потому, что он не выдан центром сертификации, которому доверяет клиент.
Это проблема, которую необходимо решить на каждом клиенте (доверять ЦС, выдавшему ЦС) или на сервере (использовать сертификат, выданный ЦС, которому доверяет клиент), но не решить на прокси-сервере. В противном случае атака человека посередине была бы легкой задачей.