Introduction
In 2020, Google Chrome changed the behavior ofSameSite=None
cookies to require activation of the Secure
option. As a result, testing a Web UI client whose API backend runs in a local Kubernetes cluster now requires HTTPS access.In this tutorial, you will learn how to obtain HTTPS access by generating a self-signed certificate for Kubernetes using cert-manager, CFSSL, Easy-RSA, and OpenSSL methods.
Prerequisites
- A Kubernetes cluster (you can create it by using minikube)
- kubectl command-line tool installed
Generating Certificates via cert-manager
As the native Kubernetes certificate management controller, the cert-manager add-on is the most common way to generate self-signed certificates.Step 1: Install cert-manager
To install cert-manager, first create a namespace for it:kubectl create namespace cert-manager

kubectl apply
command and the yaml
file available online to install the add-on:kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.13.1/cert-manager.yaml

Step 2: Create a Certificate Issuer
Create a namespace where you will generate certificates:kubectl create namespace [namespace]

kubectl apply -n [namespace] -f <(echo "
apiVersion: cert-manager.io/v1alpha2
kind: Issuer
metadata:
name: [issuer-name]
spec:
selfSigned: {}
")
The output confirms the successful issuer creation:
ClusterIssuer
using the available selfsigned-issuer.yaml
file:kubectl apply -f https://gist.githubusercontent.com/t83714/51440e2ed212991655959f45d8d037cc/raw/7b16949f95e2dd61e522e247749d77bc697fd63c/selfsigned-issuer.yaml
Step 3: Generate a Certificate
Generate a self-signed certificate by typing the following multi-line command into the terminal:kubectl apply -n [namespace]-f <(echo '
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: [certificate-name]
spec:
secretName: [secret-name]
dnsNames:
- "*.[namespace].svc.cluster.local"
- "*.[namespace]"
issuerRef:
name: [issuer-name]
')
The output confirms the creation was successful:
kubectl -n [namespace] get certificate

get secret
command:kubectl -n [namespace] get secret [secret-name]

ca.crt
, tls.crt
, and tls.key
. For the entire Secret, type:kubectl -n [namespace] get secret [secret-name] -o yaml
Note: Learn more about Kubernetes secrets, object storing sensitive pieces of data.
Step 4: Test the Certificate
Use the following command to test the validity of the certificate:openssl x509 -in <(kubectl -n [namespace] get secret
first-tls -o jsonpath='{.data.tls.crt}' | base64 -d)
-text -noout

X509v3 Subject Alternative Name
line should contain the dnsNames
you provided during the certificate generation.Generating Certificates via CFSSL
Another common tool for generating and verifying self-signed certificates is CFSSL. The tool consists of four programs:cfssl
– a command-line utility for CFSSL package management.multirootca
– a certificate authority server.mkbundle
– a certificate pool bundle builder.cfssljson
– a certificate generator that usesjson
outputs fromcfssl
andmultirootca
.
Step 1: Install CFSSL using Go
To install CFSSL, first, you need to install the necessary Go language packages. Type the following command:sudo apt install golang

cfssl
:go get -u github.com/cloudflare/cfssl/cmd/cfssl
Next, copy the file from ~/go/bin
to the appropriate folder:sudo cp ~/go/bin/cfssl /usr/local/bin/cfssl
Finally, repeat the process with cfssljson
:go get -u github.com/cloudflare/cfssl/cmd/cfssljson
sudo cp ~/go/bin/cfssljson /usr/local/bin/cfssljson
Step 2: Create a Certificate Authority
After you install the programs, proceed with creating a self-signed certificate authority (CA). The example below creates a file namedca.json
.The file defines the following:CN
– Common name for the authorityalgo
– the algorithm used for the certificatessize
– algorithm size in bitsC
– CountryL
– Locality (city)ST
– State or provinceO
– OrganizationOU
– Organizational Unit
{
"CN": "Example Company Root CA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "New York",
"ST": "New York",
"O": "Example Company",
"OU": "Example Company Root CA"
}
]
}
Create and save the json
file in a text editor. Then, use it to generate the ca.pem
and ca-key.pem
files by typing the following cfssl
command:cfssl gencert -initca ca.json | cfssljson -bare ca

Step 3: Create the Configuration File
To proceed, create thecfssl.json
configuration file. The file provides details about the certificate’s expiration date and usage for separate profiles (peer, server, and client).cfssl.json
should look like this:{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"intermediate_ca": {
"usages": [
"signing",
"digital signature",
"key encipherment",
"cert sign",
"crl sign",
"server auth",
"client auth"
],
"expiry": "8760h",
"ca_constraint": {
"is_ca": true,
"max_path_len": 0,
"max_path_len_zero": true
}
},
"peer": {
"usages": [
"signing",
"digital signature",
"key encipherment",
"client auth",
"server auth"
],
"expiry": "8760h"
},
"server": {
"usages": [
"signing",
"digital signing",
"key encipherment",
"server auth"
],
"expiry": "8760h"
},
"client": {
"usages": [
"signing",
"digital signature",
"key encipherment",
"client auth"
],
"expiry": "8760h"
}
}
}
}
Save the file and exit.Step 4: Create an Intermediate Certificate Authority
Anotherjson
file you must create is intermediate-ca.json
. It defines the intermediate certificate authority and looks similar to the previously created ca.json
:{
"CN": " Example Company Intermediate CA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "New York",
"ST": "New York",
"O": "Example Company",
"OU": "Example Company Intermediate CA"
}
],
"ca": {
"expiry": "42720h"
}
}
Step 5: Sign the Certificate
After creating both files, type the following command to create theintermediate_ca.pem
, intermediate_ca.csr
and intermediate_ca-key.pem
files, and sign the intermediate CA:cfssl gencert -initca intermediate-ca.json | cfssljson -bare intermediate_ca

