How to secure applications running on Kubernetes (SSL/TLS Certificates)?
Securing an application running on Kubernetes (SSL/TLS Certificates)
You can secure an application running on Kubernetes by creating a secret that contains a TLS (Transport Layer Security) private key and certificate.
Currently, Ingress supports a single TLS port, 443, and assumes TLS termination.
The TLS secret must contain keys named tls. crt and tls. keys that contain the certificate and private key to use for TLS.
Create TLS Secret:
Using kubectl:$ kubectl create secret tls my-tls-secret \
--key < private key filename> \
--cert < certificate filename>
Using YAML file:
tls.crt: "base64 encoded cert"
tls.key: "base64 encoded key"
Ingress with TLS:
Self Signed Certificate
A self-signed SSL certificate is an SSL Certificate that is issued by the person creating it rather than a trusted certificate authority. This can be good for testing environments.
Step 1: Generate a CA private key
$ OpenSSL genrsa -out ca.key 2048
Step 2: Create a self-signed certificate, valid for 365 days.
$ openssl req -x509 \
-new -nodes \
-days 365 \
-key ca.key \
-out ca.crt \
Step 3: Now, create the tls secret using the kubectl command or using the yaml definition.
$ kubectl create secret tls my-tls-secret \
--key ca.key \
secret "my-tls-secret" created
Check the secret.
$ kubectl get secrets/my-tls-secretNAME TYPE DATA AGEmy-tls-secret kubernetes.io/tls 2 37s
Describe the secret.
$ kubectl describe secrets/my-tls-secret
tls.crt: 1115 bytes
tls.key: 1675 bytes
Drawbacks of Self-signed Certificate:
Self-signed shows untrusted connection warning while connecting to HTTPS website. Thus, the Self-Signed certificate is not the right choice for online businesses
A self-signed certificate does lack authenticity hence, attackers can replace the self-signed certificate with the attacker’s certificate. However, browsers will have no idea whether it is communicating with the right SSL certificate or a replaced certificate.
Third-party CAs offer warrants against certain losses in the case of certificate is-issuance. A self-signed certificate does not endow with warranty protection.
Customer scared to deal with a self-signed certificate because of the unsafe environment of the certificate while customer gains self-assurance transacting online with a signed certificate.
How to do TLS between microservices in Kubernetes?
Kubernetes Services and DNS Discovery
In general, it is recommended to put a Service in front of a Deployment that manages pods in Kubernetes. The Service creates a stable DNS and IP endpoint for pods that may be deleted and be assigned a different IP address when recreated. DNS service discovery is automatically enabled with a ClusterIP type service and is in the format: <service name>.<kubernetes namespace>.svc.<cluster domain> where cluster domain is usually cluster.local. This means that we can use the auto-created DNS and assigned ClusterIP in our alt names for our certificate.
Kubernetes Internal CA
Kubernetes does have an internal CA along with API methods to post CSRs and have those CSRs signed by the CA however I would not use the internal CA for securing microservices. The internal CA is primarily used by the kubelet and other internal cluster processes to authenticate to the Kubernetes API server. There is no functionality for autorenewal and I think the cert will always be signed for 30 days.
Kubernetes-native Certificate Management
You can install and use cert-manager to have the cluster automatically create and manage certificates for you using custom resources. They have excellent examples on their website so I would encourage you to check that out if it is of interest. You should be able to use the CA Issuer Type and create Certificate Resources that will create a certificate as a Kubernetes Secret. For the alt names, refer to the below certificate generation steps in the manual section of my response.
Manually Create and Deploy Certificates
You should be able to achieve the same result using your “without Kubernetes” approach using cfssl:
generate CA using cfssl
add CA as trusted in the image (using your Dockerfile approach)
create Kubernetes Service (for example purposes I will use kubectl create)
$ kubectl create service clusterip grpcserver — tcp=8000
describe the created Kubernetes Service, note IP will most likely be different in your case
$ kubectl describe service/grpcserver
Port: 8000 8000/TCP
Session Affinity: None
generate a certificate for gRPCServer with a CN of grpcserver.default.svc.cluster.local the following alt names:
generate the client certificate with cfssl
put both certificates into Secret objects
kubectl create secret tls server — cert=server.pem — key=server.key
kubectl create secret tls client — cert=client.pem — key=client.key
mount the secret into the podspec
For More, Recommendations are
👋 Join us today !!
️Follow us on LinkedIn, Twitter, Facebook, and Instagram
If this post was helpful, please click the clap 👏 button below a few times to show your support! ⬇