Skip to content

[cherry-pick: release-v0.80.x] fix(consoleplugin): translate IANA ciphers to OpenSSL for nginx#3655

Open
tekton-robot wants to merge 1 commit into
release-v0.80.xfrom
cherry-pick-3639-to-release-v0.80.x
Open

[cherry-pick: release-v0.80.x] fix(consoleplugin): translate IANA ciphers to OpenSSL for nginx#3655
tekton-robot wants to merge 1 commit into
release-v0.80.xfrom
cherry-pick-3639-to-release-v0.80.x

Conversation

@tekton-robot

Copy link
Copy Markdown
Contributor

This is a cherry-pick of #3639


Summary

  • Resolves tls-scanner TC08 finding: pipelines-console-plugin nginx was not honoring the cluster cipher suite (Intermediate profile) — api_server_tls_config_compliance.ciphers=false
  • Adds ianaToOpenSSLCiphers() to translate IANA cipher suite names (from the OpenShift APIServer TLS profile) to the OpenSSL names required by nginx's ssl_ciphers directive
  • The mapping is derived by inverting library-go's openSSLToIANACiphersMap — the canonical source of truth for OpenShift profile ciphers
  • TLS 1.3 ciphers (TLS_AES_*, TLS_CHACHA20_*) are intentionally skipped: nginx/OpenSSL negotiates them automatically when TLSv1.3 is in ssl_protocols
  • ssl_prefer_server_ciphers on; is emitted alongside ssl_ciphers so the cluster-defined ordering is respected

Context

Part of the central TLS management work (SRVKP-9632). The console plugin already:

  • fetches the APIServer TLS profile dynamically
  • applies ssl_protocols and ML-KEM PQC groups (ssl_conf_command Groups X25519MLKEM768:X25519)

This PR adds the missing ssl_ciphers piece.

Behaviour when APIServer cipher list is nil

When no explicit tlsSecurityProfile is set on APIServer/cluster, the operator receives a nil cipher list and writes no ssl_ciphers directive. Nginx then falls back to its built-in default (HIGH:!aNULL:!MD5), which on RHEL/OpenSSL 3.x expands to ~131 cipher suites — far broader than any OpenShift TLS profile.

This is intentional and consistent with all other Pipelines components: propagate what the APIServer provides, never invent a fallback cipher list. Production OpenShift clusters always carry an explicit TLS profile (the platform default is Intermediate, confirmed by library-go: DefaultTLSProfileType = TLSProfileIntermediateType). A cluster with no profile set is misconfigured from a compliance standpoint — the operator should not silently mask that.

To reproduce real production conditions, explicitly set the Intermediate profile:

oc patch apiserver cluster --type=merge \
  -p '{"spec":{"tlsSecurityProfile":{"type":"Intermediate","intermediate":{}}}}'

Cluster validation evidence

APIServer set to Intermediate profile. The nginx ConfigMap is generated with exactly the 6 TLS 1.2 Intermediate ciphers:

ssl_protocols TLSv1.2 TLSv1.3;
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;
ssl_prefer_server_ciphers on;
ssl_conf_command Groups X25519MLKEM768:X25519;

Live TLS handshake tests:

Test Result
TLS 1.2 + ECDHE-RSA-AES128-GCM-SHA256 (Intermediate cipher) ✅ Negotiated
TLS 1.2 + AES256-SHA (Old-profile-only cipher) ✅ Rejected (handshake failure, Cipher: NONE)

Test plan

  • Deploy operator to an OCP cluster with Intermediate profile explicitly set
  • Confirm nginx.conf contains the Intermediate cipher set from the API server
  • Verify Intermediate ciphers are accepted and non-profile ciphers are rejected
  • Run tls-scanner and confirm TC08 passes

Relates-To: SRVKP-9632

Apply cluster cipher suites to the nginx ssl_ciphers directive by
translating IANA cipher suite names (used by OpenShift TLS profiles)
to their OpenSSL equivalents required by nginx.

The mapping is derived by inverting library-go's
openSSLToIANACiphersMap (the canonical source of truth for
OpenShift TLS profile ciphers). TLS 1.3 ciphers are intentionally
excluded since nginx/OpenSSL negotiates them automatically when
TLSv1.3 appears in ssl_protocols.

This resolves the tls-scanner TC08 finding where the console plugin
nginx was not honoring the cluster cipher suite (Intermediate profile).

Relates-To: SRVKP-9632

Signed-off-by: Jawed khelil <jkhelil@redhat.com>
Assisted-by: Claude Sonnet 4.6 (via Cursor)
Co-authored-by: Cursor <cursoragent@cursor.com>
@tekton-robot tekton-robot added the do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. label Jul 2, 2026
@tekton-robot

Copy link
Copy Markdown
Contributor Author

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
To complete the pull request process, please assign anithapriyanatarajan after the PR has been reviewed.
You can assign the PR to them by writing /assign @anithapriyanatarajan in a comment when ready.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@tekton-robot tekton-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Jul 2, 2026
@jkhelil

jkhelil commented Jul 2, 2026

Copy link
Copy Markdown
Member

/release-note-none

@tekton-robot tekton-robot added release-note-none Denotes a PR that doesnt merit a release note. and removed do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. labels Jul 2, 2026
@jkhelil

jkhelil commented Jul 2, 2026

Copy link
Copy Markdown
Member

/retest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-note-none Denotes a PR that doesnt merit a release note. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants