Skip to content

CNTRLPLANE-3973: Make sure unencrypted metrics bind to localhost only, and remove dead code - #6350

Open
vincentdephily wants to merge 2 commits into
openshift:mainfrom
vincentdephily:vdp-metrics-tls
Open

CNTRLPLANE-3973: Make sure unencrypted metrics bind to localhost only, and remove dead code#6350
vincentdephily wants to merge 2 commits into
openshift:mainfrom
vincentdephily:vdp-metrics-tls

Conversation

@vincentdephily

@vincentdephily vincentdephily commented Jul 30, 2026

Copy link
Copy Markdown

- What I did

  • Added checks so that the unencrypted /metrics endpoint only binds localhost (kube-rbac-proxy is responsible for exposing the TLS endpoint)
  • Removed dead code that failed to encrypt that base endpoint
  • Deprecated MCC and MCD cli flags that failed to configure tls minversion and ciphersuites for the metrics endpoint (kube-rbac-proxy was only looking at the APIserver settings)

- How to verify it
There should be no behaviour change apart from the deprecated cli flags, this is a code cleanup.

- Description for the changelog
Deprecated ineffective --tls-cipher-suites and --tls-min-version flags of machine-config-controller and machine-config-daemon: the metrics TLS config is always fecthed from the APIServer.

Summary by CodeRabbit

  • Changes
    • Metrics /metrics endpoint is now served localhost-only and unencrypted by default.
    • Metrics listener TLS configuration has been removed; TLS cipher-suite and minimum-version flags are deprecated and no longer affect metrics.
    • Updated controller/daemon startup arguments to align with the simplified metrics configuration.
  • Operational Improvements
    • Controller/daemon lifecycles now rely on the main context cancellation for shutdown behavior.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 30, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@vincentdephily: This pull request references CNTRLPLANE-3973 which is a valid jira issue.

Details

In response to this:

- What I did

  • Added checks so that the unencrypted /metrics endpoint only binds localhost (kube-rbac-proxy is responsible for exposing the TLS endpoint)
  • Removed dead code that failed to encrypt that base endpoint
  • Deprecated MCC and MCD cli flags that failed to configure tls minversion and ciphersuites for the metrics endpoint (kube-rbac-proxy was only looking at the APIserver settings)

- How to verify it
There should be no behaviour change apart from the deprecated cli flags, this is a code cleanup.

- Description for the changelog
Deprecated ineffective --tls-cipher-suites and --tls-min-version flags of machine-config-controller and machine-config-daemon: the metrics TLS config is always fecthed from the APIServer.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 30, 2026
@openshift-ci

openshift-ci Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: vincentdephily
Once this PR has been reviewed and has the lgtm label, please assign yuqi-zhang for approval. For more information see the Code Review Process.

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

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@vincentdephily, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 31 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ad36c5c8-705f-47cd-a0d0-ad2b222dd472

📥 Commits

Reviewing files that changed from the base of the PR and between 10482b0 and f6a6dec.

📒 Files selected for processing (4)
  • cmd/machine-config-controller/start.go
  • cmd/machine-config-daemon/start.go
  • manifests/machineconfigcontroller/deployment.yaml
  • manifests/machineconfigdaemon/daemonset.yaml

Walkthrough

Metrics listeners now bind to localhost by default, reject non-loopback addresses, and run without configurable TLS settings. Controller and daemon startup wiring plus deployment manifests were updated to use the simplified listener configuration.

Changes

Metrics Listener Simplification

Layer / File(s) Summary
Local metrics listener contract
pkg/controller/common/metrics.go
The default bind address is localhost, listener inputs no longer include TLS settings, loopback addresses are validated, and the HTTP server starts without TLS configuration.
Controller and daemon startup wiring
cmd/machine-config-controller/start.go, cmd/machine-config-daemon/start.go
Startup options no longer store metrics TLS settings; metrics defaults use DefaultMetricsBindAddress, TLS flags are deprecated, and listener calls use the reduced signature.
Deployment argument and scheduling updates
manifests/machineconfigcontroller/deployment.yaml, manifests/machineconfigdaemon/daemonset.yaml
Container arguments no longer pass metrics TLS flags, and the controller pod gains a control-plane NoSchedule toleration.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: cheesesashimi, isabella-janssen, djoshy

