Lorsqu’on souhaite déployer un service sur Kubernetes et le protéger via TLS, la méthode la plus simple est généralement de s’appuyer sur la solution d’ingress controller existante sur le cluster.
Mais dans certains cas on doit intervenir sur des clusters qui sont gérés par d’autres équipes et sur lequels aucune solution d’ingress n’est mise en place pour gérer le traffic entrant. De plus sur ce type de cluster on n’a pas forcément la lattitude de pouvoir faire ce qui nous plaît faute de droits suffisants.
Dans ce cas, une solution est de déployer soi-même un pod Nginx et de le configurer pour qu’il porte la terminaison TLS de notre service.
Gestion des certificats
Première étape, créons notre autorité de certification :
openssl genrsa -out rootCA.key 4096
openssl req -x509 -sha256 -new -nodes -key rootCA.key -days 3650 -out rootCA.crt
Puis le certificat pour notre service :
openssl req -new -newkey rsa:4096 -nodes -keyout cert.key -out cert.csr -subj "/C=FR/O=Xian-Labs/CN=mon-service.example.com"
openssl x509 -req -sha256 -days 365 -in cert.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out cert.crt
Vérifions le certificat produit :
openssl x509 -in cert.crt -text -noout
Configuration Nginx
Nous utilisons le fichier de configuration suivant pour Nginx :
default.conf
ouvrir
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/certs/tls.crt;
ssl_certificate_key /etc/nginx/certs/tls.key;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
proxy_set_header Host $host:8443;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
location / {
proxy_pass http://mon-service;
}
}
Ce fichier nous permet de définir l’emplacement des certificats TLS ainsi que le service vers lequel nous souhaitons proxifier le traffic via la directive :
proxy_pass http://mon-service
Nous allons ensuite créer les élements de configuration pour notre Pod Nginx :
-
un Secret qui contiendra les certificats TLS
kubectl create secret tls mon-service-tls --cert cert.crt --key cert.key
-
un ConfigMap qui contiendra le fichier de configuration Nginx décrit ci-dessus
kubectl create configmap mon-service-tls --from-file default.conf
Déploiement du reverse proxy Nginx
Nous déclarons un Deployment ainsi qu’un Service Kubernetes de type NodePort :
nginx-tls.deployment.yaml
ouvrir
apiVersion: apps/v1
kind: Deployment
metadata:
name: mon-service-tls
namespace: xian
spec:
replicas: 1
selector:
matchLabels:
app: mon-service-tls
template:
metadata:
labels:
app: mon-service-tls
spec:
containers:
- name: nginx
image: nginx:1.23.1-alpine
volumeMounts:
- name: nginx-conf
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
readOnly: true
- name: certs
mountPath: /etc/nginx/certs
volumes:
- name: nginx-conf
configMap:
name: mon-service-tls
- name: certs
secret:
secretName: mon-service-tls
nginx-tls.service.yaml
ouvrir
apiVersion: v1
kind: Service
metadata:
name: mon-service-tls
namespace: xian
spec:
ports:
- nodePort: 32352
port: 443
protocol: TCP
targetPort: 443
selector:
app: mon-service-tls
type: NodePort
kubectl apply -f nginx-tls.deployment.yaml
kubectl apply -f nginx-tls.service.yaml
Et voilà, notre service est protégé avec TLS ;-)