Golang ListenAndServeTLS returns data when not usi

2019-04-05 11:38发布

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):

using http

Question: Why is there a question mark?

标签: http ssl https go
3条回答
甜甜的少女心
2楼-- · 2019-04-05 12:07

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."

查看更多
ら.Afraid
3楼-- · 2019-04-05 12:14

If at all still relevent:

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

查看更多
Ridiculous、
4楼-- · 2019-04-05 12:24

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) 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 (
"net/http"
"log"
)
func redirect(w http.ResponseWriter, req *http.Request) {
 // remove/add not default ports from 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() {
 //define a variable for the FileServer directory in this case ./static/
 var fs = http.FileServer(http.Dir("static"))
 //express the handler function
 http.Handle("/", fs)
 //We should redirect requests on port 80
 go http.ListenAndServe(":80", http.HandlerFunc(redirect))
 //finally we Listen for requests and serve them up on a specific port
 http.ListenAndServeTLS(":443", "fullchain.pem", "privkey.pem", nil)

 }
查看更多
登录 后发表回答