EOL CentOS remediation
Close the recurring scanner finding — “the OS is End-of-Life and has received no security patches” — safely, idempotently, and with audit evidence a reviewer can actually accept.
This does not make an EOL OS supported. It installs every patch that existed up to End-of-Life. Vulnerabilities disclosed after EOL cannot be fixed by patching.
The finding is only durably closed by migrating to a supported OS (RHEL 8/9, AlmaLinux, Rocky) — optionally bridged by paid extended support (TuxCare ELS). A migrate-plan command is included to help scope that work.
When CentOS reaches End-of-Life, the mirrors behind mirrorlist.centos.org are switched off and the content is archived on vault.centos.org. yum/dnf then fail with 404s, so the box stops receiving even the last patches published before EOL. This tool repoints the OS repositories to the vault, installs everything available up to EOL, and packages the proof.
Auto-detected from /etc/os-release and /etc/centos-release. Point releases are cumulative, so patching rolls the host forward to the final release — the supported “install all updates” path.
| OS | Pkg mgr | Vault target | Rolls forward to |
|---|---|---|---|
| CentOS Linux 7.x | yum | os / updates / extras | 7.9.2009 |
| CentOS Linux 8.x | dnf | BaseOS / AppStream / extras / PowerTools | 8.5.2111 |
| CentOS Stream 8 | dnf | 8-stream tree | 8-stream |
Anything else — Stream 9/10 are still supported, and Rocky/Alma ship vendor repos — is refused with a clear message rather than a risky guess.
Read-only diagnostics are safe to run in an SSH loop; anything that touches the system is clearly marked and gated.
| Command | Effect | Changes the system? |
|---|---|---|
| diagnose | OS/version, repo health, pending updates, web listeners | No |
| migrate-plan | Per-host migration-assessment report | No |
| patch | Snapshot gate → repoint to vault → update → validate → reboot prompt. OS repos only by default; --with-epel to include EPEL | Yes |
| cleanup-kernels | Remove old kernels (keep 2), with a dry-run preview | Yes |
| verify | Post-reboot checks + optional functional test of a portal URL | No |
| bundle | tar.gz the evidence directory for the ticket | No |
A single host, start to finish. Look before you leap, patch interactively, verify after reboot.
# copy the script over scp os-patch.sh root@server: # look before you leap (read-only) ssh -t root@server './os-patch.sh diagnose' # interactive: snapshot gate + reboot prompt ssh -t root@server './os-patch.sh patch' # after it reboots ssh root@server './os-patch.sh verify https://the-portal.example'
There's a fleet workflow in the README too — triage, then assess migration effort, then patch each host individually. Ansible is deliberately not used: the snapshot gate and reboot are per-host and interactive, and you generally want to watch production DMZ boxes as they update.
Built to be run against production you can't afford to break.
patch refuses to proceed until you confirm a VMware/vCenter snapshot exists — taken from vCenter, since the guest can't snapshot itself.
Re-running is safe. Stock repo files are moved aside only if they point at dead mirrors; your custom repos are left untouched.
The transaction disables all other repos, so third-party repos and EPEL can't cause GPG or dependency surprises mid-update.
The vault path is built from the host's actual point release — nothing is hard-coded.
A timestamped bundle: before/after package lists, check-update with exit code, version and port diffs, update log, SUMMARY.txt.
docs/EOL-NOTES.md gives wording you can paste into the ticket — and honestly explains why patching alone can't permanently close the finding.
The line most scanners want — “no outstanding security updates remain” — is produced by the post-update check:
check-update-after.txt -> EXIT_CODE:0
EXIT_CODE:0 on the OS repos means no further patches are available for that release. Attach SUMMARY.txt plus the bundle tarball, and you have proof a reviewer can accept.
May I count anonymous visits with Google Analytics? No personal data is collected.