Joel Dare

How to Create an HTTPS (TLS) Server in Go

I wanted to create a Go program that runs over HTTPS. Lucky for me, the Go net/http module has built in support for TLS. The main magic happens in the ListenAndServeTLS function. Here’s the full code I ended up with and some additional instructions for getting the certificate setup and then initializing and building this app.

Template

Here’s a template for the the full Go program using TLS. I’ve saved this program as app.go.

package main

import (
	"fmt"
	"io"
	"net/http"
)

type application struct {
	config struct {
		port string
		path string
		cert string
		key  string
	}
}

func main() {
	// Setup some application data
	app := new(application)
	app.config.port = "9001"
	app.config.path = "./www"
	app.config.cert = "localhost.crt"
	app.config.key = "localhost.key"
	// Setup a file server to serve the www directory
	fileServer := http.FileServer(http.Dir(app.config.path))
	http.Handle("/", fileServer)
	// Routes
	http.HandleFunc("/hello", app.helloHandler)
	// Start a server
	fmt.Printf("Server started on port %s\n", app.config.port)
	if err := http.ListenAndServeTLS(":"+app.config.port, app.config.cert, app.config.key, nil); err != nil {
		fmt.Println(err)
	}
}

func (app *application) helloHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("content-type", "text/html")
	io.WriteString(w, "Hello World.\n")
}

Generate the Certificates

Before we can use this code we need a certificate. Run the following command to generate a private key file and a certificate signing request.

openssl req  -new  -newkey rsa:2048  -nodes  -keyout localhost.key  -out localhost.csr

Now that we have those, we need to run the following command to generate the certificate based on them.

openssl  x509  -req  -days 365  -in localhost.csr  -signkey localhost.key  -out localhost.crt

Initialize the Go Program

Before you can compile the program you’ll need to generate the mod file for it. You do that by running the following command in the root directory of your project.

go mod init example/app

Build and Run

Finally, you can build and run your Go TLS Server.

go build
./app