- 1. Create a Root CA
- 2. Trusting new RootCA in system
- 3. Create Key, CSR and Certificate
- 4. How to verify SSL Certificates
- 5. Kubernetes CA Certificates
- 6. SAN (Subject Alternative Name) Certificates
- 7. References
1. Create a Root CA
$ mkdir RootCA && cd RootCA
# Create RootCA Key
$ openssl genrsa -out rootCA.key 4096
Remove the
-des3option for non-password protected key. The-des3option specifies how the private key is encrypted with a password. Without a cipher option, the private key is not encrypted and no password is required.
Note: Optionally you can create the RootCA.csr and sign it.
$ openssl req -new -key ca.key -subj "/CN=MYROOT-CA" -out rootCA.csr
$ openssl x509 -req -in rootCA.csr -signkey rootCA.key -out rootCA.crt
# Create self-sign CA Certificate with 10 years validity
$ openssl req -x509 -new -nodes -key rootCA.key -sha512 -days 3650 -out rootCA.pem
2. Trusting new RootCA in system
Fedora / RHEL
$ sudo cp ../RootCA/rootCA.pem /etc/pki/ca-trust/source/anchors/iamgini-rootCA.pem
# make sure the certificate is made available through the /etc/pki/ca-trust/extracted
$ sudo update-ca-trust
# Verify Root CA - List trust or certificates
$ trust list
Ubuntu / Debian
$ sudo cp rootCA.pem /usr/local/share/ca-certificates/iamgini-rootCA.crt
$ sudo update-ca-certificates
3. Create Key, CSR and Certificate
Optional - create a folder to avoid overwrite.
$ cd .. && mkdir SSL_CERTS && cd SSL_CERTS
3.1. Create a new SSL Key for server/application
$ openssl genrsa -out myserver.key 4096
3.2. Generate Certificate Signing Request (CSR)
$ openssl req -new \
-key myserver.key \
-out myserver.csr \
-subj "/C=SG/ST=Singapore/L=CBD/O=iamgini/OU=IT/CN=aap25.lab.iamgini.com/[email protected]"
Note: Adding
-nodes(means no DES) tells OpenSSL not to encrypt the private key.
You can also create a new key and CSR together:
$ openssl req -newkey rsa:4096 \
-keyout myserver.key \
-out myserver.csr \
-nodes \
-subj "/C=SG/ST=Singapore/L=CBD/O=iamgini/OU=IT/CN=aap25.lab.iamgini.com/[email protected]"
For interactive CSR entry:
$ openssl req -newkey rsa:4096 \
-keyout myserver.key \
-out myserver.csr \
-nodes
3.3. Generate myserver.crt Certificate using CSR and CA
$ openssl x509 -req \
-CA ../RootCA/rootCA.pem \
-CAkey ../RootCA/rootCA.key \
-CAcreateserial \
-in myserver.csr \
-out myserver.crt \
-days 1825 -sha512
Verify certificate content
$ openssl x509 -in myserver.crt -text -noout
Verify key and certificate matching using md5:
$ openssl rsa -noout -modulus -in myserver.key | openssl md5
MD5(stdin)= 22c83dc812316f248c20ba345410fb77
$ openssl x509 -noout -modulus -in myserver.crt | openssl md5
MD5(stdin)= 22c83dc812316f248c20ba345410fb77
Or match using fingerprint:
$ openssl rsa -in myserver.key -pubout -outform PEM | openssl sha256
SHA2-256(stdin)= df3581f4be1929b53745c5cda83e49914382c9f48fff39d83936ea76d8ccfc56
$ openssl x509 -in myserver.crt -pubkey -noout | openssl sha256
SHA2-256(stdin)= df3581f4be1929b53745c5cda83e49914382c9f48fff39d83936ea76d8ccfc56
Check a PKCS#12 file (.pfx or .p12):
$ openssl pkcs12 -info -in keyStore.p12
Check and verify Key file:
$ openssl rsa -in server.key -check
Verify CSR content:
$ openssl req -in server.csr -noout -text
$ openssl req -in server.csr -noout -text -verify
Generate Certificate using CSR, CA, and extension file:
$ openssl x509 -req \
-passin file:passphrase.txt \
-CA myserver-CA.pem -CAkey myserver-CA.key -CAcreateserial \
-in myserver.csr \
-out myserver.crt \
-days 1825 -sha256 -extfile myserver.ext
$ openssl x509 -in myserver.crt -text -noout
4. How to verify SSL Certificates
4.1. Verify Certificate and Key
You should get the same md5 output for all three commands.
# certificate
$ openssl x509 -noout -modulus -in <file>.crt | openssl md5
# key
$ openssl rsa -noout -modulus -in <file>.key | openssl md5
# csr
$ openssl req -noout -modulus -in <file>.csr | openssl md5
Check the key only:
$ openssl rsa -check -noout -in myserver.key
RSA Key is ok
4.2. Change or remove passphrase
Remove passphrase from SSL key:
$ openssl rsa -in original.key -out new.key
Change the passphrase of the SSL key:
$ openssl rsa -aes256 -in original.key -out new.key
4.3. Extract from PFX file
$ openssl pkcs12 -in [yourfile.pfx] -nocerts -out [drlive.key]
4.4. Extract Certificate from P7B file
$ openssl pkcs7 -inform PEM -outform PEM -in certnew.p7b -print_certs > certificate.cer
5. Kubernetes CA Certificates
Kubernetes uses its own internal CA to sign certificates for cluster components (API server, kubelet, etcd, etc.).
5.1. Create Kubernetes CA
# Step 1: Generate CA key
$ openssl genrsa -out ca.key 2048
# Step 2: Create Certificate Signing Request
$ openssl req -new -key ca.key -subj "/CN=KUBERNETES-CA" -out ca.csr
# Step 3: Self-sign the CA certificate
$ openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
5.2. Sign Component Certificates with Kubernetes CA
Use the CA to sign certificates for cluster components (e.g. kube-apiserver, etcd, service accounts):
# Generate component key
$ openssl genrsa -out apiserver.key 2048
# Create CSR with correct CN and O (used for RBAC)
$ openssl req -new -key apiserver.key \
-subj "/CN=kube-apiserver/O=system:masters" \
-out apiserver.csr
# Sign with the CA
$ openssl x509 -req \
-in apiserver.csr \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-out apiserver.crt \
-days 365
Note: Kubernetes uses the
CNfield as the username andOfield as the group for RBAC purposes.
5.3. OpenShift / kubeadm kubeconfig Certs
When building a kubeconfig manually (e.g. for UPI installs), the client cert must be signed by the cluster CA. The CN in the cert becomes the Kubernetes username.
# Admin kubeconfig cert
$ openssl genrsa -out admin.key 2048
$ openssl req -new -key admin.key \
-subj "/CN=kubernetes-admin/O=system:masters" \
-out admin.csr
$ openssl x509 -req -in admin.csr \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-out admin.crt -days 365
5.4. Verify Kubernetes Cluster Certificates
# Check API server cert on a running cluster
$ openssl s_client -connect <api-server>:6443 </dev/null 2>/dev/null | \
openssl x509 -noout -text
# Check cert expiry
$ openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -enddate
# Check all kubeadm-managed certs
$ kubeadm certs check-expiration
6. SAN (Subject Alternative Name) Certificates
SANs are required for multi-hostname or IP-based certificates. Most modern tools reject certs without SANs.
6.1. Using a config file (recommended)
Create myserver.ext or myserver_csr.conf:
[req]
default_md = sha512
prompt = no
req_extensions = req_ext
distinguished_name = req_distinguished_name
[req_distinguished_name]
commonName = myserver.lab.iamgini.com
countryName = SG
stateOrProvinceName = Singapore
organizationName = iamgini
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.0 = myserver.lab.iamgini.com
DNS.1 = myserver
IP.0 = 192.168.7.10
Generate key, CSR, and sign with CA:
$ openssl genrsa -out myserver.key 4096
$ openssl req -new -nodes \
-key myserver.key \
-config myserver_csr.conf \
-out myserver.csr
$ openssl x509 -req \
-in myserver.csr \
-CA ../RootCA/rootCA.pem \
-CAkey ../RootCA/rootCA.key \
-CAcreateserial \
-extensions req_ext \
-extfile myserver_csr.conf \
-out myserver.crt \
-days 3650 -sha512
6.2. PostgreSQL / Database Example
$ openssl genrsa -out pgsql.key 4096
$ cat > pgsql_csr.conf << 'EOF'
[req]
default_md = sha512
prompt = no
req_extensions = req_ext
distinguished_name = req_distinguished_name
[req_distinguished_name]
commonName = database.ansible.com
countryName = US
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.0 = database.ansible.com
IP.0 = 192.168.7.19
EOF
$ openssl req -new -nodes -key pgsql.key -config pgsql_csr.conf -out pgsql.csr
$ openssl x509 -req \
-in pgsql.csr \
-CA ~/RootCA/rootCA.pem \
-CAkey ~/RootCA/rootCA.key \
-CAcreateserial \
-extensions req_ext \
-extfile pgsql_csr.conf \
-out pgsql.crt \
-days 3650
Trust the CA on the controller node (RHEL/Fedora):
$ cp rootCA.pem /etc/pki/ca-trust/source/anchors/
$ restorecon -Rv /etc/pki/ca-trust/source/anchors/
$ update-ca-trust