🚥 Pre-merge checks | ✅ 15
✅ Passed checks (15 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: localhost-only unencrypted metrics binding and removal of dead code.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed PASS: The PR only changes controller/daemon startup and manifests; no *_test.go files or Ginkgo titles were added or modified.
Test Structure And Quality ✅ Passed No Ginkgo test code was added or modified; this PR only changes start commands and manifests, so the checklist is not applicable.
Microshift Test Compatibility ✅ Passed No new Ginkgo/e2e tests were added; touched files are CLI/manifests only and contain no It/Describe/Context or MicroShift-skipped tags.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the PR only changes CLI flags, metrics wiring, and manifests, so there’s no SNO-specific test risk.
Topology-Aware Scheduling Compatibility ✅ Passed PASS: The commit only removes TLS args/deprecates flags; no new nodeSelectors, affinity, replicas, or PDBs were introduced.
Ote Binary Stdout Contract ✅ Passed No process-level stdout writes were introduced; startup paths set logtostderr=true, and the new metrics listener uses only klog logging.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; PR only changes start/metrics code and manifests, so this compatibility check is not applicable.
No-Weak-Crypto ✅ Passed No weak-crypto primitives or custom crypto/comparison code were added; the patch only removes TLS flag plumbing and enforces localhost metrics binding.
Container-Privileges ✅ Passed Diff only removes TLS args; no new privileged, hostPID/hostNetwork, or allowPrivilegeEscalation settings were added in the touched manifests.
No-Sensitive-Data-In-Logs ✅ Passed The patch only removes TLS flags/args; no logging changes were introduced, and metrics.go wasn’t part of the actual diff.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

The `/metrics` endpoint is set up to be served unencrypted on localhost:8797 and proxied on *:9637
via kube-rbac-proxy. There were attempts to serve encrypted metrics in
0e8aab3 and 3db3e26, but neither
actually switched to `ListenAndServeTLS()`.

Don't try to serve TLS: just depend on the proxy and make sure that we're only binding to localhost.

CNTRLPLANE-3973: machine-config-operator not respecting global TLS Profile
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 30, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/controller/common/metrics.go`:
- Around line 146-152: Update the validation logging around net.SplitHostPort
and the loopback check to avoid including the operator-configured addr value,
which may expose internal hostnames. Log only generic validation-failure
messages or a redacted representation, while preserving the existing early
return and localhost enforcement behavior.
- Around line 163-166: Update the HTTP server setup in the metrics listener to
configure appropriate request deadlines, including ReadHeaderTimeout, and
replace the unbounded Shutdown(context.Background()) call with a context.Context
that has a finite timeout. Ensure shutdown uses that bounded context and is
properly canceled.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 613fc20f-0f64-45bb-a4ed-7c42252de4bf

📥 Commits

Reviewing files that changed from the base of the PR and between 22961b3 and ea37bf1.

📒 Files selected for processing (5)
  • cmd/machine-config-controller/start.go
  • cmd/machine-config-daemon/start.go
  • manifests/machineconfigcontroller/deployment.yaml
  • manifests/machineconfigdaemon/daemonset.yaml
  • pkg/controller/common/metrics.go
💤 Files with no reviewable changes (2)
  • manifests/machineconfigdaemon/daemonset.yaml
  • manifests/machineconfigcontroller/deployment.yaml

Comment on lines +146 to +152
host, _, err := net.SplitHostPort(addr)
if err != nil {
klog.Errorf("invalid metrics listen address %q: %v", addr, err)
return
}
if ip := net.ParseIP(host); ip == nil || !ip.IsLoopback() {
klog.Errorf("metrics is listening on %q, it should listen on localhost and be exposed via a TLS proxy", addr)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Avoid logging raw rejected listener addresses.

addr is operator-configurable; invalid values may contain internal hostnames and are written directly to logs. Redact the address or log only the validation failure.

As per coding guidelines, “Flag logging that may expose … internal hostnames.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/controller/common/metrics.go` around lines 146 - 152, Update the
validation logging around net.SplitHostPort and the loopback check to avoid
including the operator-configured addr value, which may expose internal
hostnames. Log only generic validation-failure messages or a redacted
representation, while preserving the existing early return and localhost
enforcement behavior.

Source: Coding guidelines

Comment on lines +163 to +166
klog.Infof("Starting metrics listener on %s", addr)
mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.Handler())
s := http.Server{
TLSConfig: tlsConfig,
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler)),
Addr: addr,
Handler: mux}
s := http.Server{Addr: addr, Handler: mux}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Bound request and shutdown time.

