FreeBSD Fundamentals · Module 14 of 14

Capstone — build and operate a FreeBSD server

Combine identity, packages, networking, services, storage, ZFS concepts, firewall validation, monitoring and lifecycle checks into one operational runbook.

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 1

Baseline the host and port 80

freebsd-version -ku
sockstat -4 -6 -l | grep ":80" || true
pkg info nginx 2>/dev/null || true
STEP 2

Install nginx and configure persistence

pkg install -y nginx
pkg info nginx
sysrc nginx_enable="YES"
sysrc nginx_enable
STEP 3

Create 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 4

Start and verify locally

service nginx start
service nginx status
sockstat -4 -6 | grep nginx
fetch -qo - http://127.0.0.1/
STEP 5

Restart and prove service recovery

service nginx restart
service nginx status
fetch -qo - http://127.0.0.1/
STEP 6

Verify 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 7

Validate 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 8

Collect 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 9

Clean 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 connection

A 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.

My Learning

Record your progress for this module.

Progress is saved in this browser immediately. When you sign in to My Learning, it can also sync across devices.

Not started

Attempt the core lab and knowledge checks before marking the module complete.