Как я могу исправить ошибку рукопожатия TLS, используя Go на Heroku? - PullRequest
0 голосов
/ 23 сентября 2018

У меня есть простой прокси-сервер, который прослушивает соединения 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)
    })
}

Ответы [ 3 ]

0 голосов
/ 23 сентября 2018

По умолчанию http-сервер golang поддерживает прослушивание только трафика http или https на заданном порту (но не на обоих).Для прослушивания трафика https вам необходимо использовать http.ListenAndServeTLS.

Если вы направляете трафик http и https в точку, настроенную только для одного, вы в конечном итоге увидите ошибки.

Существуют сторонние решения (например, cmux ), которые поддерживают размещение безопасного и незащищенного трафика на одном и том же порту.Не так просто, как разделить порты, но если это то, что вы хотите сделать, у них есть пример конфигурации в README.

0 голосов
/ 23 сентября 2018

Завершение TLS обрабатывается маршрутизатором Heroku и не может быть выполнено на уровне приложения ¯_ (ツ) _ / ¯

0 голосов
/ 23 сентября 2018

Вы не можете прослушивать http и https на одном и том же порту, и эти ошибки журнала являются случаями, когда ваши http-клиенты пытаются подключиться к приложению.

...