MTLS - Golang mTLS example,mTLS using TLS do both side authentication & authorization

Related tags

DevOps Tools mTLS
Overview

mTLS Golang Example

1. What is mutual TLS (mTLS)?

Mutual TLS, or mTLS for short, is a method for mutual authentication. mTLS using TLS do both side authentication & authorization.

mTLS helps ensure that traffic is secure and trusted in both directions between a client and server.

2. How does mTLS work?

Normally in TLS, the server has a TLS certificate and a public/private key pair, while the client does not. The typical TLS process works like this:

  1. Client connects to server
  2. Server presents its TLS certificate
  3. Client verifies the server's certificate
  4. Client and server exchange information over encrypted TLS connection

In mTLS, however, both the client and server have a certificate, and both sides authenticate using their public/private key pair. Compared to regular TLS, there are additional steps in mTLS to verify both parties (additional steps in bold):

  1. Client connects to server
  2. Server presents its TLS certificate
  3. Client verifies the server's certificate
  4. Client presents its TLS certificate
  5. Server verifies the client's certificate
  6. Server grants access
  7. Client and server exchange information over encrypted TLS connection

3. Example Walkthrough

3.1 Certs and Keys

The completed script is certs/key.sh

  1. Generate CA Root. The first thing we need to do to add mTLS to the connection is to generate a self-signed rootCA file that would be used to sign both the server and client cert.

    openssl req -newkey rsa:2048 \
        -new -nodes -x509 \
        -days ${DAYS} \
        -out ca.crt \
        -keyout ca.key \
        -subj "/C=US/ST=Earth/L=Mountain View/O=MegaEase/OU=MegaCloud/CN=localhost" 
  2. Generate the Server Certificate

    #create a key for server
    openssl genrsa -out server.key 2048
    
    #generate the Certificate Signing Request 
    openssl req -new -key server.key -days ${DAYS} -out server.csr \
        -subj "/C=US/ST=Earth/L=Mountain View/O=MegaEase/OU=MegaCloud/CN=localhost" 
    
    #sign it with Root CA
    openssl x509  -req -in server.csr \
        -extfile <(printf "subjectAltName=DNS:localhost") \ 
        -CA ca.crt -CAkey ca.key  \
        -days ${DAYS} -sha256 -CAcreateserial \
        -out server.crt 

    Note: after golang 1.15, we could have the following errors:

    x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0"

    https://stackoverflow.com/questions/64814173/ how-do-i-use-sans-with-openssl-instead-of-common-name

  3. Generate the Client certification

    It's similar to server-side

    openssl genrsa -out ${CLIENT}.key 2048
    
    openssl req -new -key ${CLIENT}.key -days ${DAYS} -out ${CLIENT}.csr \
        -subj "/C=US/ST=Earth/L=Mountain View/O=$O/OU=$OU/CN=localhost"
    
    openssl x509  -req -in ${CLIENT}.csr \
        -extfile <(printf "subjectAltName=DNS:localhost") \ 
        -CA ca.crt -CAkey ca.key -out ${CLIENT}.crt -days ${DAYS} -sha256 -CAcreateserial

3.2 Server.go

The server.go has the following works.

  • Listen on both HTTP(8080) and HTTPS(8443). For mTLS, we only consider the HTTPS.
  • It needs the three files
    • CA Root certificate ca.crt
    • Server's certificate servier.crt and its private key server.key
  • /hello is the HTTP API call, which would reply "Hello, World" to the client.

To enable the mTLS , it requires for a CA pool and client-side authentication, something like below

caCertPool := x509.NewCertPool()
caCertFile, err := ioutil.ReadFile("./certs/ca.crt")
caCertPool.AppendCertsFromPEM(caCertFile) 
...
...
tlsConfig := &tls.Config{
	ClientCAs:  caCertPool,
	ClientAuth: tls.RequireAndVerifyClientCert, //<-- this is the key
	MinVersion: tls.VersionTLS12,
}

You can run Server like this

go run server.go

When the client successfully sent the request. It would output the header and TLS connection state which includes the client's subjects.

