For workloads with strict in-transit security requirements, configure and verify TLS protocol versions and cipher suites for Nginx Ingress Controller.
Prerequisites
Ensure the following:
-
Nginx Ingress Controller is installed and running in your cluster. See Manage Nginx Ingress Controller components.
-
kubectl is configured to connect to the cluster. See Connect to an ACK cluster using kubectl.
TLS encryption settings
Configure TLS protocol versions and cipher suites with the ssl-protocols and ssl-ciphers fields in the nginx-configuration ConfigMap under the kube-system namespace.
| Field | Description | Default value |
|---|---|---|
ssl-protocols |
The TLS protocol versions accepted by the ingress. TLS 1.2 and TLS 1.3 by default. See ssl-protocols. | TLSv1.2 TLSv1.3 |
ssl-ciphers |
The cipher suites accepted by the ingress, in OpenSSL format. The default cipher suites support multiple TLS clients. To use more restrictive suites, set ssl-ciphers in the ConfigMap to override the default. Order determines algorithm priority — defaults prioritize PFS-capable suites. See ssl-ciphers. | ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 |
Cipher suite order determines algorithm priority. The defaults prioritize PFS-capable suites — keep them unless you have specific security requirements.
After applying the configuration, verify it with testssl.sh or SSL Labs.
Update the ConfigMap
Console
-
Log on to the Container Service Management Console. In the left navigation pane, click Clusters.
-
On the Clusters page, click the name of your cluster. In the left navigation pane, choose Configurations > ConfigMaps.
-
On the ConfigMap page, select kube-system from the Namespace drop-down. Search for
nginx-configurationin the Name search box. Find nginx-configuration and click Edit in the Actions column. -
On the Edit page, click +Add. Enter the Name and Value, then click OK.
kubectl
Open the ConfigMap in your editor:
kubectl edit cm -n kube-system nginx-configuration
Add or update the ssl-protocols and ssl-ciphers fields:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-configuration
namespace: kube-system
data:
ssl-protocols: "TLSv1.2 TLSv1.3" # Only TLS 1.2 and TLS 1.3 are allowed.
ssl-ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384" # Default cipher suite list.
Verify TLS versions and cipher suites
Confirm the TLS configuration with either method.
-
Method 1: Download testssl.sh and run:
./testssl.sh <site-domain-name>Weak cipher suites or deprecated TLS versions are highlighted in red. Expected output for a correctly configured ingress:
Testing protocols via sockets except NPN+ALPN SSLv2 not offered (OK) SSLv3 not offered (OK) TLS 1 not offered TLS 1.1 not offered TLS 1.2 offered (OK) TLS 1.3 offered (OK): final NPN/SPDY not offered ALPN/HTTP2 h2, http/1.1 (offered) Testing cipher categories NULL ciphers (no encryption) not offered (OK) Anonymous NULL Ciphers (no authentication) not offered (OK) Export ciphers (w/o ADH+NULL) not offered (OK) LOW: 64 Bit + DES, RC[2,4] (w/o export) not offered (OK) Triple DES Ciphers / IDEA not offered Obsolete CBC ciphers (AES, ARIA etc.) not offered Strong encryption (AEAD ciphers) offered (OK) Testing robust (perfect) forward secrecy, (P)FS -- omitting Null Authentication/Encryption, 3DES, RC4 PFS is offered (OK) TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-CHACHA20-POLY1305 TLS_AES_128_GCM_SHA256 ECDHE-RSA-AES128-GCM-SHA256 Elliptic curves offered: prime256v1 secp384r1 secp521r1 X25519 X448 Finite field group: ffdhe2048 ffdhe3072 ffdhe4096 ffdhe6144 ffdhe8192 Testing server preferences Has server cipher order? yes (OK) -- TLS 1.3 and below Negotiated protocol TLSv1.3 Negotiated cipher TLS_AES_256_GCM_SHA384, 253 bit ECDH (X25519) Cipher order TLSv1.2: ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-CHACHA20-POLY1305 TLSv1.3: TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256 ... -
Method 2: Enter your domain in the SSL Labs SSL Server Test.
View configured cipher suites
View the active cipher suites in the Nginx configuration:
kubectl -n kube-system exec deploy/nginx-ingress-controller -- nginx -T | grep ssl_ciphers
Expected output:
Defaulted container "nginx-ingress-controller" out of: nginx-ingress-controller, init-sysctl (init)
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
nginx: configuration file /etc/nginx/nginx.conf test is successful
FAQ
Does Nginx Ingress Controller support Chinese cryptographic algorithms?
No. ACK Nginx Ingress Controller is based on the Kubernetes community ingress-nginx project and does not currently support Chinese cryptographic algorithms.
What cipher suites does Nginx Ingress support?
Nginx uses OpenSSL for encryption. To list available cipher suites, exec into the controller pod:
kubectl exec -it -n kube-system <nginx-ingress-pod-name> bash
Inside the container, run nginx -V to check the Nginx and OpenSSL versions:
nginx-ingress-controller-5c455d7d9f-nr7dd:/etc/nginx$ nginx -V
Expected output:
nginx version: nginx/1.21.6
built by gcc 12.2.1 20220924 (Alpine 12.2.1_git20220924-r10)
built with OpenSSL 3.1.3 19 Sep 2023 (running with OpenSSL 3.1.5 30 Jan 2024)
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --conf-path=/etc/nginx/nginx.conf --modules-path=/etc/nginx/modules --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-compat --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_geoip_module --with-http_gzip_static_module --with-http_sub_module --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_realip_module --with-stream_ssl_preread_module --with-threads --with-http_secure_link_module --with-http_gunzip_module --with-file-aio --without-mail_pop3_module --without-mail_smtp_module --without-mail_imap_module --without-http_uwsgi_module --without-http_scgi_module --with-cc-opt='-g -O3 -flto -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wno-deprecated-declarations -fno-strict-aliasing -D_FORTIFY_SOURCE=2 --param=ssp-buffer-size=4 -DTCP_FASTOPEN=23 -fPIC -I/root/.hunter/_Base/d45d77d/aab92d8/3b7ee27/Install/include -Wno-cast-function-type -m64 -mtune=generic' --with-ld-opt='-flto -fPIE -fPIC -pie -Wl,-z,relro -Wl,-z,now -L/root/.hunter/_Base/d45d77d/aab92d8/3b7ee27/Install/lib' --user=www-data --group=www-data --add-module=/tmp/build/ngx_devel_kit-0.3.2 --add-module=/tmp/build/set-misc-nginx-module-0.33 --add-module=/tmp/build/headers-more-nginx-module-0.34 --add-module=/tmp/build/ngx_http_substitutions_filter_module-b8a71eacc7f986ba091282ab8b1bbbc6ae1807e0 --add-module=/tmp/build/lua-nginx-module-0.10.25 --add-module=/tmp/build/stream-lua-nginx-module-0.0.13 --add-module=/tmp/build/lua-upstream-nginx-module-8aa93ead98ba2060d4efd594ae33a35d153589bf --add-dynamic-module=/tmp/build/nginx-http-auth-digest-1.0.0 --add-dynamic-module=/tmp/build/nginx-opentracing-0.19.0/opentracing --add-dynamic-module=/tmp/build/ModSecurity-nginx-1.0.3 --add-dynamic-module=/tmp/build/ngx_http_geoip2_module-a26c6beed77e81553686852dceb6c7fdacc5970d --add-dynamic-module=/tmp/build/ngx_brotli
Run openssl ciphers to list all supported cipher suites:
nginx-ingress-controller-5c455d7d9f-nr7dd:/etc/nginx$ openssl ciphers
Expected output:
TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:RSA-PSK-AES256-GCM-SHA384:DHE-PSK-AES256-GCM-SHA384:RSA-PSK-CHACHA20-POLY1305:DHE-PSK-CHACHA20-POLY1305:ECDHE-PSK-CHACHA20-POLY1305:AES256-GCM-SHA384:PSK-AES256-GCM-SHA384:PSK-CHACHA20-POLY1305:RSA-PSK-AES128-GCM-SHA256:DHE-PSK-AES128-GCM-SHA256:AES128-GCM-SHA256:PSK-AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:ECDHE-PSK-AES256-CBC-SHA384:ECDHE-PSK-AES256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-AES-256-CBC-SHA:RSA-PSK-AES256-CBC-SHA384:DHE-PSK-AES256-CBC-SHA384:RSA-PSK-AES256-CBC-SHA:DHE-PSK-AES256-CBC-SHA:AES256-SHA:PSK-AES256-CBC-SHA384:PSK-AES256-CBC-SHA:ECDHE-PSK-AES128-CBC-SHA256:ECDHE-PSK-AES128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:RSA-PSK-AES128-CBC-SHA256:DHE-PSK-AES128-CBC-SHA256:RSA-PSK-AES128-CBC-SHA:DHE-PSK-AES128-CBC-SHA:AES128-SHA:PSK-AES128-CBC-SHA256:PSK-AES128-CBC-SHA
Run openssl ciphers -tls1_2 -v to list TLS 1.2 cipher suites:
nginx-ingress-controller-5c455d7d9f-nr7dd:/etc/nginx$ openssl ciphers -tls1_2 -v
Expected output:
TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any Enc=AESGCM(256) Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
...
How do I get the OpenSSL name for an IANA/RFC cipher suite name?
Cipher suites have two naming conventions: OpenSSL (e.g., AES128-SHA) and IANA/RFC (e.g., TLS_RSA_WITH_AES_128_CBC_SHA).
To convert an IANA name to its OpenSSL equivalent, use either method:
-
Look up the mapping in the OpenSSL–IANA cipher name mapping table.
-
Run
openssl ciphers -convert <IANA-cipher-suite-name>inside the controller container. For example:nginx-ingress-controller-5c455d7d9f-nr7dd:/etc/nginx$ openssl ciphers -convert TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 OpenSSL cipher name: ECDHE-RSA-AES128-GCM-SHA256