【问题标题】:How can I fix a TLS handshake error using Go on Heroku?如何在 Heroku 上使用 Go 修复 TLS 握手错误?
【发布时间】:2018-09-22 22:27:51
【问题描述】:

我有一个简单的代理,它在同一个端口上侦听 HTTP 和 HTTPS 连接。

但是我看到奇怪的 TLS 握手错误,似乎是由 Heroku 路由器引起的:

heroku[router]: sock=backend at=error code=H18 desc="Server Request Interrupted" method=GET path="/favicon.ico" host=banana.camp request_id=f56144c8-e480-476a-90b8-429b490f1ff5 fwd="24.67.185.77" dyno=web.1 connect=0ms service=1ms status=503 bytes=7 protocol=https
http: TLS handshake error from 10.81.159.108:19578: tls: first record does not look like a TLS handshake
http: TLS handshake error from 172.17.117.25:36924: EOF

有没有办法修复或忽略它们?非常感谢任何线索。

谢谢!

func InitServer() error {
    m := autocert.Manager{
        Cache:  autocert.DirCache(*StorageDir),
        Prompt: autocert.AcceptTOS,
        HostPolicy: func(ctx context.Context, host string) error {
            return nil
        },
    }

    errchan := make(chan error)

    s := &http.Server{
        Addr:      ":" + os.Getenv("PORT"),
        TLSConfig: &tls.Config{GetCertificate: m.GetCertificate},
        Handler:   ServeHTTP(),
    }

    go (func() {
        errchan <- http.ListenAndServe(":"+os.Getenv("PORT"), m.HTTPHandler(nil))
    })()

    errchan <- s.ListenAndServeTLS("", "")

    return <-errchan
}

func ServeHTTP() http.Handler {
    return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
        if upstreams, ok := Hosts[req.Host]; ok {
            forwarder, _ := forward.New(forward.PassHostHeader(true))
            loadbalancer, _ := roundrobin.New(forwarder)

            for _, upstream := range upstreams {
                if url, err := url.Parse(upstream); err == nil {
                    loadbalancer.UpsertServer(url)
                } else {
                    log.Fatal("InitHostsList: ", err)
                }
            }

            loadbalancer.ServeHTTP(res, req)

            return
        }

        http.Error(res, "The request service couldn't be found here", http.StatusNotImplemented)
    })
}

【问题讨论】:

    标签: ssl go heroku lets-encrypt


    【解决方案1】:

    TLS 终止由 Heroku 路由器处理,无法在应用级别完成¯_(ツ)_/¯

    【讨论】:

      【解决方案2】:

      您不能在同一个端口上同时收听 http 和 https,这些日志错误是您有 http 客户端尝试连接到应用程序时的情况。

      【讨论】:

      • 当我只收听 TLS 时,我得到了同样的错误。另外,HTTP 监听器在一个 goroutine 中,应该可以解决它,不是吗?
      【解决方案3】:

      默认情况下,golang http 服务器只支持在给定端口上监听 http 或 https 流量(不能同时监听)。监听https流量需要使用http.ListenAndServeTLS

      如果您在仅配置一个点同时引导 http 和 https 流量,您最终会看到错误。

      有第三方解决方案(如cmux)支持在同一端口上托管安全和不安全的流量。不像分离端口那么容易,但如果你想这样做,它们在 README 中有一个示例配置。

      【讨论】:

        猜你喜欢
        • 2017-01-17
        • 2016-03-21
        • 2014-12-09
        • 1970-01-01
        • 2017-01-25
        • 2019-06-07
        • 1970-01-01
        • 2021-06-16
        • 2021-11-13
        相关资源
        最近更新 更多