(HTTP) Listen on :8080
(HTTPS) Listen on :8443
2021/12/31 14:47:13 >>>>>>>>>>>>>>>> Header <<<<<<<<<<<<<<<<
2021/12/31 14:47:13 User-Agent:curl/7.77.0
2021/12/31 14:47:13 Accept:*/*
2021/12/31 14:47:13 >>>>>>>>>>>>>>>> State <<<<<<<<<<<<<<<<
2021/12/31 14:47:13 Version: 303
2021/12/31 14:47:13 HandshakeComplete: true
2021/12/31 14:47:13 DidResume: false
2021/12/31 14:47:13 CipherSuite: c02f
2021/12/31 14:47:13 NegotiatedProtocol: h2
2021/12/31 14:47:13 NegotiatedProtocolIsMutual: true
2021/12/31 14:47:13 Certificate chain:
2021/12/31 14:47:13  0 s:/C=[SO]/ST=[Earth]/L=[Mountain]/O=[Client-B]/OU=[Client-B-OU]/CN=localhost
2021/12/31 14:47:13    i:/C=[SO]/ST=[Earth]/L=[Mountain]/O=[MegaEase]/OU=[MegaCloud]/CN=localhost
2021/12/31 14:47:13  1 s:/C=[SO]/ST=[Earth]/L=[Mountain]/O=[MegaEase]/OU=[MegaCloud]/CN=localhost
2021/12/31 14:47:13    i:/C=[SO]/ST=[Earth]/L=[Mountain]/O=[MegaEase]/OU=[MegaCloud]/CN=localhost
2021/12/31 14:47:13 >>>>>>>>>>>>>>>>> End <<<<<<<<<<<<<<<<<<

3.3 Client.go

The client.go has the following works.

It needs the three files - ca.crt, client.crt, client.key

You can indicate -c=a for client a, and -c=b for client b. such as:

go run client.go -c=a
go run client.go -c=b

You also can use the curl to connect to the server.

curl --trace trace.log -k \
	--cacert ./certs/ca.crt \
	--cert ./certs/client.b.crt \
	--key ./certs/client.b.key \
	https://localhost:8443/hello
  • --trace trace.log would record the network details of how the client communicates to the server.
  • -k because we use a self-signed certificate, so we need to add this.
You might also like...
Go-backend-test - Creating backend stuff & openid connect authentication stuff in golang

Go Backend Coding Practice This is my practice repo to learn about creating back

An example of Kubernetes' Horizontal Pod Autoscaler using costume metrics.
An example of Kubernetes' Horizontal Pod Autoscaler using costume metrics.

Kubernetes Autoscaling Example In this project, I try to implement Horizontal Pod AutoscalerHPA provided by Kubernetes. The Horizontal Pod Autoscaler

Simple example using Git actions + Argo CD + K8S + Docker and GO lang

CICD-simple_example Simple example using Git actions + Argo CD + K8S + Docker and GO lang Intro Pre reqs Have an ArgoCD account and Installed. Docker

The example shows how to build a simple multi-tier web application using Kubernetes and Docker
The example shows how to build a simple multi-tier web application using Kubernetes and Docker

Guestbook Example This example shows how to build a simple multi-tier web application using Kubernetes and Docker. The application consists of a web f

Go-gke-pulumi - A simple example that deploys a GKE cluster and an application to the cluster using pulumi

This example deploys a Google Cloud Platform (GCP) Google Kubernetes Engine (GKE) cluster and an application to it

An example of using Litestream's live read replication feature.

Litestream Read Replica Example This repository is an example of how to setup and deploy a multi-node SQLite database using Litestream's live read rep

S3 Reverse Proxy with GET, PUT and DELETE methods and authentication (OpenID Connect and Basic Auth)
S3 Reverse Proxy with GET, PUT and DELETE methods and authentication (OpenID Connect and Basic Auth)

Menu Why ? Features Configuration Templates Open Policy Agent (OPA) API GET PUT DELETE AWS IAM Policy Grafana Dashboard Prometheus metrics Deployment

k6 extension to load test Apache Kafka with support for Avro messages and SASL Authentication

xk6-kafka This project is a k6 extension that can be used to load test Kafka, using a producer. Per each connection to Kafka, many messages can be sen

A minimal Go project with user authentication ready out of the box. All frontend assets should be less than 100 kB on every page load

Golang Base Project A minimal Golang project with user authentication ready out of the box. All frontend assets should be less than 100 kB on every pa

Owner
Hao Chen
Founder of MegaEase Inc. 芝兰生于空谷,不以无人而不芳。
Hao Chen
🔑 Kubernetes Authentication & Authorization WebHook Server

Guard Guard by AppsCode is a Kubernetes Webhook Authentication server. Using guard, you can log into your Kubernetes cluster using various auth provid

Kubernetes Guard 546 Dec 16, 2022
Establishes inter-service mTLS connectivity.

\ \\, \\\,^,.,,. “Zero to Hero” ,;7~((\))`;;,, <zerotohero.dev> ,(@') ;)`))\;;', stay up to date, be curiou

Zero to Hero 0 Dec 22, 2021
The official container networking plugin for both OECP of Alibaba Cloud and SOFAStack of Ant Financial Co.

Rama What is Rama? Rama is an open source container networking solution, integrated with Kubernetes and used officially by following well-known PaaS p

null 163 Dec 29, 2022
GitHub Rate Limits Prometheus exporter. Works with both App and PAT credentials

Github Rate Limit Prometheus Exporter A prometheus exporter which scrapes GitHub API for the rate limits used by PAT/GitHub App. Helm Chart with value

Kostiantyn Kulbachnyi 7 Sep 19, 2022
oci-ccm custom build for both arm64 and amd64

OCI Cloud Controller Manager (CCM) oci-cloud-controller-manager is a Kubernetes Cloud Controller Manager implementation (or out-of-tree cloud-provider

Manasseh Zhou 0 Jan 18, 2022
The server-side reproduction, similar the one of https://popcat.click, improve the performance and speed.

PopCat Echo The server-side reproduction, similar the one of https://popcat.click, improve the performance and speed. Docker Image The docker image is

SuperSonic 61 Dec 15, 2022
Pulumi-k8s-operator-example - OpenGitOps Compliant Pulumi Kubernetes Operator Example

Pulumi GitOps Example OpenGitOps Compliant Pulumi Kubernetes Operator Example Pr

Christian Hernandez 3 May 6, 2022
Discover expired TLS certificates in the services of a kubernetes cluster

About verify-k8s-certs is a daemon (prometheus exporter) to discover expired TLS certificates in a kubernetes cluster. It exposes the informations as

Angelo Poerio 7 Feb 1, 2022
Watch and react to changes in Kubernetes TLS Secrets

cert-watch Watch and react to change in Kubernetes TLS Secrets. What is cert-watch? Kubernetes has introduced a number of different ways to keep certi

null 8 Feb 4, 2022
Terraform-house - Golang Based terraform automation example using tf.json

Terraform House Manage your own terraform workflow using go language, with the b

Bayu Rizky Ramadhan 0 Feb 17, 2022