Step 1: Create a Certificate Authority (CA)
We'll start by generating our own CA, which will sign the server certificate.
What is a Certificate Authority (CA)?
A Certificate Authority (CA) is an entity that issues digital certificates. These certificates confirm the identity of the server or client and establish trust in the encrypted connection. By creating your own CA, you take on the role of a trusted entity for your local environment.
Create directories
mkdir -p https_server/certs && cd https_server/certs
Generate CA private key
openssl genrsa -des3 -out myCA.key 2048
- Note: You'll be prompted to set a passphrase. Remember it; you'll need it later.
Generate CA certificate
openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.pem
- When prompted, you can leave fields blank or fill them as needed.
Step 2: Install the CA certificate in the System Trust Store
Adding your CA to the system's trusted root certificates ensures that certificates signed by your CA are trusted.
Install ca-certificates package
sudo apt update
sudo apt install -y ca-certificates
Add your CA certificate
sudo cp myCA.pem /usr/local/share/ca-certificates/myCA.crt
sudo update-ca-certificates
- Output should include:
1 added, 0 removed; done. Adding debian:myCA.pem
Step 3: Generate a server certificate signed by your CA
Generate server private key
openssl genrsa -out server.key 2048
Create a Certificate Signing Request (CSR)
CSR contains information (e.g. common name, organization, country) the Certificate Authority (CA) will use to create your certificate. It also contains the public key that will be included in your certificate and is signed with the corresponding private key.
openssl req -new -key server.key -out server.csr
Create a configuration file for extensions
Create a file named server.ext with the following content:
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
Generate the server certificate
openssl x509 -req -in server.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial -out server.crt -days 825 -sha256 -extfile server.ext
- Note: Enter the CA passphrase when prompted.
Step 4: Install the CA certificate in your browser
As the final step, add your CA certificate to your browser's trusted authorities.
Google Chrome
- Navigate to Settings > Privacy and security > Security.
- Scroll down and click Manage certificates.
- Select the Authorities tab.
- Click Import and choose your myCA.pem file.
- Check all trust options and confirm.
Step 5: Create an HTTPS server in Go
Now, let's set up a simple HTTPS server using Go.
Write the server code
Create a file named main.go in ~/https_server:
package main
import (
"crypto/tls"
"fmt"
"log"
"net/http"
"os"
"time"
)
func index(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte("Hello world!!!.\n"))
}
func ExecServer() error {
mux := http.NewServeMux()
mux.HandleFunc("/", index)
// Load tls certificates
serverTLSCert, err := tls.LoadX509KeyPair("certs/server.crt", "certs/server.key")
if err != nil {
log.Fatalf("Error loading certificate and key file: %v", err)
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{serverTLSCert},
}
serv := &http.Server{
Addr: ":8080",
Handler: mux,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
TLSConfig: tlsConfig,
}
fmt.Println("### Server is starting... Listening on https://localhost:8080 ###")
defer serv.Close()
log.Fatal(serv.ListenAndServeTLS("", ""))
return nil
}
func main() {
if err := ExecServer(); err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)
}
}
Run the server
cd ~/https_server
go run main.go
Open https://localhost:8080 in your browser.
You should see something like this:
Congratulations 🎉 🎉, you have an https server running using locally trusted certificates.
Remember that for production you have to obtain a certificate from a trusted CA.