{"id":51620750,"url":"https://github.com/bitwire-it/hpe-ilo-fan-watch","last_synced_at":"2026-07-12T19:01:01.236Z","repository":{"id":365731652,"uuid":"1273490496","full_name":"bitwire-it/HPE-iLO-Fan-Watch","owner":"bitwire-it","description":"Interactive installer and systemd-based thermal watchdog for **HPE Gen11 servers** using the **iLO Redfish API** to reduce unnecessary fan noise while preserving safe thermal behavior.","archived":false,"fork":false,"pushed_at":"2026-06-18T15:36:42.000Z","size":19,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-18T17:20:00.829Z","etag":null,"topics":["cpu","debian","fan-control","fancontrol","hpe","linux","linux-server","linux-shell","proliant","proxmox","proxmox-api","proxmox-backup-server","proxmox-cluster","proxmox-infrastructure","proxmox-tools","proxmox-ve","proxmoxve","server","thermal","thermal-management"],"latest_commit_sha":null,"homepage":"https://bitwire.it","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bitwire-it.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-18T15:16:25.000Z","updated_at":"2026-06-18T15:40:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bitwire-it/HPE-iLO-Fan-Watch","commit_stats":null,"previous_names":["bitwire-it/hpe-ilo-fan-watch"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/bitwire-it/HPE-iLO-Fan-Watch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwire-it%2FHPE-iLO-Fan-Watch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwire-it%2FHPE-iLO-Fan-Watch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwire-it%2FHPE-iLO-Fan-Watch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwire-it%2FHPE-iLO-Fan-Watch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitwire-it","download_url":"https://codeload.github.com/bitwire-it/HPE-iLO-Fan-Watch/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwire-it%2FHPE-iLO-Fan-Watch/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35400291,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-12T02:00:06.386Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpu","debian","fan-control","fancontrol","hpe","linux","linux-server","linux-shell","proliant","proxmox","proxmox-api","proxmox-backup-server","proxmox-cluster","proxmox-infrastructure","proxmox-tools","proxmox-ve","proxmoxve","server","thermal","thermal-management"],"created_at":"2026-07-12T19:00:59.977Z","updated_at":"2026-07-12T19:01:01.231Z","avatar_url":"https://github.com/bitwire-it.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# **HPE iLO Fan-Watch Installer**\n\nAn interactive installer and systemd-based thermal watchdog for **HPE ProLiant Gen10/Gen11 servers**. It uses HPE's **official Python Redfish tooling** (`python-ilorest-library` — the same engine behind the `ilorest` RESTful Interface Tool) to optimize fan speeds and reduce unnecessary noise while maintaining safe thermal operating limits.\n\nThis tool is designed for deployments where the host OS lacks a compatible HPE AMS/AMSD package path, but iLO Redfish access is available and the platform supports the `Oem.Hpe.FanPercentAdjust` property on the thermal endpoint. It uses **only supported Redfish APIs** — no firmware modifications, no unsupported binary patching, no fan hacks.\n\n## **Overview**\n\nThe installer configures a local service that monitors the iLO thermal endpoint, evaluates designated hardware sensors, and dynamically updates the `FanPercentAdjust` value based on real-time temperature data.\n\n### **Operational Workflow**\n\n* **quiet:** Applied when all monitored sensors remain below warning thresholds.\n* **normal:** Applied when one or more sensors cross a warning threshold.\n* **safe:** Enforced immediately if any sensor crosses a critical threshold, or if Redfish connectivity fails repeatedly (see **Max failures**).\n\nThe service is engineered to **fail-safe**. Escalation to maximum cooling occurs instantly, while de-escalation back to quieter modes uses hysteresis to prevent rapid fan speed oscillation (fan flapping). If the service stops for any reason, fans revert to full firmware control by default.\n\n## **Problem Statement**\n\nOn certain HPE platforms — particularly those running unsupported operating systems or non-standard hardware configurations — system fans may run at unnecessarily aggressive speeds despite healthy thermals. This project offers a host-side mitigation via Redfish, removing any operational dependency on the AMSD daemon.\n\n## **Security Model**\n\nSecurity is a first-class concern in this tool:\n\n* **Always-verified TLS.** The installed service never uses `--insecure`. During setup the installer pins the iLO's certificate (or you supply a trusted CA/PEM path), and every Redfish call is verified against it via the official library's `cafile`.\n* **No cleartext credentials.** Service credentials are stored as **encrypted systemd credentials** (`systemd-creds encrypt`, systemd ≥ 250, host/TPM-bound) when available, and delivered to the unit via `LoadCredentialEncrypted=`. On older systems they fall back to a **root-only `0400` environment file**, with a warning suggesting integration with a secrets manager (e.g. HashiCorp Vault). The generated config file contains **no** secrets.\n* **Least privilege.** The dedicated iLO service account is provisioned with only **Login** and **Configure iLO Settings** privileges.\n* **Hardened unit.** The systemd service runs with `ProtectSystem=strict`, `ProtectHome`, `PrivateTmp`, `NoNewPrivileges`, a managed `StateDirectory`, and a `WatchdogSec` health check.\n* **Explicit permissions.** All files are written with strict, explicit modes (secrets `0400`, config `0600`).\n\n## **Features**\n\n* **Official tooling:** All iLO I/O runs through HPE's official `python-ilorest-library` (module `redfish`) via an embedded control-plane helper.\n* **Interactive setup:** Driven by a `whiptail`-based terminal UI.\n* **Cross-distro dependency management:** Installs prerequisites on **Debian/Ubuntu (apt), RHEL/Rocky/Fedora (dnf/yum), and OpenSUSE Leap (zypper)**. Fails cleanly with a useful list on unknown package managers.\n* **TLS certificate pinning:** Fetches and displays the iLO certificate fingerprint for confirmation, then pins it for all future calls.\n* **Encrypted credential storage:** `systemd-creds` encryption with a root-only fallback.\n* **Account automation:** Provisions or reuses a least-privilege iLO service account, with automatic cleanup of an orphaned account if setup is aborted.\n* **Compatibility guard:** Probes the iLO generation and `FanPercentAdjust` capability and warns clearly if the platform cannot be driven.\n* **Dynamic inventory:** Discovers and parses the live sensor list directly from iLO prior to configuration.\n* **Granular control:** Custom sensor selection with per-sensor warning and critical thresholds, configurable poll interval, fan-bias tuning, and a configurable failure threshold (1–10).\n* **Persistent, watchdog-protected service:** A dedicated systemd unit with `sd_notify` keepalive, local state caching to avoid redundant PATCH requests, re-assert-on-start, and revert-on-exit (default ON).\n* **Diagnostics:** A formatted `--status` dashboard and a `--dry-run` mode.\n* **Lifecycle management:** Detects existing installs and offers reconfigure, edit, restart, status, logs, and uninstall (optionally deleting the iLO account).\n* **Version tracking:** An embedded `VERSION` is written to the config and shown in the management menu.\n\n## **Technical Architecture**\n\nThe background daemon monitors the following iLO endpoint:\n\n`https://\u003cILO_HOST\u003e/redfish/v1/Chassis/1/Thermal/`\n\nThe script extracts and processes:\n\n* `Temperatures[]` for monitored sensor tracking.\n* `Fans[]` to report current RPM metrics.\n* `Oem.Hpe.FanPercentAdjust` to modify fan behavior.\n\nAll requests are made by the embedded Python helper (`redfish_ctl.py`), which logs into iLO with a verified TLS session and returns a clean JSON envelope to the Bash monitor.\n\n### **Operating Modes**\n\n| State | Target Behavior | Default FanPercentAdjust Value |\n| :---- | :---- | :---- |\n| quiet | Maximum noise reduction when thermals are optimal. | 50 |\n| normal | Moderate cooling enhancement upon crossing warning limits. | 25 |\n| safe | Standard firmware control; zero offset bias during critical events or failures. | 0 |\n\n*Note: Per HPE iLO logic, higher offset values translate to a quieter fan profile within this service's architecture.*\n\n## **Recommended Sensors \u0026 Default Thresholds**\n\nThe installer pre-selects the following reference sensors when detected on the host:\n\n| Sensor | Warning Threshold | Critical Threshold |\n| :---- | ----: | ----- |\n| 01-Inlet Ambient | 35°C | 40°C |\n| 02-CPU 1 PkgTmp | 75°C | 85°C |\n| 05-Chipset | 75°C | 85°C |\n| 17-BMC | 75°C | 85°C |\n| 20-PCI 1 Zone | 65°C | 75°C |\n| 21-M2 Zone | 60°C | 70°C |\n| 22-Sys Exhaust 1 | 55°C | 65°C |\n\n## **Requirements**\n\n* HPE ProLiant Gen10/Gen11 server with active Redfish network access (iLO 5/6).\n* Functional Redfish endpoint at `/redfish/v1/Chassis/1/Thermal/` exposing `Oem.Hpe.FanPercentAdjust`.\n* Root privileges on the target host OS.\n* One of: Debian/Ubuntu, RHEL/Rocky, Fedora, or OpenSUSE Leap.\n\nThe installer automatically installs its prerequisites: `whiptail`/`newt`, `curl`, `jq`, `openssl`, `python3`, `python3-pip`, and HPE's `python-ilorest-library`.\n\n\u003e **TLS note:** Verification succeeds cleanly when you connect using the name or IP present in the iLO certificate's subject/SAN. If the default iLO certificate does not include the IP you connect by, connect via the certificate's hostname or regenerate the iLO certificate with the correct SAN — the service intentionally does **not** weaken verification.\n\n## **Installation \u0026 First Run**\n\nExecute the installer script with root privileges:\n\n```\nchmod +x hpe-fan-watch-installer.sh\nsudo ./hpe-fan-watch-installer.sh\n```\n\n### **Setup Wizard Steps**\n\n1. **Target definition:** Specify the iLO hostname or IP address.\n2. **TLS pinning:** Fetch and confirm the iLO certificate fingerprint (or supply a trusted CA/PEM path).\n3. **Credentials:** Generate a dedicated least-privilege iLO service account or input existing credentials.\n4. **Compatibility check:** Probe iLO generation and `FanPercentAdjust` availability.\n5. **Sensor selection:** Choose specific hardware sensors to track.\n6. **Threshold definition:** Set warning and critical temperature targets.\n7. **Polling frequency:** Set the monitoring interval.\n8. **Tuning:** Adjust baseline values for quiet, normal, and safe modes.\n9. **Failure threshold:** Set how many consecutive Redfish failures force SAFE (1–10).\n10. **Policy:** Configure re-assert-on-start, revert-on-exit (default ON), and journal logging.\n\n## **Existing Installation Management**\n\nIf the installer detects existing components, it routes to an interactive management menu:\n\n| Menu Option | Action Performed |\n| :---- | :---- |\n| **Reconfigure** | Falls through to the full setup wizard. |\n| **Edit config** | Opens the config in `$VISUAL` → `$EDITOR` → `nano`/`vim`/`vi`; offers to restart afterward. |\n| **Restart service** | Runs `systemctl restart` and reports status. |\n| **Show status** | Runs `hpe-fan-watch.sh --status` and displays the dashboard in a scrollable box. |\n| **Tail logs** | Drops to `journalctl -u … -n 40 -f`; Ctrl+C returns to the menu. |\n| **Uninstall** | Comprehensive teardown (see below). |\n\n### **Teardown Sequence**\n\n1. Double-confirmation safety prompt.\n2. Stops and disables the systemd service (failures surfaced via `whiptail`).\n3. **Optionally deletes the iLO service account** via Redfish, after prompting for an iLO administrator login.\n4. Deletes all installed files: monitor, unit, config, credentials, pinned certificate, and helper.\n5. Triggers `systemctl daemon-reload`.\n6. Offers to purge the state directory (`/var/lib/hpe-fan-watch`).\n\n## **File System Footprint**\n\n| Path | Purpose | Mode |\n| :---- | :---- | :---- |\n| `/usr/local/sbin/hpe-fan-watch.sh` | Core monitor script | `0750` |\n| `/usr/local/lib/hpe-fan-watch/redfish_ctl.py` | Official-library control-plane helper | `0755` |\n| `/etc/systemd/system/hpe-fan-watch.service` | Systemd unit (watchdog-protected) | `0644` |\n| `/etc/hpe-fan-watch/config` | Configuration (no secrets) | `0600` |\n| `/etc/hpe-fan-watch/ilo.crt` | Pinned iLO TLS certificate | `0644` |\n| `/etc/hpe-fan-watch/ilo.cred` | Encrypted credentials (`systemd-creds` mode) | `0400` |\n| `/etc/hpe-fan-watch/ilo.env` | Root-only credentials (fallback mode) | `0400` |\n| `/var/lib/hpe-fan-watch/` | State/cache directory | `0750` |\n\n## **CLI Usage Modes**\n\nThe core script supports manual execution via the following flags:\n\n```\n# Run a single evaluation cycle and exit\n/usr/local/sbin/hpe-fan-watch.sh --once\n\n# Run continuously as a daemon (handled by systemd)\n/usr/local/sbin/hpe-fan-watch.sh --daemon\n\n# Print the formatted sensor/fan status dashboard\n/usr/local/sbin/hpe-fan-watch.sh --status\n\n# Evaluate and log without writing anything to the iLO\n/usr/local/sbin/hpe-fan-watch.sh --dry-run --once\n```\n\n## **Limitations \u0026 Disclaimer**\n\n* **Support status:** This software operates independently as a Redfish-based workaround and is not an officially supported HPE AMSD deployment.\n* **Firmware compliance:** Proper execution depends on the firmware accepting `Oem.Hpe.FanPercentAdjust`. iLO 4 (Gen8/Gen9) does not expose this control; the installer warns when it cannot be driven.\n* **Validation requirement:** Validate system thermals under sustained production workloads before deploying aggressive noise-reduction profiles.\n\n**Use at your own risk.** Changing fan profiles impacts hardware cooling. Thoroughly test configurations against your environmental profiles and firmware baselines before broad production rollouts.\n\n## **License**\n\nThis project is open-source. Insert your preferred licensing terms here (e.g., MIT, GPLv3).\n\n### **Screenshot**\n\n\u003cimg width=\"755\" height=\"462\" alt=\"Setup\" src=\"https://github.com/user-attachments/assets/55449ffa-6f17-4926-b116-f11352a00f65\" /\u003e\n\u003cimg width=\"755\" height=\"403\" alt=\"Setup2\" src=\"https://github.com/user-attachments/assets/7f4cd0fa-5c69-480f-b749-ac8eaebd48ef\" /\u003e\n\u003cimg width=\"755\" height=\"402\" alt=\"Setup3\" src=\"https://github.com/user-attachments/assets/955f9235-8923-4b9e-916e-abe5373f9c8e\" /\u003e\n\u003cimg width=\"755\" height=\"522\" alt=\"Setup4\" src=\"https://github.com/user-attachments/assets/b69213b7-81a8-4d50-8788-ce7e5ee37f41\" /\u003e\n\u003cimg width=\"755\" height=\"478\" alt=\"Setup5\" src=\"https://github.com/user-attachments/assets/e90dd1a6-ecd4-4cfe-a7bc-4abafd313f46\" /\u003e\n\u003cimg width=\"755\" height=\"581\" alt=\"Setup6\" src=\"https://github.com/user-attachments/assets/7690fc98-4d30-4435-8fa1-e28eed6b1997\" /\u003e\n\u003cimg width=\"755\" height=\"530\" alt=\"Setup7\" src=\"https://github.com/user-attachments/assets/971aafa5-ebf3-47a9-875c-a5172b330dbc\" /\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitwire-it%2Fhpe-ilo-fan-watch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitwire-it%2Fhpe-ilo-fan-watch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitwire-it%2Fhpe-ilo-fan-watch/lists"}