Golang 实现多域名 HTTPS 反向代理的思考

2022-08-29 13:39:04 +08:00
 DollarKiller

我看现在关于 golang 反向代理的实现基本依靠的是 httputil.ReverseProxy :

import (
    "log"
    "net/http"
    "net/http/httputil"
    "net/url"
)

// NewProxy takes target host and creates a reverse proxy
// NewProxy 拿到 targetHost 后,创建一个反向代理
func NewProxy(targetHost string) (*httputil.ReverseProxy, error) {
    url, err := url.Parse(targetHost)
    if err != nil {
        return nil, err
    }

    return httputil.NewSingleHostReverseProxy(url), nil
}

// ProxyRequestHandler handles the http request using proxy
// ProxyRequestHandler 使用 proxy 处理请求
func ProxyRequestHandler(proxy *httputil.ReverseProxy) func( http.ResponseWriter, *http.Request) {
    return func(w http.ResponseWriter, r *http.Request) {
        proxy.ServeHTTP(w, r)
    }
}

func main() {
    // initialize a reverse proxy and pass the actual backend server url here
    // 初始化反向代理并传入真正后端服务的地址
    proxy, err := NewProxy("http://my-api-server.com")
    if err != nil {
        panic(err)
    }

    // handle all requests to your server using the proxy
    // 使用 proxy 处理所有请求到你的服务
    http.HandleFunc("/", ProxyRequestHandler(proxy))
    log.Fatal( http.ListenAndServe(":8080", nil))
}

上面的代码只实现了 监听一个端口 来实现特点网站的反向代码

怎么实现类似 nginx 监听一个端口 支持多个网站的反代实现呢 我想通过 r.URL.Host 针对不同来来源来进行不同的操作 实现了 HTTP 的 单端口多网站的代理实现

return func(w http.ResponseWriter, r *http.Request) {
		r.URL.Host
		proxy.ServeHTTP(w, r)
	}

但是 HTTPS 的怎么做了, 每个不同的域名都有不同的证书

log.Fatal( http.ListenAndServe(":8080", nil))
	
http.ListenAndServeTLS()
1051 次点击
所在节点    问与答
3 条回复
dzdh
2022-08-29 13:48:33 +08:00
前阵子刚研究过。

伪代码:

```
func main() {

tlsConfig := &tls.Config{
GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {

return tls.X509KeyPair(certBlockByte, keyBlockByte), nil
},
}

httpsSrv := http.Server{
Addr: ":443",
TLSConfig: tlsConfig,
}
httpSrv := http.Server{
Addr: ":80",
}
go httpSrv.ListenAndServe()
go httpsSrv.ListenAndServe()

}
```
dzdh
2022-08-29 13:50:47 +08:00
GetCertificate 部分通过接口也好,通过数据库、redis 都可,返回一个 tls.Certficiate 就可

proxy.ServeHTTP 的 request,在传入前,把 request.Host 置空,否则不走 r.URL.Host 直接走了 r.Host
DollarKiller
2022-08-29 13:56:50 +08:00
@dzdh 谢谢老师 太厉害了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/876179

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX