Nginx Ingress Controller with Cloudflare Full (strict) SSL/TLS encryption + mTLS mode

Jbn1233
2 min readAug 17, 2024

--

Upload “Cloudflare certificate

https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pem

to Ingress Controller Before enable “Authenticated Origin Pulls”

$ k get cm -n ingress-nginx  cloudflare-client-cert 
NAME DATA AGE
cloudflare-client-cert 1 18h

$ k describe cm -n ingress-nginx cloudflare-client-cert
Name: cloudflare-client-cert
Namespace: ingress-nginx
Labels: <none>
Annotations: <none>

Data
====
cloudflare-client-cert.crt:
----
-----BEGIN CERTIFICATE-----
MIIGCjCCA/KgAwIBAgIIV5G6lVbCLmEwDQYJKoZIhvcNAQENBQAwgZAxCzAJBgNV
...
...
...
-----END CERTIFICATE-----


BinaryData
====

Events: <none>

Put into CM and mount it to Ingress Controller.

        volumeMounts:
- mountPath: /etc/cloudflare-client-cert.crt
name: cloudflare-client-cert
subPath: cloudflare-client-cert.crt
...
volumes:
- configMap:
defaultMode: 420
name: cloudflare-client-cert
name: cloudflare-client-cert
...

Add http-snippet into ConfigMap

Note: This step will enable ssl_verify_client to ***ALL*** traffic/ingress trough this ingress controller.

apiVersion: v1
kind: ConfigMap
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
data:
http-snippet: |
ssl_verify_client on;
ssl_client_certificate /etc/cloudflare-client-cert.crt;

Rollout restart Ingress Controller and curl to verify

$ curl -k https://192.168.1.101
<html>
<head><title>400 No required SSL certificate was sent</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center>
<hr><center>nginx</center>
</body>
</html>

Last step, enable “Authenticated Origin Pulls”

$ curl https://echo-th1.jbndns1.online/


Hostname: echo-hostport-79d4b54f5-5v66n

Pod Information:
-no pod information available-

Server values:
server_version=nginx: 1.12.2 - lua: 10010

Request Information:
client_address=10.169.210.144
method=GET
real path=/
query=
request_version=1.1
request_scheme=http
request_uri=http://echo-th1.jbndns1.online:8080/

Request Headers:
accept=*/*
accept-encoding=gzip, br
cdn-loop=cloudflare
cf-connecting-ip=x.x.x.x
cf-ipcountry=TH
cf-ray=8b47035fedf2ce6d-SIN
...
...
...

That is all.

Update1:

nginx setting

  nginx.conf: |
worker_processes 1;
events {}
http {
log_format json '{'
'"time_local": "$time_local",'
'"remote_addr": "$remote_addr",'
'"real_remote_addr": "$http_cf_connecting_ip",'
'"cf_ipcountry": "$http_cf_ipcountry",'
'"request": "$request",'
'"status": "$status",'
'"body_bytes_sent": "$body_bytes_sent",'
'"http_referer": "$http_referer",'
'"http_user_agent": "$http_user_agent",'
'"request_time": "$request_time",'
'"upstream_response_time": "$upstream_response_time",'
'"host": "$host",'
'"method": "$request_method"'
'}';
access_log /dev/stdout json;
server {
ssl_protocols TLSv1.3;
real_ip_header proxy_protocol;
#set_real_ip_from 0.0.0.0/0;
set_real_ip_from 192.168.1.0/24;
listen 443 ssl proxy_protocol;
server_name _;
#server_name test.jbndns1.online;
ssl_certificate /etc/nginx/ssl/tls.crt;
ssl_certificate_key /etc/nginx/ssl/tls.key;
ssl_client_certificate /etc/nginx/cloudflare-client-cert/cloudflare-client-cert.crt;
#ssl_verify_client on;
ssl_verify_client optional;
#ssl_verify_depth 2;
if ($ssl_client_verify != SUCCESS) {
return 403;
}
proxy_set_header X-SSL-Client-Verify $ssl_client_verify;
proxy_set_header X-SSL-Client-DN $ssl_client_s_dn;
proxy_set_header X-SSL-Client-SID $ssl_session_id;
proxy_set_header X-CF-Remote-Addr $remote_addr;
location / {
proxy_pass http://echo;
}
}
}

Update:2

Download and use cert for default SSL cert for ingress

--

--

Jbn1233
Jbn1233

Written by Jbn1233

Very short and simple notes for CKA/SRE and may not works on your environment | jbn1233@gmail.com | Bangkok, Thailand |

No responses yet