No, you do not need to use Apache/Nginx, Go handles TLS just fine.
Check http.ListenAndServeTLS
Example:
➜ sudo letsencrypt certonly --standalone --agree-tos --email you@email.com -d domain1.com [-d domain2.com, etc..]
➜ sudo cat /etc/letsencrypt/archive/domain1.com/fullchain1.pem > cert.pem
➜ sudo cat /etc/letsencrypt/archive/domain1.com/privkey1.pem > key.pem
➜ cat main.go
import (
"log"
"net/http"
)
func handler(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte("This is an example server.
"))
}
func main() {
http.HandleFunc("/", handler)
log.Printf("About to listen on 10443. Go to https://domain1.com:10443/")
log.Fatal(http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil))
}
Note that if you want your go server to listen on port 443 (default https port), you will either have to run it as root or use systemd to pass it the port.
Example of running on port 443:
Change the code to log.Fatal(http.ListenAndServeTLS(":443", "cert.pem", "key.pem", nil))
go build
sudo ./your-package-name
- or if you don't want to run as root, you will have to chown cert.pem/key.pem as your user then run
setcap cap_net_bind_service=+ep your-package-name
then you will be able to listen on port 443/80 as a user.
More details about using setcap: https://wiki.apache.org/httpd/NonRootPortBinding