Golang的ListenAndServeTLS在浏览器中不使用https时返回数据。

huangapple go评论96阅读模式
英文:

Golang ListenAndServeTLS returns data when not using https in the browser

问题

以下是我的tls后端代码:

package main

import (
    "fmt"
    "net/http"
)

const (
    PORT       = ":8443"
    PRIV_KEY   = "./private_key"
    PUBLIC_KEY = "./public_key"
)

func rootHander(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Nobody should read this.")
}

func main() {
    http.HandleFunc("/", rootHander)
    err := http.ListenAndServeTLS(PORT, PUBLIC_KEY, PRIV_KEY, nil)
    if err != nil {
        fmt.Printf("main(): %s\n", err)
    }
}

这些密钥是使用以下两行生成的:

openssl genrsa -out private_key 2048
openssl req -new -x509 -key private_key -out public_key -days 365

当我启动tls服务器,并使用浏览器访问网站(https://example.com:8443),我得到了预期的结果,在忽略浏览器警告之后

Nobody should read this.

到目前为止一切都很好。

现在,当我将浏览器指向http://example.com:8443(注意使用的是http,而不是https),我在Firfox中得到了以下结果(Chrome也是一样的,但是会下载网站):

Golang的ListenAndServeTLS在浏览器中不使用https时返回数据。

问题:为什么会有一个问号?

英文:

The following is my tls backend:

package main

import (
    "fmt"
    "net/http"
)

const (
    PORT       = ":8443"
    PRIV_KEY   = "./private_key"
    PUBLIC_KEY = "./public_key"
)

func rootHander(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Nobody should read this.")
}

func main() {
    http.HandleFunc("/", rootHander)
    err := http.ListenAndServeTLS(PORT, PUBLIC_KEY, PRIV_KEY, nil)
    if err != nil {
        fmt.Printf("main(): %s\n", err)
    }
}

The keys are generated using these two lines:

openssl genrsa -out private_key 2048
openssl req -new -x509 -key private_key -out public_key -days 365

When I start the tls server, and visit the site with a browser (https://example.com:8443) I get the expected result, after ignoring the browser warning:

Nobody should read this.

So far everything is cool.

Now, when I point my browser to http://example.com:8443 (notice that http is used, not https) I get the following result for Firfox (Chrome does the same, but downloading the site):

Golang的ListenAndServeTLS在浏览器中不使用https时返回数据。

Question: Why is there a question mark?

答案1

得分: 8

如果将输出导入到od中,curl -k -3 http://localhost:8443 | od -A n -t x1,你会得到以下字节序列 15 03 01 00 02 02 0a,这是由浏览器渲染/处理的。

根据https://code.google.com/p/go/issues/detail?id=2253,这代表了TLS的意思是“我不明白你说的话”。

英文:

If you pipe the output into od, curl -k -3 http://localhost:8443 | od -A n -t x1, you get the following sequence of bytes 15 03 01 00 02 02 0a which is rendered/handled by the browser.

Which, according to https://code.google.com/p/go/issues/detail?id=2253, is TLS for "I didn't understand what you said."

答案2

得分: 4

如果仍然相关的话:

http.ListenAndServeTLS(...)接受证书私钥,而不是公钥私钥

英文:

If at all still relevent:

http.ListenAndServeTLS(...) takes certificate and private key not public & private key.

答案3

得分: 2

以下是将请求从端口80重定向到443并使用类似于lets encrypt的CA提供TLS证书的一些代码。我知道使用lets encrypt时,您需要引用生成的fullchain.pem文件和privkey.pem文件。

自签名的最大问题是在生产环境中不太可行。在使用golang时,我们需要非常具体地配置我们的应用程序,因此在准备启动时,正确附加TLS证书这样的简单事项是一个重要的主题。

以下是我实际用于启动静态网站的一些简单代码:

package main

import (
    "net/http"
    "log"
)

func redirect(w http.ResponseWriter, req *http.Request) {
    // 从req.Host中删除/添加非默认端口
    target := "https://" + req.Host + req.URL.Path
    if len(req.URL.RawQuery) > 0 {
        target += "?" + req.URL.RawQuery
    }
    log.Printf("redirect to: %s", target)
    http.Redirect(w, req, target, http.StatusTemporaryRedirect)
}

func main() {
    // 定义一个变量,用于指定FileServer目录,这里是./static/
    var fs = http.FileServer(http.Dir("static"))
    // 表达处理函数
    http.Handle("/", fs)
    // 我们应该重定向端口80上的请求
    go http.ListenAndServe(":80", http.HandlerFunc(redirect))
    // 最后,我们监听请求并在特定端口上提供服务
    http.ListenAndServeTLS(":443", "fullchain.pem", "privkey.pem", nil)
}

<details>
<summary>英文:</summary>

Here is some code to redirect requests on port 80 to 443 and to serve up tls certificates using a CA like lets encrypt. I know that with lets encrypt ([letsencrypt.org][1]) you want to reference the resulting fullchain.pem file as well as the privkey.pem.

The biggest problem with self signing is that it wont be very viable in production. With golang we really configure our applications quite specifically so something simple like attaching tls certs properly is an important topic when we are ready to launch.


here some simple code I have actually used to launch a static site:


    package main
    import (
    &quot;net/http&quot;
    &quot;log&quot;
    )
    func redirect(w http.ResponseWriter, req *http.Request) {
     // remove/add not default ports from req.Host
     target := &quot;https://&quot; + req.Host + req.URL.Path
     if len(req.URL.RawQuery) &gt; 0 {
         target += &quot;?&quot; + req.URL.RawQuery
     }
     log.Printf(&quot;redirect to: %s&quot;, target)
     http.Redirect(w, req, target,
             http.StatusTemporaryRedirect)
     }


    func main() {
     //define a variable for the FileServer directory in this case ./static/
     var fs = http.FileServer(http.Dir(&quot;static&quot;))
     //express the handler function
     http.Handle(&quot;/&quot;, fs)
     //We should redirect requests on port 80
     go http.ListenAndServe(&quot;:80&quot;, http.HandlerFunc(redirect))
     //finally we Listen for requests and serve them up on a specific port
     http.ListenAndServeTLS(&quot;:443&quot;, &quot;fullchain.pem&quot;, &quot;privkey.pem&quot;, nil)

     }


  [1]: http://letsencrypt.org

</details>



huangapple
  • 本文由 发表于 2014年5月6日 19:56:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/23494082.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定