I'm reading https://www.kaihag.com/https-and-go/ and bought an SSL certificate from Comodo which they emailed me a .zip
file. All of the files I have so far look like this
csr.pem
private-key.pem
website.com.crt
website.com.ca-bundle
website.com.zip
The above website wants me to concatenate 3 .pem
files which I don't have. Incidentally what is the reason the .pem
files need to concatenated? Using the above files which haven't been modified, how can https be set up on a golang webserver?
Use https://golang.org/pkg/net/http/#ListenAndServeTLS
http.HandleFunc("/", handler)
log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/")
err := http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil)
log.Fatal(err)
This isn't really a go question, but the intermediate certs are required because computers only store root certs. By concatenating them you put them all in one file so the browser gets all certs - this is a required step otherwise your server will fail on certain devices. Your cert provider will provide instructions for doing this. For go you need one cert file and one private key file.
https://kb.wisc.edu/page.php?id=18923
Here are some instructions for comodo for combining the certs (doesn't matter which server is used, the process is the same):
You need http.ListenAndServeTLS
package main
import (
// "fmt"
// "io"
"net/http"
"log"
)
func HelloServer(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte("This is an example server.
"))
// fmt.Fprintf(w, "This is an example server.
")
// io.WriteString(w, "This is an example server.
")
}
func main() {
http.HandleFunc("/hello", HelloServer)
err := http.ListenAndServeTLS(":443", "server.crt", "server.key", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
Here’s a snippet: https://gist.github.com/denji/12b3a568f092ab951456
The library https://github.com/adrianosela/sslmgr abstracts away the whole concept of keys and certificates. All you need is for the server to be reachable by the hostname (i.e. your DNS must point yourdomain.com to your-public-ip). You can even disable SSL for local development as follows:
ss, err := sslmgr.NewServer(sslmgr.ServerConfig{
Hostnames: []string{os.Getenv("yourdomain.com")},
Handler: h,
ServeSSLFunc: func() bool {
return strings.ToLower(os.Getenv("PROD")) == "true"
},
})
if err != nil {
log.Fatal(err)
}
ss.ListenAndServe()
Here is my finding and I would like to share because it took me a few hours as all available installation guides were for Nginx and Apache HTTP configurations, not for the Golang Web Server.
Environments:
Issue:
Solution:
The solution is to concatenate the following certificates by using a text editor and name it as you'd like. I saved it as "my_domain.txt".
Then run it like this,
router.RunTLS(":"+os.Getenv("PORT"), "../my_domain.txt", "../my_private_key.txt")
Hope it helped!