docs: design notes for a Redfish/IPMI BMC driver

No code yet. The README explains why one Redfish driver with vendor quirk
modules beats a Supermicro-only IPMI driver, and keeps IPMI over LAN as a
read-only fallback. docs/ holds a draft for a new ManagementController
role base in napalm-device-types, the getter-to-resource map, the first
test device (Supermicro X10DRL-i, Redfish firmware 3.91), the security
points (IPMI RAKP hash disclosure, power control, credentials) and the
test plan with DMTF mockups and fixtures to record.
This commit is contained in:
Christian Manivong committed 2026-10-13 01:15:57 +02:00
commit 5f8a4ef975
9 files changed
+557

No files matched your search

+44
View File
@@ -0,0 +1,44 @@
# Getters mapped to Redfish resources
Paths use the usual single-member IDs (`Systems/1`, `Managers/1`, `Chassis/1`); the driver
must follow the collections instead of assuming IDs, because vendors differ (Dell uses
`System.Embedded.1`, HPE uses `1`, Supermicro uses `1`).
## Authentication
- **Session:** `POST /redfish/v1/SessionService/Sessions` with user and password returns
an `X-Auth-Token` header and the session's URI. Use the token, `DELETE` the session on
close. BMCs allow few concurrent sessions, so leaking them locks out the web UI.
- **Basic auth** works on most services and is the fallback.
- Self-signed certificates are the norm; verification is configurable per device.
## NAPALM getters
| Getter | Resource | Fields |
|---|---|---|
| `get_facts` | `Systems/{id}`, `Managers/{id}` | `Manufacturer`, `Model`, `SerialNumber`, `HostName`; BMC `FirmwareVersion` as `os_version`. `uptime` is not in Redfish (return -1). `interface_list` from `Managers/{id}/EthernetInterfaces` |
| `get_interfaces` | `Managers/{id}/EthernetInterfaces/*` | BMC ports: `MACAddress`, `SpeedMbps`, `LinkStatus`, `InterfaceEnabled` |
| `get_interfaces_ip` | same | `IPv4Addresses`, `IPv6Addresses` |
| `get_environment` | `Chassis/{id}/Thermal` (`Temperatures[]`, `Fans[]`), `Chassis/{id}/Power` (`PowerSupplies[]`, `PowerControl[].PowerConsumedWatts`) | Newer services move these to `ThermalSubsystem`, `PowerSubsystem` and `Sensors`; read whichever exists. CPU and memory of the host OS are unknown to a BMC |
| `get_users` | `AccountService/Accounts/*` | `UserName`, `RoleId`, `Enabled` |
| `get_ntp_servers` | `Managers/{id}/NetworkProtocol` | `NTP.NTPServers` (newer schema versions only) |
| `get_snmp_information` | `Managers/{id}/NetworkProtocol` | `SNMP.ProtocolEnabled` (details vary) |
| `get_config` | n/a | A BMC has no configuration file. Not implemented |
## Role methods (draft, see role.md)
| Method | Resource |
|---|---|
| `get_power_state` | `Systems/{id}`: `PowerState` |
| `set_power_state` | `POST Systems/{id}/Actions/ComputerSystem.Reset` with `ResetType`; allowed values from `ResetType@Redfish.AllowableValues` (or the `ActionInfo` resource) |
| `reboot_host` (the BMC) | `POST Managers/{id}/Actions/Manager.Reset` |
| `get_hardware_inventory` | `Systems/{id}` (`ProcessorSummary`, `MemorySummary`), `Systems/{id}/Processors/*`, `Systems/{id}/Memory/*`, `Systems/{id}/Storage/*` (older: `SimpleStorage`), `Chassis/{id}/Power` PSUs, `Systems/{id}/EthernetInterfaces/*` |
| `get_event_log` | `Systems/{id}/LogServices/*/Entries` or `Managers/{id}/LogServices/*/Entries` (where the SEL lives varies by vendor) |
| `get_firmware_inventory` | `UpdateService/FirmwareInventory/*`: `Name`, `Version`, `Updateable` |
| `get_management_protocols` | `Managers/{id}/NetworkProtocol`: `HTTP`, `HTTPS`, `SSH`, `IPMI`, `SNMP`, `KVMIP`, `VirtualMedia`, `SSDP`, each with `ProtocolEnabled` and `Port` |
## IPMI fallback (`ipmi` entry point)
Read-only, via `pyghmi`: device ID and FRU data for `get_facts`, sensor data repository for
`get_environment`, chassis status for `get_power_state`, SEL for `get_event_log`. No power
control over IPMI.
+46
View File
@@ -0,0 +1,46 @@
# References
Collected 2026-10-13.
## Standards and DMTF tools
| What | URL |
|---|---|
| DMTF Redfish standards page (specification, schemas, DSP2043 mockups) | https://www.dmtf.org/standards/redfish |
| Redfish publications (schemas, mockups) on GitHub | https://github.com/DMTF/Redfish-Publications |
| Redfish-Mockup-Server | https://github.com/DMTF/Redfish-Mockup-Server |
| Redfish-Mockup-Server Docker image | https://hub.docker.com/r/dmtf/redfish-mockup-server |
| Redfish-Service-Validator | https://github.com/DMTF/Redfish-Service-Validator |
| Redfish-Interop-Validator | https://github.com/DMTF/Redfish-Interop-Validator |
## Libraries
| Library | Use | License | Status (2026-10) |
|---|---|---|---|
| `redfish` (DMTF python-redfish-library) | thin Redfish client: sessions, GET/POST | BSD-3-Clause | release 3.4.1, 2026-10-09 |
| `sushy` (OpenStack) | object-model Redfish client | Apache-2.0 | active |
| `sushy-tools` (OpenStack) | Redfish emulator for tests | Apache-2.0 | active |
| `pyghmi` | IPMI over LAN, pure Python | Apache-2.0 | release 1.6.19, 2026-07-13 on PyPI (the GitHub mirror is archived) |
Choosing between the thin `redfish` client and `sushy` is open. The thin client keeps
quirk handling in this driver; `sushy` brings an object model but also its own assumptions
about Ironic's needs.
## Supermicro
| What | URL |
|---|---|
| BMC firmware for X10DRL-i (REDFISH_X10 3.91) | https://supermicro.com/en/support/resources/downloadcenter/firmware/MBD-X10DRL-i/BMC |
| Redfish Reference Guide (HTML, X12/H12 and later) | https://www.supermicro.com/manuals/other/redfish-ref-guide-html/ |
| Redfish Reference Guide 1.0a for X10 (third-party mirror) | https://update.shared.it/SUPERMICRO/X10DRL-I/IPMI/REDFISH_X10_327/Redfish_Ref_Guide_1%200a.pdf |
## Security
- CVE-2013-4786: IPMI 2.0 RAKP password hash disclosure.
## netOrk
- Discovery already fingerprints `idrac` and `ilo` by HTTP (`netork/jobs/tasks/discovery.py`),
without a driver. Supermicro BMCs are not fingerprinted yet.
- Default-credential audit: NetOrk/netork#141.
- Reachability recovery (a hung host could be power-cycled through its BMC): NetOrk/netork#938.
+70
View File
@@ -0,0 +1,70 @@
# Role base draft: `ManagementControllerDriver`
Draft for napalm-device-types. Nothing here is decided; the decisions are tracked in the
netOrk options issue.
## Why a new role
The existing role bases (`SwitchDriver`, `FirewallDriver`, `AccessPointDriver`,
`HypervisorDriver`, `StorageDriver`, `OSDriver`, `PhoneDriver`, `MediaDriver`,
`ResidentialGatewayDriver`) each describe what a device *is*. A BMC is a separate computer
with its own network port, IP and MAC that manages *another* machine: it reads that
machine's sensors and switches its power, whatever OS the machine runs. None of the
existing contracts fits, and borrowing one (e.g. `OSDriver`) would make netOrk offer
package updates and service control for a BMC.
## Sketch
```python
class ManagementControllerDriver(DeviceTypeDriver):
"""Contract, not code."""
ROLE: str = "management_controller" # key exposed as device_class
TYPE_LABEL: str = "Management Controller"
USES_SSH: bool = False # Redfish is HTTPS; IPMI is UDP
if TYPE_CHECKING:
# The managed machine
def get_power_state(self) -> PowerStateDict: ...
def set_power_state(self, action: PowerAction) -> None: ... # On, GracefulShutdown,
# ForceOff, GracefulRestart,
# ForceRestart, PowerCycle
def get_hardware_inventory(self) -> HardwareInventoryDict: ... # CPUs, DIMMs, drives,
# PSUs, NICs, serials
def get_event_log(self, limit: int = 500) -> List[EventLogEntryDict]: ... # SEL
# The controller itself
def get_firmware_inventory(self) -> List[FirmwareDict]: ... # BMC, BIOS, others
def get_management_protocols(self) -> ManagementProtocolsDict: ... # IPMI, SSH,
# HTTP(S), SNMP,
# KVM, virtual media
```
Points to settle in napalm-device-types:
- **`reboot_host` means the BMC.** `HostRebootMixin` says a driver restarts its *own*
host, never one it manages ("a hypervisor restarts the hypervisor, not a VM"). For a BMC
that is `Manager.Reset`; the managed server goes through `set_power_state`. A driver for
a BMC must not map `reboot_host` to the server.
- **Sensors.** NAPALM's `get_environment` already has fans, temperatures and power supplies.
It also requires CPU and memory, which a BMC does not know for the host OS. Either return
`get_environment` with those empty, or add a `get_sensors` that also carries voltages and
power draw. Prefer reusing `get_environment` if the empty fields are acceptable.
- **Health metrics.** `HealthMetricsMixin` is SNMP/UCD-MIB. A BMC's health comes from Redfish,
so this role does **not** mix it in. If netOrk needs `get_health_metrics` for BMCs, the
driver implements it from Redfish, as `SwitchDriver` drivers do from their own sources.
- **`CommandChannelMixin`** comes with `DeviceTypeDriver` but stays unimplemented: no shell.
- **Write capability by `hasattr`.** `set_power_state` exists only on drivers that can do it,
so the IPMI fallback (read-only) simply does not define it.
- **Models.** `PowerStateDict`, `HardwareInventoryDict`, `EventLogEntryDict`,
`FirmwareDict`, `ManagementProtocolsDict` go into `models.py`.
- **Fingerprinting.** An unauthenticated `GET /redfish/v1/` returns the service root
(`RedfishVersion`, `UUID`, `Vendor` on newer services) on every Redfish BMC. That is a
vendor-neutral `PORT_SPECS`/`HTTP_FINGERPRINT` rule and can replace the hand-written
`idrac`/`ilo` platform strings in netOrk's discovery.
## Relation to the managed server
A BMC is its own device in netOrk (own IP, own credentials, own firmware and CVEs), linked
to the host it manages. How to link them (matching the server's serial or system UUID from
`Systems/{id}` against the host's DMI data, or by hand) is a netOrk decision, not part of
this contract. The driver exposes the identifiers needed for matching:
`SerialNumber`, `UUID` and the host's MAC addresses from `Systems/{id}/EthernetInterfaces`.
+43
View File
@@ -0,0 +1,43 @@
# Security
A BMC can power a server off, mount virtual media and open a remote console. Its
credentials are worth as much as root on every machine it manages.
## Credentials
- Use a dedicated BMC account for netOrk, not the factory administrator. A read-only role
(Redfish `ReadOnly`) suffices for everything except power control, which needs
`Operator`.
- netOrk's credential gating applies unchanged: no job without credentials.
- Close Redfish sessions after each poll. BMCs allow few concurrent sessions, and a leaked
session can lock the web UI out.
## IPMI over LAN
- IPMI 2.0's RAKP handshake returns a salted hash of the user's password to any client that
names a valid user, before authentication (CVE-2013-4786). The hash can be cracked
offline. This is part of the protocol, not a bug a firmware update fixes.
- Cipher suite 0 (no authentication) is enabled on some BMCs and allows login with any
password.
- So the `ipmi` entry point is read-only and a fallback only. `get_management_protocols`
reporting `IPMI.ProtocolEnabled = true` should become a finding in netOrk, with the advice
to disable IPMI over LAN where Redfish is available.
## Power control
- `set_power_state` can take a production server down. In netOrk it needs a
`ConfirmDialog`, a permission of its own, and an audit log entry.
- `ForceOff`/`ForceRestart`/`PowerCycle` skip the OS shutdown; offer `GracefulShutdown`/
`GracefulRestart` first.
- `reboot_host` restarts only the BMC (`Manager.Reset`). The managed server keeps running.
## Firmware
BMC firmware versions from `UpdateService/FirmwareInventory` feed netOrk's vulnerability
management. Supermicro BMCs in particular have had serious published vulnerabilities, and
the X10 Redfish firmware line is no longer updated.
## Network placement
A BMC belongs in a management network that only administrators and netOrk can reach. A BMC
reachable from a user or guest VLAN is itself a finding for the segmentation checks.
+44
View File
@@ -0,0 +1,44 @@
# Supermicro X10 (first test device: X10DRL-i)
## Firmware
Supermicro shipped Redfish to X10 boards as a separate BMC firmware line, named
`REDFISH_X10_<version>`. For the X10DRL-i the latest is **3.91**
(`REDFISH_X10_391_20200806_unsigned.zip`) in Supermicro's download center. Other X10
boards have 3.86–3.90 from 2019–2020. Users report Redfish version 1.0.x on these
firmwares, so expect:
- the legacy `Chassis/{id}/Thermal` and `Power` resources, not `ThermalSubsystem`/`Sensors`,
- an older `ManagerNetworkProtocol` schema (NTP and SNMP details may be missing),
- fewer collections overall (storage details may be absent).
The X10 BMC firmware is unlikely to get further updates. For the driver that is useful
twice: it is the oldest Redfish the driver has to survive, and a real case for flagging
outdated BMC firmware in netOrk's vulnerability management.
Supermicro's **Redfish Reference Guide 1.0a** was published with the X10 Redfish firmware.
Supermicro's own HTML guide covers X12/H12 and later.
## Check before starting
```bash
# Service root, no login: Redfish version and available collections
curl -sk https://<bmc>/redfish/v1/ | python3 -m json.tool
# The managed server: model, serial, BIOS, power state
curl -sk -u <user>:<password> https://<bmc>/redfish/v1/Systems/1 | python3 -m json.tool
```
## Known Supermicro points (from memory, to verify on the device)
- Older Supermicro BMCs shipped with `ADMIN`/`ADMIN`; newer ones have a unique password on
a label. A BMC still on `ADMIN`/`ADMIN` is a test case for netOrk's default-credential
audit (NetOrk/netork#141).
- Some out-of-band features (BIOS update and BIOS settings through the BMC) need a
Supermicro license (SFT-OOB-LIC / SFT-DCMS-SINGLE). Reading and power control should not.
Which resources the X10 omits without a license shows up in the recorded responses.
- Vendor-specific data sits under `Oem.Supermicro` in several resources.
## IPMI on the same board
The X10DRL-i also speaks IPMI 2.0 over LAN (UDP 623), so the `ipmi` fallback can be tested on
the same device, and so can the check that reports IPMI over LAN as enabled.
+47
View File
@@ -0,0 +1,47 @@
# Testing
## Without hardware
- **DMTF mockups (DSP2043).** Complete Redfish service trees as static JSON, published by
the DMTF with each Redfish release (download from the Redfish standards page). They cover
the current schema: `ThermalSubsystem`, `PowerSubsystem`, `Sensors`, storage, logs, and
actions.
- **DMTF Redfish-Mockup-Server.** Serves a mockup over HTTP (`127.0.0.1:8000` by default),
also as a Docker image `dmtf/redfish-mockup-server`. Good for integration tests of the
transport (sessions, collections, actions).
- **OpenStack sushy-tools.** An emulator that serves mockups or drives libvirt VMs via Redfish,
so `set_power_state` can be tested against something that actually changes state.
- **DMTF Redfish-Mockup-Creator.** Records a live service into a mockup. It is the tool to
turn the X10DRL-i into a complete fixture set in one go.
Unit tests use recorded JSON responses directly; the mockup server is for a small set of
integration tests.
## Fixtures to record from the X10DRL-i
Store under `tests/fixtures/supermicro-x10drl-i-3.91/`, one file per request path, plus
`COMMANDS.txt` with the paths and the machine's state (powered on/off, fans present).
Scrub serial numbers, UUIDs, MACs and IPs before committing.
- [ ] `GET /redfish/v1/` (without login)
- [ ] `GET /redfish/v1/Systems` and each member
- [ ] `GET /redfish/v1/Systems/1/Processors` and each member
- [ ] `GET /redfish/v1/Systems/1/Memory` and each member
- [ ] `GET /redfish/v1/Systems/1/Storage` or `SimpleStorage`, whichever exists
- [ ] `GET /redfish/v1/Systems/1/EthernetInterfaces` and each member
- [ ] `GET /redfish/v1/Systems/1/LogServices` and the entries of each
- [ ] `GET /redfish/v1/Chassis` and each member
- [ ] `GET /redfish/v1/Chassis/1/Thermal`
- [ ] `GET /redfish/v1/Chassis/1/Power`
- [ ] `GET /redfish/v1/Managers/1`
- [ ] `GET /redfish/v1/Managers/1/EthernetInterfaces` and each member
- [ ] `GET /redfish/v1/Managers/1/NetworkProtocol`
- [ ] `GET /redfish/v1/Managers/1/LogServices` and the entries of each
- [ ] `GET /redfish/v1/AccountService` and `AccountService/Accounts`
- [ ] `GET /redfish/v1/UpdateService/FirmwareInventory` and each member
- [ ] `POST /redfish/v1/SessionService/Sessions` response headers (token redacted)
- [ ] the error body of a request without credentials and of a wrong path
- [ ] `ResetType@Redfish.AllowableValues` from `Systems/1`
- [ ] IPMI: FRU, sensor list, chassis status, SEL (via `ipmitool` for comparison with `pyghmi`)
Or run the Redfish-Mockup-Creator once against the BMC and keep its output.