Auditing a gaming laptop that thinks it's a server
A read-only audit of my homelab box. No firewall, password SSH, no backups, and 86 unsafe shutdowns on the SSD.
On this page
My homelab server is a Lenovo Legion gaming laptop running Arch Linux. It hosts my hackathon demo sites (kept online for my CV), Docker, Tailscale and a Cloudflare Tunnel. It had been running for a while without anyone looking at it critically, so I asked Claude Code to audit the quality of the system and how it was set up.
The ground rules
- Read-only first. The first pass ran without root.
- Don't touch the other Claude. Another Claude Code session was busy building ExamX in a tmux window on the same machine. The audit stayed away from that directory and that session.
- Root without sharing the password. A
!command in Claude Code has no terminal, sosudocan't prompt there. Instead of passing my password into the session, Claude wrote a read-only audit script. I read it, ran it withsudoin my own terminal, and Claude read the output file.
That last pattern is worth reusing: the AI writes the script, you review and run it, and it reads the results. No credentials ever enter the chat.
What was already fine
- No failed systemd units, and the system was up to date.
- Only 59 explicitly installed packages. Package signature checking was on.
sudorequires a password (noNOPASSWDanywhere).- Every SSH login in the journal was key-based, from my own laptop over Tailscale.
- Both drives passed SMART. The HDD had 0 reallocated or pending sectors, and the NVMe had 0 media errors.
- No port forwarding: remote access goes through Tailscale and a Cloudflare Tunnel.
What wasn't, worst first
- No host firewall at all. The
INPUTpolicy wasACCEPTfor IPv4 and IPv6. SSH, HTTP, the tunnel's metrics port and two Docker-published app ports were listening on every interface. On a machine that has been moved between networks, that matters. - SSH accepted passwords.
sshd -TconfirmedPasswordAuthentication yes. I only ever use keys, so turning passwords off costs nothing. /bootwas world-readable, including the random seed file, which systemd flags as a security hole.- 86 unsafe shutdowns on the NVMe, and 17% wear after only about 3,000 power-on hours. The last boot had ended with
watchdog did not stop!. That's what a laptop that sometimes gets hard-powered-off looks like. - No backups. Nothing was configured,
/homelived on a single drive, and the 1 TB HDD held old Windows data, mounted read-only. - Smaller items: membership of the
dockergroup (root-equivalent), unpinned:latestimages, 589 MB of reclaimable build cache, orphaned packages and a BIOS from 2022.
There was also one thing the audit couldn't fully explain: / was 20 GB used of 32 GB, but Docker only accounted for 0.4 GB of it.
The output: a plan, not changes
The result wasn't a pile of edits. It was a single Markdown file:
- a snapshot of the system and what's already good;
- an 11-item TODO list in priority order;
- copy-pasteable fixes, each with a rollback note;
- a suggested order of work and the open questions for me to decide.
I sent it to my Windows laptop with Taildrop (tailscale file cp). Taildrop needs root, or a one-time tailscale set --operator=<user>. Claude wouldn't change my Tailscale settings without asking, so I ran the send myself.
Nothing was changed in this session. The point of an audit is to know what you're dealing with before you touch it.
The next day this audit turned into a much bigger job. I'll be out of the country for three months with no physical access to the box. Part 2 is about getting it ready for that.