Understanding Mutual SSL Authentication
Mutual authentication, also known as 2-way authentication, involves a bilateral verification process where both the client and server authenticate each other using digital certificates issued by a Certificate Authority. As defined by CodeProject.com, mutual SSL authentication ensures that both parties verify the provided digital certificate, establishing mutual trust in each other’s identity.
Mutual Authentication Flow
This tutorial utilizes the curl client and NGINX server to demonstrate the mutual authentication flow. Before diving into the setup, it’s crucial to configure the Ingress-Nginx controller on your Kubernetes cluster. Ensure compatibility with Minikube version 0.30 and Ingress-Nginx version 0.19, or refer to the Ingress-Nginx deployment documentation for alternative setups.
Setting Up Mutual Authentication
To implement mutual authentication, follow these essential steps:
- Creating Certificates
Generate self-signed certificates (for testing purposes only) using OpenSSL. Key terms include CommonName (CN), Certificate Authority (CA), Server Certificate, and Client Certificate. These certificates establish secure communication between the client and server.
$ openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=Fern Cert Authority'
$ openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr -nodes -subj '/CN=meow.com'
$ openssl x509 -req -sha256 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
$ openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=Fern'
$ openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt
2. Creating Kubernetes Secrets
Store the generated certificates in a Kubernetes Secret, simplifying their usage in the Ingress-Nginx controller. For simplicity, the example combines the Server Certificate and CA Certificate into one Secret named “my-certs.”
$ kubectl create secret generic my-certs --from-file=tls.crt=server.crt --from-file=tls.key=server.key --from-file=ca.crt=ca.crt
$ kubectl get secret my-certs
3. Deploying an Application with Mutual Authentication
Deploy pods using deployments, expose them using services, and set up Ingress rules to access the service securely via HTTPS.
#deployment.yaml content
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: meow
spec:
replicas: 2
selector:
matchLabels:
app: meow
template:
metadata:
labels:
app: meow
spec:
containers:
- name: meow
image: gcr.io/kubernetes-e2e-test-images/echoserver:2.1
ports:
- containerPort: 8080
#service.yaml content
apiVersion: v1
kind: Service
metadata:
name: meow-svc
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: meow
#ingress.yaml content
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
nginx.ingress.kubernetes.io/auth-tls-secret: "default/my-certs"
name: meow-ingress
namespace: default
spec:
rules:
- host: meow.com
http:
paths:
- backend:
serviceName: meow-svc
servicePort: 80
path: /
tls:
- hosts:
- meow.com
secretName: my-certs
# Deployment
$ kubectl apply -f deployment.yaml
# Service
$ kubectl apply -f service.yaml
# Ingress Rules
$ kubectl apply -f ingress.yaml
$ sudo -- sh -c "echo $(minikube ip) meow.com >> /etc/hosts"
4. Testing the Configuration
Verify the mutual authentication setup by testing requests with and without the client certificate and key.
# Without Client Certificate and Key (Expect 400 Bad Request)
$ curl https://meow.com/ -k
# With Client Certificate and Key (Expect successful redirection)
$ curl https://meow.com/ --cert client.crt --key client.key -k
Additional Settings and Troubleshooting
Explore additional settings such as client certificate verification depth, error page redirection, and passing certificates to the upstream server. For troubleshooting, check NGINX configuration and logs.
# Check NGINX Configuration
$ kubectl exec -it -n kube-system nginx-ingress-controller-<pod_id> cat /etc/nginx/nginx.conf | grep ssl_client_certificate -A 1
# Check NGINX Controller Logs
$ kubectl logs -n kube-system nginx-ingress-controller-<pod_id>
If you found this content helpful or informative, consider giving it a thumbs up or expressing your appreciation! I’m here to assist and provide valuable information. Feel free to ask if you have any more questions or if there’s anything else I can help you with. Happy coding! 👍🚀
Loved this?
So, did you find this article helpful? If you did, please consider buying me a coffee :-)