Learning objectives
By the end of this module, you should be able to:
- Build a repeatable FreeBSD server baseline.
- Verify service, network and security state from evidence.
- Produce an operator-ready handover checklist.
The capstone is an operating model
The goal is not merely to make a web service respond once. A production-ready baseline must be explainable, restartable, observable and recoverable.
Verification closes the loop
Every configuration change should have an explicit verification command and a rollback path. That habit is more transferable than memorizing any single FreeBSD command.
Worked examples
See the idea in practice.
Baseline evidence bundle
freebsd-version -ku
sysrc -a | egrep "hostname|sshd|pf"
pkg audit -F || true
service -e
sockstat -4 -6
zpool status 2>/dev/null || true
- This bundle samples identity, enabled services, sockets, package security and ZFS health.
Hands-on lab
Capstone — build, verify, hand over and clean up a FreeBSD web host
Goal: Install nginx on a clean disposable VM, validate configuration, prove local and remote service reachability, restart it, validate PF policy offline, capture handover evidence and clean up.
Before you start
- Disposable FreeBSD VM with console recovery and networking.
- Use a clean lab host where nginx is not already serving another workload and port 80 is not already required.
STEP 1Baseline the host and port 80
freebsd-version -ku
sockstat -4 -6 -l | grep ":80" || true
pkg info nginx 2>/dev/null || true
STEP 2Install nginx and configure persistence
pkg install -y nginx
pkg info nginx
sysrc nginx_enable="YES"
sysrc nginx_enable
STEP 3Create Academy content and validate nginx
mkdir -p /usr/local/www/nginx-dist
echo "GNU Group FreeBSD Academy" > /usr/local/www/nginx-dist/index.html
cat /usr/local/www/nginx-dist/index.html
nginx -t
STEP 4Start and verify locally
service nginx start
service nginx status
sockstat -4 -6 | grep nginx
fetch -qo - http://127.0.0.1/
STEP 5Restart and prove service recovery
service nginx restart
service nginx status
fetch -qo - http://127.0.0.1/
STEP 6Verify from another machine
From the hypervisor or another system that can reach the VM, request http://<freebsd-vm-ip>/ and confirm the Academy text is returned.
curl -fsS http://<freebsd-vm-ip>/
STEP 7Validate the capstone PF policy offline
cat > /tmp/pf.capstone.conf <<'EOF'
set skip on lo0
block all
pass out keep state
pass in proto tcp to port { 22, 80 } keep state
EOF
pfctl -nf /tmp/pf.capstone.conf
STEP 8Collect operator handover evidence
echo "=== RELEASE ==="
freebsd-version -ku
echo "=== PACKAGE ==="
pkg info nginx
echo "=== PACKAGE AUDIT ==="
pkg audit -F || true
echo "=== PERSISTENT CONFIG ==="
sysrc nginx_enable
echo "=== SERVICE ==="
service nginx status
echo "=== SOCKETS ==="
sockstat -4 -6 | grep nginx
echo "=== HTTP ==="
fetch -qo - http://127.0.0.1/
echo "=== PF VALIDATION ==="
pfctl -nf /tmp/pf.capstone.conf
STEP 9Clean up the disposable capstone
service nginx stop
sysrc nginx_enable="NO"
pkg delete -y nginx
rm -f /tmp/pf.capstone.conf
rm -f /usr/local/www/nginx-dist/index.html
sockstat -4 -6 | grep nginx || true
Verify
- nginx -t succeeds before service activation.
- nginx serves the expected page locally and from another reachable machine.
- nginx survives an explicit service restart and remains enabled during the handover check.
- PF rules validate with pfctl -nf and are never activated by the lab.
- The handover bundle captures release, package, audit, persistent service, runtime socket, HTTP and PF-validation state.
- Cleanup stops/removes the disposable nginx workload and temporary PF file.
Expected outcome
- A complete install → validate → start → observe → restart → remote-check → security-validate → handover → cleanup lifecycle succeeds.
If it fails
- If port 80 is already occupied or nginx was already part of another workload, stop and use a clean disposable VM rather than disrupting existing services.
- If nginx fails, run nginx -t and inspect logs before restarting repeatedly.
- If remote HTTP fails while localhost works, inspect the VM network path and firewall state before changing nginx.
Real-world connectionA service is operationally ready only when configuration, persistence, reachability, restart behavior, security validation, evidence and cleanup/recovery are all explicit.
Avoid these traps
Common mistakes
- Calling a service production-ready because curl succeeded once.
- Enabling firewall rules without a tested management/recovery path.
Knowledge check
Can you explain it without looking back?
Open each answer only after you have tried to answer the question yourself.
1What makes the capstone stronger than a one-time install?
It includes persistent configuration, verification evidence, troubleshooting and recovery considerations.
2Why validate PF offline first?
To reduce the risk that syntax or policy mistakes break remote access.
3What should an operator handover contain?
Version, configuration intent, service state, listening endpoints, security/update status and recovery notes.