Adopt a benchmark as your baseline standard and prove the estate meets it
Task
Take a published benchmark, which is a guideline while it sits on the publisher's site, and adopt part of it as your own baseline standard: each setting written as a measurable requirement with a check, run against your lab VM, and every failure either fixed or recorded as an owned, dated exception. This is the moment a guideline becomes mandatory, and the lab makes you do it properly.
Steps
- Choose the source and name it exactly in
/tmp/baseline-standard.md: the CIS Benchmark for your distribution, or the distribution's own hardening guide, with its version and date. Write one sentence stating that the selected settings are adopted as a mandatory standard from today. - Select at least twelve settings that apply to your VM: SSH, password and account settings, file permissions, logging, services. Include some you expect to fail.
- For each, write a measurable requirement and a check command that settles it, in
/tmp/baseline.csvwith the headerid,requirement,benchmark_ref,check_command. A requirement you cannot write a check for is not yet a standard: rewrite it until you can. - Write
/tmp/check-baseline.sh, which runs every check and prints one line per setting in the form<id> PASSor<id> FAIL, reading the state of the VM each time rather than printing remembered results. - Run it. For each failure, either remediate it and re-run, or record an exception in
/tmp/exceptions.csvwith the headerid,reason,compensating_control,owner,expiry(expiry as YYYY-MM-DD). Record at least one exception, because a real baseline always has some. - Finally, add a section headed
Guidance (optional)to/tmp/baseline-standard.mdwith one benchmark recommendation you chose NOT to mandate, and why. It stays a guideline.
Verify
bash /tmp/check-baseline.sh | tee /tmp/baseline-run.txt | grep -cE ' (PASS|FAIL)$'
python3 - <<'PY'
import csv,re
rows=list(csv.DictReader(open('/tmp/baseline.csv')))
assert len(rows)>=12, 'fewer than twelve settings adopted'
nocheck=[r['id'] for r in rows if not r['check_command'].strip()]
assert not nocheck, 'no check for: '+', '.join(nocheck)+' - if you cannot check it, it is not yet a standard'
run={}
for line in open('/tmp/baseline-run.txt'):
m=re.match(r'(\S+)\s+(PASS|FAIL)$', line.strip())
if m: run[m.group(1)]=m.group(2)
unchecked=[r['id'] for r in rows if r['id'] not in run]
assert not unchecked, 'adopted but never checked: '+', '.join(unchecked)
exc={r['id']:r for r in csv.DictReader(open('/tmp/exceptions.csv'))}
assert exc, 'no exceptions recorded - a real baseline always has some'
fails=[i for i,v in run.items() if v=='FAIL']
open_fails=[i for i in fails if i not in exc]
assert not open_fails, 'failing with no recorded exception: '+', '.join(open_fails)
for i,r in exc.items():
assert r['owner'].strip(), 'exception %s has no owner' % i
assert re.match(r'\d{4}-\d{2}-\d{2}$', r['expiry'].strip()), 'exception %s has no expiry date' % i
print('%d settings: %d pass, %d fail, every failure covered by an owned, dated exception'
% (len(rows), len(run)-len(fails), len(fails)))
PY
grep -ciE "version|adopted|guidance \(optional\)" /tmp/baseline-standard.md
The check script runs live against the VM, so the PASS and FAIL lines are the state of the machine now, not a list you typed. The assertions enforce the three properties that make a standard real: every requirement has a check, every check was run, and every failure is either fixed or covered by an exception somebody owns until a stated date.
Notes
The benchmark document did not change during this lab; its status did. Before step 1 it was advice from an outside body. After it, the twelve settings you adopted are a mandatory standard inside your organisation, auditable by the script you wrote. The recommendation you left in the optional section is the reminder that guidelines still have a place: where mandating one answer would be wrong.
This is an independent study companion for CompTIA Security+ SY0-801 and is not produced by or endorsed by CompTIA.