Nginx Ingress Controller with Cloudflare Full (strict) SSL/TLS encryption + mTLS mode
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