设置 Let's encrypt with Go - 握手错误

Posted

技术标签:

【中文标题】设置 Let\'s encrypt with Go - 握手错误【英文标题】:Setting up Let's encrypt with Go - handshake errors设置 Let's encrypt with Go - 握手错误 【发布时间】:2017-08-26 22:59:19 【问题描述】:

我正在尝试在用 Go 编写的负载均衡器上设置 let's encrypt,我尝试了自动和手动设置,但总是出错。

该域正确指向我们的服务器(Digital Ocean),我什至可以从浏览器打开该站点而不会出现错误,并且 ssl 检查报告此域上没有错误。事实是,当我从 CLI 在服务器上运行 Go 可执行文件时,我反复收到错误。

    自动(acme/autocert)设置:

服务器代码是,证书和密钥是在服务器启动后我第一次从浏览器查看域时创建的:

    go func() 
        log.Printf("Staring HTTP service on %s ...", ":80")

        http.HandleFunc("/*", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) 
            http.Redirect(w, r, "https://" + app.Cfg.S_HOST + ":443" + r.RequestURI, http.StatusMovedPermanently)
        ))

        if err := http.ListenAndServe(":80", nil); err != nil 
            errs <- err
        

    ()



    log.Printf("Staring HTTPS service on %s ...", ":443")

    http.HandleFunc("/hello", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) 
        w.Header().Set("Content-Type", "text/plain")
        w.Write([]byte("This is an example server.\n"))
    ))


    certManager := autocert.Manager
        Prompt:     autocert.AcceptTOS,
        HostPolicy: autocert.HostWhitelist(app.Cfg.S_HOST), //your domain here
        Cache:      autocert.DirCache("certs"), //folder for storing certificates
    

    server := &http.Server
        Addr: ":443",
        TLSConfig: &tls.Config
            ServerName: app.Cfg.S_HOST,
            GetCertificate: certManager.GetCertificate,
        ,
    

    if err := server.ListenAndServeTLS("", ""); err != nil 
        print(err.Error())
     //key and cert are comming from Let's Encrypt

我收到这些错误:

    http: 来自 (ip):59451 的 TLS 握手错误:读取 tcp (myserver IP):443->(ip):59451: 读取:连接被对等方重置

    hello.ServerName empty:2017/04/01 17:14:38 http:来自 (ip):58193 的 TLS 握手错误:acme/autocert:缺少服务器名称

    http:来自 (ip):45822 的 TLS 握手错误:acme/autocert:主机未配置

    http:来自 (ip):58440 的 TLS 握手错误:EOF

然后我尝试手动(成功)创建证书并简单地使用该代码,但我一次又一次地收到错误:

服务器代码是:

    go func() 
        log.Printf("Staring HTTP service on %s ...", ":80")

        http.HandleFunc("/*", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) 
            http.Redirect(w, r, "https://" + app.Cfg.S_HOST + ":443" + r.RequestURI, http.StatusMovedPermanently)
        ))

        if err := http.ListenAndServe(":80", nil); err != nil 
            errs <- err
        

    ()



    log.Printf("Staring HTTPS service on %s ...", ":443")

    http.HandleFunc("/hello", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) 
        w.Header().Set("Content-Type", "text/plain")
        w.Write([]byte("This is an example server.\n"))
    ))


    // ssl["cert"] and ssl["key"] are the cert and key path (letsencrypt/live...)
    if err := http.ListenAndServeTLS(sslAddr, ssl["cert"], ssl["key"], nil); err != nil 
        errs <- err
    

错误:

    http2:服务器:从客户端 (ip) 读取前言时出错:10319:伪造 问候“POST / HTTP/1.1\r\nHost: 4”

    http:来自 (ip):10322 的 TLS 握手错误:EOF

    http:来自 (ip):13504 的 TLS 握手错误:读取 tcp(我的服务器 ip):443->(ip):13504:读取:对等方重置连接

    http2:服务器:从客户端(ip)读取前言时出错:9672:等待客户端前言超时

有人可以帮帮我吗?谢谢

【问题讨论】:

如果你在开放的互联网上有一个服务器,你就会收到损坏和格式错误的 TLS 请求。您是否遇到过您自己的任何客户的错误? 似乎没有,我只是尝试从 chrome 刷新页面,但它似乎没有触发任何错误......无论如何我还是得到了很多,5-20 x 分钟...... 您是否尝试过运行***.com/a/40494806/1465640 中的代码并只是更新您的域信息?并且您确定您正在访问端口 443 上的服务器 @Pylinux 是的!我基本上尝试了任何可能的配置,只有 443、443 + 80、80 重定向到 443,所有这些都使用 autocert 以及手动创建的证书。该网站正常运行,我的实际配置获得了 A+ 评级......我的客户工作得很好,没有错误,而且我还在 safari 和 chrome 上获得了“安全”徽标。我只是不断收到来自未知 IP 的错误和错误...我希望至少能够停止日志,反正我觉得很奇怪,我的意思是每分钟 30 个错误请求??? Aaaa,所以它可以工作,但是您从某些 IP 得到错误,可能是老客户试图访问您的网站吗? Golang 仅支持新的安全加密协议:github.com/golang/go/issues/3930 【参考方案1】:

正如 JimB 和其他人在 cmets 中所说,这可能是错误请求的结果。使用https://www.ssllabs.com/ssltest/ 测试站点的 https 配置时,将记录无效请求。良好的测试分数可以让您确信日志消息是良性的并且可以安全地忽略。

此外,acme/autocert 软件包正在迅速发展(2018 年 1 月),请检查您的版本是否是最新的。

【讨论】:

以上是关于设置 Let's encrypt with Go - 握手错误的主要内容,如果未能解决你的问题,请参考以下文章

带有 Let's Encrypt 的 Google App Engine SSL“无法插入”

未能续订 Let's Encrypt SSL

如何为 Service Fabric 配置 Let's Encrypt 证书?

Java 是不是支持 Let's Encrypt 证书?

如何在没有交互的情况下安装 Certbot (Let's Encrypt)?

在 Docker 映像中创建 Let's Encrypt 证书和 Certbot