Without ReadHeaderTimeout, a same-pod client can retain connections while sending headers indefinitely; Shutdown(context.Background()) can then also wait forever. Configure server deadlines and use a bounded shutdown context.

As per path instructions, “context.Context for cancellation and timeouts.”

🧰 Tools
🪛 ast-grep (0.45.0)

[warning] 165-165: This http.Server is constructed without a ReadTimeout. Without a read timeout, a slow or malicious client can hold connections open indefinitely (e.g. a Slowloris attack), exhausting server resources and causing a denial of service. Set ReadTimeout (and ideally ReadHeaderTimeout, WriteTimeout, and IdleTimeout) on the http.Server to bound how long the server waits while reading a request.
Context: http.Server{Addr: addr, Handler: mux}
Note: [CWE-400] Uncontrolled Resource Consumption.

(http-server-missing-read-timeout-go)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/controller/common/metrics.go` around lines 163 - 166, Update the HTTP
server setup in the metrics listener to configure appropriate request deadlines,
including ReadHeaderTimeout, and replace the unbounded
Shutdown(context.Background()) call with a context.Context that has a finite
timeout. Ensure shutdown uses that bounded context and is properly canceled.

Sources: Path instructions, Linters/SAST tools

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/machine-config-controller/start.go`:
- Around line 59-60: The TLS flags are missing before MarkDeprecated is called,
and both errors are discarded. In cmd/machine-config-controller/start.go lines
59-60 and cmd/machine-config-daemon/start.go lines 60-61, register compatible
no-op flags named tls-cipher-suites and tls-min-version, then handle the errors
returned by each MarkDeprecated call so both binaries continue accepting and
deprecating these flags.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6427b432-15c3-47ae-9efd-906039959a1e

📥 Commits

Reviewing files that changed from the base of the PR and between ea37bf1 and 10482b0.

📒 Files selected for processing (5)
  • cmd/machine-config-controller/start.go
  • cmd/machine-config-daemon/start.go
  • manifests/machineconfigcontroller/deployment.yaml
  • manifests/machineconfigdaemon/daemonset.yaml
  • pkg/controller/common/metrics.go
💤 Files with no reviewable changes (1)
  • manifests/machineconfigdaemon/daemonset.yaml

Comment thread cmd/machine-config-controller/start.go Outdated
…C and MCD

These flags were a noop in practice (see 42c60ca), and there is no
need to support them.

CNTRLPLANE-3973: machine-config-operator not respecting global TLS Profile
@openshift-ci

openshift-ci Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@vincentdephily: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@kaleemsiddiqu

Copy link
Copy Markdown

/verified by @kaleemsiddiqu
Local run of tests with this change went successful.

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Aug 5, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@kaleemsiddiqu: This PR has been marked as verified by @kaleemsiddiqu.

Details

In response to this:

/verified by @kaleemsiddiqu
Local run of tests with this change went successful.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@kaleemsiddiqu

Copy link
Copy Markdown

/verified remove

@openshift-ci-robot openshift-ci-robot removed the verified Signifies that the PR passed pre-merge verification criteria label Aug 5, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@kaleemsiddiqu: The verified label has been removed.

Details

In response to this:

/verified remove

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

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

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants