How To Setup HTTPS on Go Web Server

Photo by Andrew Neel on Unsplash

How To Setup HTTPS on Go Web Server

Overview

HTTPS (Hypertext Transfer Protocol Secure) is an extension of HTTP. It extends HTTP to give more security by implementing SSL/TLS to encrypt the connection between client and server. Because of that, HTTPS is often referred to as HTTP over SSL/TSL. HTTPS implementation on a web service makes the system more resilient to web attacks such as man-in-the-middle-attack. By default, HTTPS listen to port 443 instead of port 80 of HTTP.

Problem

Here is the code used to build a simple web server written in Go. This web server has only 1 endpoint and listens to port 8081.

package main

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

func main() {

    http.HandleFunc("/hi", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "{message: 'Hello Secure World'}")
    })

    log.Fatal(http.ListenAndServe(":8081", nil))

}

Let's analyze the packet on Wireshark to see how the packet is transmitted. As a testing ground, I will use the curl command to send HTTP GET requests to go web server.

curl http://localhost:8081/hi

Here is the screenshot of the packet capture from Wireshark. Screenshot_20220107_174144.png As you can see, the payload is clearly shown up at the packet capture. This is a serious issue as someone can tap into your connection and know what kind of data you sent and received.

Solution

Let's encrypt our connection using HTTPS. But first, we need to generate some files using this command:

go run $(go env GOROOT)/src/crypto/tls/generate_cert.go --host=localhost

In the go code, you need to change http.ListenAndServe to http.ListenAndServeTLS in order to use the https.

package main

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

func main() {

    http.HandleFunc("/hi", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "{message: 'Hello Secure World'}")
    })

    err := http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", nil)
    if err != nil {
        log.Fatal(err.Error())
    }
    log.Printf("Web server works")
}

Result

Test the following code using the curl command

# as we self-sign the certificate, our certificate can't be trusted
# worry not, the TLS still applies to our connection
curl -k https://localhost:8443/hi

This is the screenshot from Wireshark where we capture the packet.

image.png

As you can see, the connection now has been encrypted using TLS.

Thank you, I hope you find this article useful.

Did you find this article valuable?

Support Ekky Kharismadhany by becoming a sponsor. Any amount is appreciated!