cfssl sign -ca ca.pem -ca-key ca-key.pem -config cfssl.json -profile intermediate_ca intermediate_ca.csr | cfssljson -bare intermediate_ca

Step 6: Generate Host Certificates
To generate host certificates for peer, server, and client profiles, create thehost1.json
file with the necessary information about the hosts.{
"CN": "host.example-company.com",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "New York",
"O": "Example Company",
"OU": "Example Company Intermediate CA",
"ST": "New York"
}
],
"hosts": [
"host1.example-company.com",
"localhost"
]
}
Note: Different servers and clients may require different variations of the
json
file used above. Some require only the common name (CN) and do not check the hosts
section. Others need the IP address to be stated in the hosts
section.cfssl gencert -ca intermediate_ca.pem -ca-key intermediate_ca-key.pem -config cfssl.json -profile=peer host1.json | cfssljson -bare host-1-peer

cfssl gencert -ca intermediate_ca.pem -ca-key intermediate_ca-key.pem -config cfssl.json -profile=server host1.json | cfssljson -bare host-1-server

cfssl gencert -ca intermediate_ca.pem -ca-key intermediate_ca-key.pem -config cfssl.json -profile=client host1.json | cfssljson -bare host-1-client

Generating Certificates via Easy-RSA
Easy-RSA is a popular utility for creating root certificate authorities, requesting and signing certificates.Step 1: Install Easy-RSA
To download Easy-RSA packages, you need curl. If you do not have curl installed, install it by typing:sudo apt install curl
Now, type the following curl command:Curl -LO https://storage.googleapis.com/kubernetes-release/easy-rsa/easy-rsa.tar.gz

tar xzf easy-rsa.tar.gz
Go to the easy-rsa-3.0.1/easyrsa3
directory:cd easy-rsa-master/easyrsa3
Once you are in the folder, type the following command to finish setting up Easy-RSA:./easyrsa init-pki

Note: Curl is a useful tool to ignore certificate errors in development. Learn how to make curl ignore SSL errors.
Step 2: Create a Self-Signed CA
To initiate the creation of a self-signed CA, use this command:./easyrsa build-ca

ca.key
file. Next, the prompt requires you to enter information about the CA you are creating.Note: The system may ask you for more details than you see in the screenshot above. If you are asked about the organizational unit (
OU
), make sure to replace the default value (IT
) with ROOT-CA
.Step 3: Generate Server Certificate and Key
The next step is to generate a server certificate and key using a multi-line command shown below. The--subject-alt-name
option sets the IP addresses and DNS names for accessing the API server.The --days
option controls the length of the certificate validity.cluster.local
is the default DNS domain name../easyrsa --subject-alt-name="IP:[master-IP-address],"
"IP:[master-cluster-IP-address],"
"DNS:kubernetes,"
"DNS:kubernetes.default,"
"DNS:kubernetes.default.svc,"
"DNS:kubernetes.default.svc.cluster,"
"DNS:kubernetes.default.svc.cluster.local"
--days=10000
build-server-full server nopass

pki/ca.crt
, pki/issued/server.crt
and pki/private/server.key
files to your directory.Generating Certificates via OpenSSL
OpenSSL allows you to generate TLS certificates manually. The following steps show how to use OpenSSL to generate keys and certificates for your cluster.Step 1: Install OpenSSL
The OpenSSL tool is commonly pre-installed on Linux systems. Check if you have it installed by typing:openssl version -a
The output looks like this:
sudo apt install openssl
Step 2: Generate the Certificate Files
Use the following command to produce a 2048-bit RSA encrypted key for certificate signing:openssl genrsa -out ca.key 2048

ca.key
to generate ca.crt
. Use the -days
option to set the length of the certificate validity:openssl req -x509 -new -nodes -key ca.key -subj "/CN=[master-ip-address]" -days [number] -out ca.crt
If no errors occurr, the command produces no output.Finally, generate the server.key
file with 2048-bit RSA encryption:openssl genrsa -out server.key 2048

Step 3: Create the Certificate Configuration File
Create acsr.conf
configuration file for generating a Certificate Signing Request (CSR). The example file below also assumes that you are using cluster.local
as the default DNS domain name.[ req ]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[ dn ]
C = [country]
ST = [state]
L = [city]
O = [company]
OU = [organization-unit]
CN = [common-name]
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster
DNS.5 = kubernetes.default.svc.cluster.local
IP.1 = [MASTER_IP]
IP.2 = [MASTER_CLUSTER_IP]
[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=@alt_names
Make sure you replace the explanations in the square brackets with the actual values. Save the file and use it to generate a certificate signing request:openssl req -new -key server.key -out server.csr -config csr.conf
The command produces no output, but it creates the server.csr
file.Step 4: Generate the Certificate
Use the file you generated in the previous step together withca.key
and ca.crt
to create a server certificate:openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key
-CAcreateserial -out server.crt -days 10000
-extensions v3_ext -extfile csr.conf
The output of this multi-line command confirms the creation of the certificate and lists the data you from the configuration file:
openssl x509 -noout -text -in ./server.crt
