Problem: You want to serve your web application through HTTPS.
Solution: Use the http.ListenAndServeTLS function to serve your web application through HTTPS.
HTTPS is nothing more than layering HTTP on top of the Transport Security Layer (TLS). The net/http package provides the http.ListenAndServeTLS function to serve your web application through HTTPS.
package main import ( "net/http" ) func main() { http.HandleFunc("/", index) http.ListenAndServeTLS(":8000", "cert.pem", "key.pem", nil) } func index(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello World")) }
Most of the code is the same, except you need a certificate file cert.pem and a private key file key.pem . The cert.pem is the SSL certificate, while key.pem is the private key for the server. In a production scenario, you will need to get the SSL certificate from a certificate authority (CA) like VeriSign or Thawte or Comodo SSL, or you can use Let’s Encrypt to get a free one. However, if you just need a certificate and private key to try things out, you can generate self-signed ones using OpenSSL.
Run this from the command line:
$ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
OpenSSL is an open source implementation of SSL and TLS. The library contains a command-line tool with the same name that can do a number of things, including creating private keys and SSL certificates.
The req command is used to manage certificate requests but can also be used to create self-signed certificates. Option -x509 tells the tool to create self-signed certificates (X.509 is an International Telecommunication Union standard defining the format of public key certificates). The option -newkey tells the tool to generate a new private key. The argument rsa:4096 tells the tool to create a key that is of size 4,096 bits. The -keyout and -out options tell the tool to create the private key and certificate files with the respective names given in the argument. The option -days specifies the number of days to certify the certificate. Here you use 365, which means the certificate is valid only for 1 year. Finally, use the -nodes option (which means, “no DES” rather than “nodes”) to say you don’t want to encrypt the private key.
When you run the command, you should see something like this:
Generating a 4096 bit RSA private key ......................................................................... ...................................++++ ......................................................................... ......................................................................... ...................................................++++ writing new private key to 'key.pem' \ - - - - - You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. \ - - - - - Country Name (2 letter code) []:SG State or Province Name (full name) []: Locality Name (eg, city) []: Organization Name (eg, company) []:Go Cookbook Organizational Unit Name (eg, section) []: Common Name (eg, fully qualified host name) []:localhost Email Address []:sausheong@gmail.com
This is the interactive mode. You can press the return key to leave the entries empty except for the common name. The common name is the fully qualified domain name of the server you want to protect. In this case, it’s for testing, so you can just enter localhost .
Once you’re done, you should have two files — the cert.pem and key.pem files. Copy them into the same directory as the main.go file. Then run the code again to start the server.
While there would be uses for configuring TLS this way, most likely, if you are deploying your web application in a production environment, you will use a reverse proxy like Nginx or Apache to handle the TLS termination. This way, you can offload the TLS termination, which will improve the performance of your web application. This means your web application can still run with HTTP while it is fronted by a reverse proxy that runs through HTTPS.