Hitchhiker's Guide — Hardening Linux, Windows, and macOS Services
The operational companion to the Phase 05 WARMUP. The WARMUP compares the four OS security models (DAC/capabilities/LSM, tokens/ACLs/integrity, sandbox/entitlements/TCC); this guide is the how — the platform-native hardening config, the verification commands, the service-hardening method, and the detection validation that prove the controls hold without silently breaking the service. Generate telemetry with benign admin actions only.
Table of Contents
- The Service Hardening Method
- Linux Hardening and Verification
- Windows Hardening and Verification
- macOS Hardening and Verification
- Attack Fixtures
- Detection Validation
- Deliverables
- Worked Examples
- Interview Drills
- References
The Service Hardening Method
The repeatable procedure, applied identically across platforms:
- Record exact operations and dependencies the service actually performs.
- Trace files, registry/plist state, sockets, devices, child processes, and destinations.
- Inventory identity, privilege, inherited handles, and update authority.
- Remove authority incrementally with functional and denial tests after each removal.
- Add resource ceilings, restart behavior, health checks, and rollback.
- Generate benign misuse and prove telemetry reaches an owner.
One happy-path trace is incomplete. Exercise startup, shutdown, upgrade, errors, locale, DNS failure, log rotation, backup, and recovery — these are where a too-tight policy breaks the service in production (Phase 05 WARMUP, Chapter 3 — seccomp must allow the error/locale/DNS paths).
Linux Hardening and Verification
Use systemd directives matched to measured requirements (Phase 05 WARMUP, Chapter 4):
[Service]
User=svc-app
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
PrivateDevices=yes
RestrictSUIDSGID=yes
CapabilityBoundingSet=CAP_NET_BIND_SERVICE # only what it needs; drop the rest
SystemCallFilter=@system-service # seccomp allowlist
RestrictAddressFamilies=AF_INET AF_INET6
MemoryMax=256M
TasksMax=64
Verify the effective configuration, not the file:
systemd-analyze security svc-app # exposure score + per-directive findings
systemctl show svc-app -p CapabilityBoundingSet -p NoNewPrivileges
Then test denied operations fail: system writes, home access, unexpected address families,
privilege gain, fork pressure, egress. Use denial logs (auditd / journalctl) to refine the
policy narrowly — add back only what the service genuinely needs.
Windows Hardening and Verification
- a dedicated virtual/service account, not a broad administrator identity (Phase 05 WARMUP, Chapter 5 — token = SIDs + privileges);
- quote executable paths and secure service binary/config ACLs (unquoted-path and weak-ACL hijacks);
- remove unnecessary privileges and interactive logon;
- protect PowerShell/script execution; collect Script Block + operational logs per policy;
- deploy Sysmon with a tested, tuned configuration (Phase 05 WARMUP, Chapter 8);
- protect recovery and update paths.
Verify: service config, binary/config ACLs, account rights, token privileges, integrity level,
RPC/named-pipe ACLs, firewall rules, and event subscriptions (sc qc, accesschk, whoami /priv,
Process Explorer). Test whether an unprivileged user can replace the executable/DLL/config/recovery
content or influence privileged IPC. (Remember UAC is not a boundary — Phase 05 WARMUP,
Chapter 6.)
macOS Hardening and Verification
- validate code signature, hardened runtime, notarization/Gatekeeper path;
- minimize entitlements and TCC-protected data access (Phase 05 WARMUP, Chapters 9–10);
- secure
launchdplist and executable ownership; - store secrets via Keychain APIs, never plist/environment;
- prefer documented Endpoint Security / system extensions over kernel extensions.
Verify: codesign -dvvv, spctl -a -vv, entitlement dump, notarization, launchd ownership,
UID, sandbox/TCC assumptions, Keychain groups, system extensions, and update signatures. Test
helper/config replacement, unauthorized XPC callers, and leakage into the unified log or crash
reports. (Not every entitlement is a vuln — flag unjustified ones.)
Attack Fixtures
The flagship normalized evaluator should catch these across platforms; the platform labs collect the evidence to populate it:
- a service executable writable by its own identity (self-replace → persistence/escalation);
- wildcard outbound network;
- a secret canary in environment/log;
- a missing process/memory ceiling;
- a privileged service performing no privileged operation (over-privilege);
- a hardening change with no rollback.
Detection Validation
Generate, with benign actions: a service-configuration change, a privileged start, an unexpected child process, protected-file access, an unusual outbound connection, and a rollback. Assert the normalized event has identity, process, action, target, time, and host. Then drop one source and prove a health alert fires (a silent source is a blind spot — Phase 09 preview). Each detection needs a benign positive fixture and a negative fixture.
Deliverables
- a before/after authority graph per service;
- platform-native configuration (systemd unit / Windows service config / launchd plist);
- functional / denial / load / restart / upgrade / rollback results;
- an open-handle (descriptor) inventory;
- canary evidence (secrets absent from logs/telemetry);
- incident-recovery runbooks;
- honest limitations where a platform can't express the desired policy (state what needs EDR/MDM).
Worked Examples
Reading systemd-analyze security
systemd-analyze security svc-app
NAME EXPOSURE PREDICATE
PrivateNetwork ✗ Service has access to the host's network
CapabilityBoundingSet ✓ 0.1 No capabilities
SystemCallFilter ✗ Service has no system call filter
...
→ Overall exposure level for svc-app: 7.8 EXPOSED 🙁
Read it as a to-do list, not a grade: the ✗ rows are the missing controls. Here, add a
SystemCallFilter=@system-service and, if the service doesn't need raw networking, tighten
RestrictAddressFamilies — then re-run and watch the score drop. The interviewer wants you to (a)
inventory the service's actual needs first and (b) add controls without breaking it (re-test
startup/error/DNS paths — Phase 05 WARMUP, Chapter 3).
Reading a Windows token
C:\> whoami /priv
Privilege Name Description State
============================= ==================================== =======
SeDebugPrivilege Debug programs Enabled ← can open ANY process
SeBackupPrivilege Back up files and directories Enabled ← bypasses file DACLs
SeImpersonatePrivilege Impersonate a client after auth Enabled ← classic LPE primitive
These three privileges are near-equivalent to "owns the box" — flag them on a service account that doesn't need them. Note: this is the token's power, separate from object ACLs (Phase 05 WARMUP, Chapter 5). And remember UAC is not the boundary standing between a medium-integrity admin and SYSTEM (Chapter 6) — a favorite interview trap.
A seccomp deny in the wild
A service that worked in dev breaks in prod after you add SystemCallFilter:
audit: type=SECCOMP ... syscall=16(ioctl) ... ← the locale/tty path needs ioctl
The lesson (WARMUP Chapter 3): build the allowlist from observed + reviewed behavior across error,
locale, DNS, and threading paths — not one happy-path trace. Add ioctl only after confirming it's
legitimate, with a regression test.
Interview Drills
- "Investigate a suspicious service creation on Windows." Security/System log + Sysmon (EID 1 process create with command line + hashes, 7045 service install): who (token/SID), with what privileges, installed what binary (path/signature), that then did what (network). Reconstruct the chain; check whether that account should be able to install services.
- "Design isolation for a Linux network service." Dedicated non-root user; drop all capabilities
except (e.g.)
CAP_NET_BIND_SERVICE;NoNewPrivileges; seccomp allowlist of its real syscalls;ProtectSystem/PrivateTmpor an AppArmor/SELinux profile; restrict address families. Inventory needs first, then minimal policy, then prove denied ops fail without breaking the service. - "Explain Kerberos tickets." Authenticate once to the KDC → Ticket-Granting Ticket; exchange the TGT for a service ticket scoped to one service; present it, the service validates locally without the DC. Time-limited, audience-scoped bearer tokens — SSO with delegation. Risks: weak service-account keys, long lifetimes, unconstrained delegation.
- "Compare ETW, auditd, and Endpoint Security." All are the platform's kernel-level activity feed. ETW = Windows high-volume tracing (Sysmon curates a useful subset). auditd = Linux rule-driven syscall/file/auth audit (eBPF for richer/cheaper). Endpoint Security = Apple's authorized monitoring/EDR framework. Same detection role, different richness and consumption model.
- "Is UAC a security boundary?" No — Microsoft says so explicitly; it has by-design elevation paths and known bypasses. The real boundaries are the kernel, integrity levels, and the user/SYSTEM divide. Don't model UAC as a control in a threat assessment.
References
- The Linux Programming Interface (Kerrisk); systemd, auditd, capabilities(7), seccomp docs.
- Windows Internals (Russinovich et al.); Sysinternals (Sysmon, accesschk, Process Explorer); Microsoft "UAC is not a security boundary" guidance.
- Apple Platform Security Guide;
codesign/spctl/Endpoint Security documentation. - CIS Benchmarks (apply with workload context); MITRE ATT&CK (per-platform techniques + telemetry).
- Sigma rule project (portable detections — Phase 09).