History

The BSD Ancestry (1977–1992)

  • FreeBSD traces its heritage directly back to BSD (Berkeley Software Distribution), developed at the University of California, Berkeley.
  • In the late 1970s, the Computer Systems Research Group (CSRG) at Berkeley released enhancements to AT&T’s Research Unix, introducing crucial concepts like the TCP/IP networking stack and the vi editor.
  • The code evolved from simple add-on patches to a complete system. By the early 1990s, CSRG aimed to release a version of BSD free from proprietary AT&T licenses, culminating in the Net/2 release (1991).

386BSD and the Fork (1992–1993)

  • In 1992, William and Lynne Jolitz released 386BSD, porting Net/2 to the Intel 80386 processor architecture.
  • Due to delays in 386BSD updates, a group of developers—Jordan Hubbard, Nate Williams, and Rod Grimes—decided to fork the project to maintain rapid bug fixes and improvements.
  • The name FreeBSD was coined by David Greenman in May 1993. The first official version, FreeBSD 1.0, was released in November 1993, based on the Net/2 tape and 386BSD patches.
  • Shortly after the release of FreeBSD 1.0, Unix System Laboratories (USL) sued Berkeley Software Design Inc. (BSDI) and UC Berkeley over trade secrets and copyright infringement.
  • The lawsuit settled in 1994. Under the agreement, Berkeley had to remove a small number of “encumbered” files from Net/2 and release a clean version, 4.4BSD-Lite.
  • FreeBSD was forced to re-base its entire operating system. In January 1995, FreeBSD released FreeBSD 2.0, completely free of encumbered AT&T code, using 4.4BSD-Lite as its new baseline.

Major Architectural Milestones

  • Over its multi-decade history, FreeBSD introduced key operating system innovations:
  • FreeBSD 3.0 (1998): Introduced ELF binary support as the default format (replacing a.out) and integrated early SMP (Symmetric Multiprocessing) capabilities.
  • FreeBSD 4.0 (2000): Renowned for its stability. Introduced the Kqueue event notification framework (a high-performance alternative to select/poll), jail process isolation, and a rewritten virtual memory subsystem.
  • FreeBSD 5.0 (2003): Redesigned the kernel locking system. Replaced the global kernel lock (Giant Lock) with fine-grained locking, enabling real multi-threaded SMP concurrency, and introduced the GEOM storage framework.
  • FreeBSD 7.0 (2008): Integrated Sun OpenZFS filesystem natively, introduced the high-performance ULE process scheduler, and optimized TCP/IP network throughput.
  • FreeBSD 9.0 (2012): Introduced the Capsicum capability sandboxing framework, the next-generation binary package manager (pkg), and support for the LLVM/Clang compiler toolchain.
  • FreeBSD 10.0 (2014): Replaced GCC with Clang/LLVM as the default base compiler, deprecated the old bind DNS server, and integrated the bhyve hypervisor.
  • FreeBSD 12.0 (2018): Updated the network stack, added VNET (virtualized network stack) support to jails by default, and transitioned the graphics subsystems to use modern DRM drivers.
  • FreeBSD 13.0 (2021): Massive performance optimizations for multi-core processors, cleaned up obsolete hardware drivers, and optimized OpenZFS to the unified upstream codebase.
  • FreeBSD 14.0 (2023): Migrated default shell for root to sh (moving away from tcsh for modern scripts), enabled NVMe driver optimizations, and expanded ARM64 tier-1 status.

The FreeBSD Development Model

  • FreeBSD is built as a complete operating system, meaning the kernel, userland utilities (such as ls, cat, ps), and core libraries are maintained together in a single source tree (src).
  • This differs from Linux distributions, which package a Linux kernel with userland tools from GNU and various other sources.
  • Core Team: A 9-member committee elected by committers every two years. They act as the project’s board of directors, governing administrative policies and resolving developer disputes.
  • Committers: Developers with write access to the FreeBSD repository (src, ports, or doc). Access is granted via mentorship and peer review.
  • Contributors: The broader community who submit patches via bug reports (Bugzilla) or pull requests.

FreeBSD Release Timeline and Architecture Mapping

  • The table outlines major FreeBSD branches, their architectural milestones, and active support status:
Marketing ReleaseKernel BranchRelease YearMain CPU ArchitecturesStatus
FreeBSD 1.01.0-RELEASE1993Intel x86 (i386)End of Life (EOL)
FreeBSD 2.02.0-RELEASE1995i386End of Life (EOL)
FreeBSD 3.03.0-RELEASE1998i386, AlphaEnd of Life (EOL)
FreeBSD 4.04.0-RELEASE2000i386, AlphaEnd of Life (EOL)
FreeBSD 5.05.0-RELEASE2003i386, IA-64, Sparc64End of Life (EOL)
FreeBSD 6.06.0-RELEASE2005i386, amd64, Sparc64End of Life (EOL)
FreeBSD 7.07.0-RELEASE2008i386, amd64, PowerPCEnd of Life (EOL)
FreeBSD 8.08.0-RELEASE2009i386, amd64, MIPS, PowerPCEnd of Life (EOL)
FreeBSD 9.09.0-RELEASE2012i386, amd64, ARM, MIPSEnd of Life (EOL)
FreeBSD 10.010.0-RELEASE2014i386, amd64, ARM, MIPSEnd of Life (EOL)
FreeBSD 11.011.0-RELEASE2016i386, amd64, ARM64, PowerPCEnd of Life (EOL)
FreeBSD 12.012.0-RELEASE2018i386, amd64, ARM64, PowerPCEnd of Life (EOL)
FreeBSD 13.013.0-RELEASE2021amd64, ARM64, i386, PowerPCLegacy Support
FreeBSD 14.014.0-RELEASE2023amd64, ARM64, i386, PowerPCActive Support
FreeBSD 15.015.0-CURRENT2025amd64, ARM64, PowerPCDevelopment

Introduction

What is FreeBSD?

  • FreeBSD is a free and open-source operating system descended directly from BSD Unix.
  • It is maintained as a cohesive, single-repository system containing the kernel, standard libraries, device drivers, and system utilities.
  • FreeBSD is widely recognized for its high-performance TCP/IP networking, storage subsystems (such as OpenZFS), and lightweight virtualization tools (such as Jails).

POSIX Compliance and certified UNIX Status

  • While FreeBSD is not formally certified as a UNIX system (due to the financial licensing costs of certification), it is engineered to comply strictly with the POSIX standards (IEEE Std 1003.1).
  • FreeBSD provides full POSIX system interfaces, shell syntax, and header definitions.
  • This strict compliance allows software developed on certified UNIX or standard Linux environments (such as Debian or Ubuntu) to be ported with minimal code modifications.

BSD License vs GPL (Copyleft vs Permissive)

  • FreeBSD is released under the permissive BSD License, which permits modification, redistribution, and commercial integration without requiring the modified code to be open-source.
  • In contrast, the GNU General Public License (GPL) used by Linux systems enforces “copyleft,” requiring all derivative works to open-source their changes under the same license terms.

Commercial Impact

  • Sony PlayStation: The operating systems powering the PS4 (Orbis OS) and PS5 are customized forks of FreeBSD, taking advantage of its proprietary-friendly licensing.
  • Netflix: The Open Connect content delivery network (CDN) appliance runs on optimized FreeBSD, serving terabits of streaming data with custom kernel optimizations.
  • Apple macOS: The Darwin kernel of macos was built by integrating parts of FreeBSD’s userland utilities and networking stack with the Mach microkernel.
  • Juniper Networks: Their enterprise routing operating system, JUNOS, is built directly on top of FreeBSD.

Core Advantages of FreeBSD

  • OpenZFS File System: Highly robust, advanced filesystem featuring built-in raid pools, copy-on-write snapshots, filesystem encryption, deduplication, and self-healing data checksums.
  • Lightweight Virtualization (Jails): Allows administrators to partition a FreeBSD system into independent, isolated environments with minimal overhead, sharing the host kernel.
  • Rock-Solid Networking: Renowned for handling massive traffic throughput under heavy loads, featuring an advanced modular firewalls layout and dynamic socket caching.
  • System Cohesiveness: Since the entire system is developed in one tree, configuration configurations, libraries, and utilities remain stable and compatible across updates.

Core Disadvantages of FreeBSD

  • Hardware Driver Gaps: Laptop wireless adapters and the latest consumer graphics cards (especially AMD and NVIDIA GPUs) often receive drivers later than on Linux.
  • Fewer Native Proprietary Apps: Software developers prioritizing Linux occasionally skip compiling native FreeBSD binaries, requiring the use of Linux binary translation subsystems.
  • Lack of systemd: While many view this as an advantage, developers deploying applications heavily reliant on systemd integrations must adapt their setup scripts to use FreeBSD’s traditional rc.d scripting engine.

Comparison: FreeBSD vs Linux vs macOS vs Windows 11

  • The table outlines structural differences across the major operating system groups:
FeatureFreeBSDLinux (e.g., Fedora)macOSWindows 11
Kernel ArchitectureMonolithic (Dynamic Modules)Monolithic (Dynamic Modules)Hybrid (XNU: Mach + BSD)Hybrid (NT Kernel)
License TypePermissive BSD LicenseCopyleft GPL LicenseProprietaryProprietary
Default Shellsh (users), tcsh (legacy root)BashZshPowerShell / CMD
Default FilesystemOpenZFS / UFS2Btrfs / Ext4APFSNTFS
Binary FormatELF (Executable & Linkable)ELFMach-OPE (Portable Executable)
Isolation TechnologyJails (with VNET stacks)Namespaces / Cgroups (Docker)Sandboxing / HypervisorHyper-V Containers
Package Managerpkg (binary) & Ports (source)DNF / APTHomebrew (Community)winget / NuGet
Release PhilosophyUnified system releasesSeparate kernel + distrosHardware-tied OS cyclesSaaS rolling update cycles

FreeBSD Release Types

  • FreeBSD developments are split into three distinct release tracks:
  • RELEASE: The stable, fully-tested production releases. Example: 14.0-RELEASE. These receive security advisories and critical errata patches.
  • STABLE: Active development branches aiming for backward compatibility. New features are backported from CURRENT here after testing. Example: 14-STABLE.
  • CURRENT: The bleeding-edge development branch. All new features and hardware integrations are introduced here first. Example: 15-CURRENT. It may experience transient instability and is not recommended for production servers.

Installation & Setup

System Requirements

Minimum (CLI / Server):
  CPU:   x86_64 (amd64), ARM64 (aarch64), or i386
  RAM:   512 MB minimum (4 GB recommended if using OpenZFS)
  Disk:  4 GB minimum
  Network: Ethernet interface card

Recommended (OpenZFS, bhyve, or Jails host):
  CPU:   Multi-core x86_64 with VT-x/AMD-V virtualization support
  RAM:   16 GB or higher
  Disk:  Mirrored SSDs (minimum 100 GB space)

Download and Verification

# Download the official ISO image from freebsd.org
# Fetch the SHA256 checksum file to verify download integrity
fetch https://download.freebsd.org/releases/ISO-IMAGES/14.0/FreeBSD-14.0-RELEASE-amd64-disc1.iso
fetch https://download.freebsd.org/releases/ISO-IMAGES/14.0/CHECKSUM.SHA256-FreeBSD-14.0-RELEASE-amd64
 
# Validate the checksum matches on a Unix-like system
sha256sum -c CHECKSUM.SHA256-FreeBSD-14.0-RELEASE-amd64 --ignore-missing
 
# Burn image to a USB flash drive (replace /dev/sdX with your disk name)
sudo dd if=FreeBSD-14.0-RELEASE-amd64-disc1.iso of=/dev/sdX bs=1M status=progress
sync

Partitioning Guide: ZFS vs UFS Layouts

  • During the interactive bsdinstall execution, you must choose a storage layout:
  • Sets up a boot pool (zroot) on your drive using GPT partitioning.
  • Automatically configures datasets for /tmp, /var, /usr/home, and root, enabling features like system snapshots, boot environments (beadm), and OpenZFS checksum validation out of the box.

UFS2 Partitioning Layout

  • For lightweight VM containers, a standard UFS partition layout is often preferred:
Partition Index   -->   Mount Point   -->   File System Type  -->   Size Allocation
/dev/ada0p1       -->   None          -->   freebsd-boot      -->   512 KB (Bootloader)
/dev/ada0p2       -->   /boot/efi     -->   efi               -->   200 MB (EFI System Partition)
/dev/ada0p3       -->   None          -->   freebsd-swap      -->   4 GB (Swap Space)
/dev/ada0p4       -->   /             -->   freebsd-ufs       -->   Remaining Disk space

Post-Installation Setup and Initial Settings

  • After copying the system files, bsdinstall requests configuration settings:
  • Root Password: Setup a complex administrative password.
  • Network Config: Select the active interface, configure IPv4/IPv6, and choose DHCP or static routing.
  • Time Zone: Set your local system clock parameters.
  • System Daemons: Enable default daemons to start on boot:
    • sshd: Enable secure remote shell administration.
    • powerd: Dynamically adjust CPU frequency to save energy.
    • ntpd: Sync system clock with network time servers.
  • Create Users: Add a daily-use, non-privileged user and add them to the wheel group.

The wheel Group and Privilege Escalation

  • On FreeBSD, only members of the wheel group are allowed to use the su command to elevate privileges to root.
  • If a user is not in the wheel group, the kernel blocks privilege escalation to protect the system.
# Add an existing user 'sysadmin' to the wheel group
pw groupmod wheel -m sysadmin
 
# As 'sysadmin', switch to root shell
su -

Kernel & Architecture

Monolithic vs Hybrid Design

  • FreeBSD uses a monolithic kernel design. Unlike microkernels, all core operating system services (Virtual Memory, Process Schedulers, File Systems, and Networking Stacks) run inside a single kernel address space for maximum execution efficiency.
  • The kernel supports dynamic expansion via Kernel Linker Modules (KLDs), allowing administrators to load or unload drivers and file systems on the fly without rebooting the system.
# List all loaded kernel modules
kldstat
 
# Manually load the OpenZFS filesystem module
sudo kldload zfs
 
# Unload an active module (e.g., sound card driver)
sudo kldunload snd_driver

The Virtual Memory (VM) Subsystem

  • FreeBSD manages system RAM using a layered VM model built on three core primitives:
  • VM Objects: Abstract representations of backable data sources (such as files, memory allocations, or swap space).
  • VM Pages: The actual physical page allocations mapping to memory blocks (default 4KB pages).
  • UMA (Unified Memory Architecture): A slab-based allocator optimized for quick kernel resource allocations. It constructs caches of pre-allocated memory pools (zones) for common structs, reducing memory fragmentation.

The ULE Process Scheduler

  • The default process scheduler in modern FreeBSD releases is the ULE Scheduler, designed specifically for Symmetric Multiprocessing (SMP) and multi-core hardware.

Core Scheduling Design

  • Per-CPU Run Queues: Each CPU core maintains its own list of active threads, minimizing lock contention across processor cores.
  • Processor Affinity: ULE attempts to schedule a thread on the same CPU core it recently ran on to maximize CPU L1/L2 cache hits.
  • Interactivity Scoring: Evaluates threads based on interactive responsiveness vs CPU-bound processing, scheduling interactive tasks (UI, terminals) with higher priority.

System Startup Boot Flow

  • The boot process proceeds through several stages:
    1. BIOS/UEFI Initialization: Hardware POST (Power On Self Test) maps early memory and hands execution over to the default EFI boot file (/boot/loader.efi).
    1. loader (The 3rd Stage Bootloader): Reads configuration files from /boot/loader.conf, loads dynamic kernel modules, and passes control to the kernel.
    1. Kernel Startup (mi_startup): Initializes machine-independent subsystems (Virtual Memory, device trees, scheduling engines).
    1. init (PID 1): The parent process of user space. It parses configuration files and executes /etc/rc to start system processes.
    1. rc.d Scripts: Boots the system into multi-user mode by loading background system daemons.

FreeBSD Boot Process Flow

  • The diagram outlines the sequence of execution from hardware power-on to login prompt:
flowchart TD
    HW[Power On / BIOS / UEFI] --> EFI[EFI Boot Loader\n/boot/loader.efi]
    EFI --> CONF[loader.conf Parsed\nKernel & Modules Loaded]
    CONF --> KERN[Kernel Starts\nmi_startup Called]
    KERN --> INIT[init Spawning\nPID 1 Created]
    INIT --> RC[rc.d Daemon Scripts\nProcesses config from rc.conf]
    RC --> LOG[getty Spawned\nUser Login Terminal Screen]

    style HW fill:#1a202c,color:#fff
    style KERN fill:#2b6cb0,color:#fff
    style RC fill:#276749,color:#fff
    style LOG fill:#744210,color:#fff

Shell & Terminal

Default Shell Environments

  • Traditionally, FreeBSD configured the C Shell (tcsh) as the default shell for the root user and the Bourne Shell (sh) for standard system accounts.
  • Modern FreeBSD releases utilize standard sh for root and user shells, but support any shell via package installation.

Installing and Configuring Zsh on FreeBSD

  • Since Zsh is not part of the base system, it must be installed from binary repositories or the ports tree:
# Install the Zsh package using pkg
sudo pkg install zsh zsh-completions
 
# Change the default shell for the user 'sysadmin'
sudo chsh -s /usr/local/bin/zsh sysadmin

Production .zshrc Configuration

  • Below is a clean, optimized .zshrc file setup tailored for FreeBSD development:
# ~/.zshrc configuration file
 
# Load completions and system configuration
autoload -Uz compinit && compinit
setopt AUTO_CD
setopt HIST_IGNORE_DUPS
 
# Set terminal prompt with host, working directory, and path info
PROMPT='%B%F{magenta}[FreeBSD]%f %F{cyan}%~%f%b %# '
 
# Enforce colors inside standard commands
export CLICOLOR=1
export LSCOLORS=ExGxFxdxCxDxDxhbadbaca
 
# Setup aliases for daily administration
alias ls="ls -G"
alias ll="ls -lah"
alias zstat="zpool status"
alias jail-ls="jls -N"

Standard Unix Permissions and System Flags

  • In addition to standard read, write, and execute permissions, FreeBSD supports advanced file attributes called system flags via the chflags utility.
  • These flags prevent modification or deletion, even by the root user:
  • schg: System Immutable flag. Can only be cleared when the system is in single-user mode or securelevel is 0.
  • uarch: User Archive flag. Marks the file for backup systems.
  • uappend: User Append-Only flag. Allows processes to append data to the file, but prevents modifications or deletion.
# Set system immutable flag on a critical system binary
sudo chflags schg /sbin/init
 
# Attempting to delete this file will fail, even as root:
# rm /sbin/init -> Operation not permitted
 
# Clear the system immutable flag
sudo chflags noschg /sbin/init

I/O Redirection, Pipes, and Scripting Basics

  • FreeBSD’s default POSIX sh shell provides lightweight execution processing:
# Redirect standard output (stdout) to overwrite a file
sysctl kern.version > system_details.txt
 
# Append standard error (stderr) logs to a file
pkg install -y non_existent 2>> pkg_error.log
 
# Chain outputs using pipes: find the top 5 memory-consuming processes
ps aux | sort -rn -k 4 | head -n 5

User & Group Management

The Account Database

  • FreeBSD manages users and groups via a master system database /etc/master.passwd.
  • This file is readable only by root. The system automatically hashes the passwords and generates the public /etc/passwd file along with the database indexes:
  • /etc/master.passwd: Contains hashed passwords, login expiration times, shells, and account details.
  • /etc/passwd: Publicly readable version with password fields replaced by an ‘x’.
  • /etc/pwd.db & /etc/spwd.db: Hashed DB files generated by pwd_mkdb to speed up system queries.

Account Administration Commands

  • Avoid editing database files directly. Use the unified pw command suite:
# Create a new group called 'developers'
sudo pw groupadd developers -g 1005
 
# Create a new user with home directory, default shell, and group memberships
sudo pw useradd developer1 -u 1005 -g developers -m -d /usr/home/developer1 -s /usr/local/bin/zsh -c "Software Developer"
 
# Set the user's password interactively
sudo passwd developer1
 
# Modify user group memberships (append developers to their supplementary groups)
sudo pw usermod developer1 -G wheel
 
# Lock a user account, preventing login
sudo pw lock developer1
 
# Unlock the user account
sudo pw unlock developer1
 
# Delete a user account and purge their home directory
sudo pw userdel developer1 -r

Secure Password and Shell Editing via vipw

  • If you must modify user database fields manually, use the vipw tool.
  • vipw locks the database, opens the master password file in a text editor, and regenerates database indexes upon saving to prevent corruption.
# Edit user configurations safely
sudo vipw

System Configuration & Services (rc.d)

The rc.d Startup Daemon Framework

  • FreeBSD uses a system startup configuration framework based on NetBSD’s rc.d system.
  • Unlike Alpine Linux’s OpenRC or Linux System Design engines using systemd, FreeBSD runs initialization scripts in a deterministic order.
  • Startup scripts declare dependencies at the top of the file. The system processes these declarations to build a dependency tree and execute services in the correct sequence.

The rc.conf Configuration System

  • The primary configuration file for system services, network interfaces, and firewalls is /etc/rc.conf.
  • Individual keys enable or disable services:
# Enable sshd daemon
sshd_enable="YES"
 
# Set system hostname
hostname="freebsd-server.local"
 
# Enable loopback and static interface configurations
ifconfig_em0="inet 192.168.1.50 netmask 255.255.255.0"
defaultrouter="192.168.1.1"

Core Configuration Files System Map

  • FreeBSD splits configurations across specific directories and files:
  • /boot/loader.conf: Configures variables passed to the kernel during early boot (e.g., loading driver modules, adjusting kernel memory limits).
  • /etc/sysctl.conf: Adjusts kernel runtime settings (e.g., enabling IP forwarding, tweaking buffer limits).
  • /etc/make.conf: Configures compilation compiler settings when building from source.
  • /etc/resolv.conf: Configures DNS name server IP lookups.
  • /etc/hosts: Maps static IP addresses to hostnames.
  • /etc/periodic.conf: Configures daily, weekly, and monthly system maintenance cron scripts.

Writing a Custom rc.d Service Script

  • Below is a complete, production-grade service script using the standard rc.subr API library.
  • Save this file as /usr/local/etc/rc.d/customdaemon to manage a background application:
#!/bin/sh
#
# PROVIDE: customdaemon
# REQUIRE: LOGIN CLEANFILES
# KEYWORD: shutdown
 
# Source the FreeBSD rc subroutines library
. /etc/rc.subr
 
name="customdaemon"
rcvar="customdaemon_enable"
 
# Define the target command executable and path parameters
command="/usr/local/bin/custom_service"
command_args="-d --config /etc/custom_service.conf"
pidfile="/var/run/${name}.pid"
 
# Load variables from rc.conf
load_rc_config "${name}"
 
# Set default values if not defined in /etc/rc.conf
: ${customdaemon_enable:="NO"}
: ${customdaemon_user:="daemon"}
 
# Custom start precheck validation function
start_precmd="customdaemon_prestart"
 
customdaemon_prestart() {
    if [ ! -f "/etc/custom_service.conf" ]; then
        err 1 "Configuration file /etc/custom_service.conf is missing."
    fi
}
 
run_rc_command "$1"
# Make the service script executable
sudo chmod +x /usr/local/etc/rc.d/customdaemon
 
# Enable the service inside rc.conf
sudo sysrc customdaemon_enable="YES"
 
# Start the service
sudo service customdaemon start
 
# Query service execution status
sudo service customdaemon status

Package Management & Ports Collection

Binary Packages (pkg) vs Ports Collection

  • FreeBSD offers two ways to install software:
  • pkg (Binary): Downloads precompiled binaries from official mirrors. Fastest installation route.
  • Ports (Source): A tree of makefiles allowing you to customize compiler configurations and compile software from source.

The pkg Package Manager Command Reference

  • The pkg utility manages binary packages on FreeBSD:
# Update the package repository index catalog
sudo pkg update
 
# Upgrade all installed binary packages to latest versions
sudo pkg upgrade
 
# Install a package (e.g., git)
sudo pkg install git
 
# Remove an installed package
sudo pkg delete git
 
# Search repositories for matching packages
pkg search apache24
 
# List all installed packages
pkg info
 
# Query which package installed a specific system file path
pkg which /usr/local/bin/tmux
 
# Perform security audit check on installed packages for known vulnerabilities
pkg audit -F
 
# Remove unused dependencies and clean the download package cache
sudo pkg autoremove
sudo pkg clean

Using the Ports Collection

  • The Ports collection contains recipes to fetch source code, apply FreeBSD compatibility patches, and compile binaries.
# Install git if not present to fetch ports tree
sudo pkg install git
 
# Clone the official FreeBSD ports tree to /usr/ports/
sudo git clone https://git.freebsd.org/ports.git /usr/ports
 
# Navigate to the target port category and package directory (e.g., security/nmap)
cd /usr/ports/security/nmap
 
# Configure build options in an interactive dialog menu
sudo make config
 
# Compile code from source, verify dependencies, and install binary
sudo make install clean
 
# Uninstall a port compiled from source
sudo make deinstall

Advanced Building using Poudriere

  • In production deployments, administrators avoid compiling ports directly on server systems. Instead, they build custom repositories using Poudriere.
  • Poudriere runs compilation processes in isolated, clean jails to generate custom binary package repositories (.txz files) matching specific compiler flags.
# Install the poudriere package
sudo pkg install poudriere
 
# Create a poudriere jail for the building pipeline
sudo poudriere jail -c -j base_14 -v 14.0-RELEASE
 
# Fetch the ports tree used by poudriere
sudo poudriere ports -c -p default
 
# Configure compilation options for your package list
sudo poudriere options -j base_14 -p default -f /usr/local/etc/poudriere.d/pkg_list
 
# Run bulk compilation pipeline
sudo poudriere bulk -j base_14 -p default -f /usr/local/etc/poudriere.d/pkg_list

Storage & Filesystems (ZFS & UFS)

OpenZFS Architecture and Pool Operations

  • FreeBSD includes native support for the enterprise-grade OpenZFS file system.
  • ZFS combines the roles of filesystem and volume manager. Storage drives are pooled into a zpool containing virtual devices (vdevs).
  • ZFS uses a Copy-on-Write (CoW) model: when data is modified, it is written to new blocks before updating metadata pointers, preventing data corruption during power losses.

vdev Redundancy Levels

  • Stripe: Spans data across drives without redundancy (similar to RAID 0).
  • Mirror: Cryptographic double-write replication across drives (similar to RAID 1).
  • RAID-Z1: Single parity disk redundancy, requiring at least 3 drives (similar to RAID 5).
  • RAID-Z2: Double parity disk redundancy, requiring at least 4 drives (similar to RAID 6).
  • RAID-Z3: Triple parity disk redundancy, requiring at least 5 drives.

Basic Pool Operations

# Create a mirrored zpool named 'datapool' using two NVMe drives
sudo zpool create datapool mirror nda0 nda1
 
# Query pool status, health, and vdev configuration layouts
zpool status datapool
 
# Set dataset compression to lz4 (highly recommended for performance)
sudo zfs set compression=lz4 datapool
 
# List all active ZFS datasets
zfs list

ZFS Dataset Management, Snapshots, and Replications

  • You can partition a ZFS pool into logical filesystems called datasets:
# Create a new dataset for secure user documents
sudo zfs create datapool/secure_docs
 
# Enable ZFS native encryption on the dataset
sudo zfs set encryption=on keyformat=passphrase datapool/secure_docs
 
# Configure storage quota limits (prevent dataset from exceeding 50 GB)
sudo zfs set quota=50G datapool/secure_docs
 
# Create a read-only point-in-time snapshot of the dataset
sudo zfs snapshot datapool/secure_docs@snap_backup
 
# Restore dataset files to the snapshot state
sudo zfs rollback datapool/secure_docs@snap_backup
 
# Send dataset snapshot to a remote backup destination via SSH
zfs send datapool/secure_docs@snap_backup | ssh backup-server zfs recv remotepool/backups

ZFS Memory Tuning: The Adaptive Replacement Cache (ARC)

  • ZFS replaces standard operating system page caches with the Adaptive Replacement Cache (ARC).
  • ARC uses dynamic algorithms to balance Most Recently Used (MRU) and Most Frequently Used (MFU) data cache algorithms in system RAM.
  • On systems with high amounts of RAM, ZFS can consume up to 90% of memory for the ARC. You can configure limits inside /boot/loader.conf:
# Limit maximum ARC size allocation to 8 GB in /boot/loader.conf
vfs.zfs.arc.max="8589934592"

UFS2 Filesystem and Soft Updates

  • For legacy server environments or minimal VM setups, FreeBSD’s traditional UFS2 filesystem is often used.
  • UFS2 implements Soft Updates, which tracks metadata dependency structures to ensure safe disk writes without the performance overhead of traditional journaling.
  • Soft Updates Journaling (SU+J): Speeds up system recovery. By maintaining a log of metadata changes, the system can skip full fsck passes after unexpected shutdowns, mounting the filesystem in seconds.
# Enable journaling on an unmounted UFS2 partition
sudo tunefs -j enable /dev/ada0p4
 
# Print detailed filesystem configuration statistics
dumpfs /dev/ada0p4

The GEOM Storage Subsystem

  • GEOM is a modular storage framework in the FreeBSD kernel. It abstracts disk access into a system of providers (data sources, like physical disks or partitions) and consumers (subsystems reading the data, like filesystems).
  • Modulators called GEOM Classes stack between them to modify transactions:
  • geli: Enforces sector-level hardware disk encryption.
  • gmirror: Creates software RAID 1 arrays.
  • gstripe: Creates software RAID 0 arrays.
  • gpart: Manages disk partitioning schemes.
# Encrypt a partition using geli, prompting for a password passphrase
sudo geli init /dev/ada0p3
 
# Attach/decrypt the partition, mapping it to /dev/ada0p3.eli
sudo geli attach /dev/ada0p3
 
# Create a clean software mirror (gmirror) named 'mirror0'
sudo gmirror label -v mirror0 /dev/ada0 /dev/ada1

Security & Hardening

Jails Virtualization (OS-Level Virtualization)

  • Introduced in FreeBSD 4.0, Jails partition a FreeBSD system into isolated, virtualized environments.
  • Jails share the host’s kernel but maintain their own root directory, user accounts, network interfaces, and process space, running with near-zero performance overhead.

VNET: Virtualized Network Stack

  • Traditionally, jails shared the host’s IP address. Modern FreeBSD releases support VNET, which provides jails with their own virtualized network stack, loopback interface, routing tables, and firewall sockets.

Production Configuration (/etc/jail.conf)

  • Below is a clean, multi-jail configuration profile. Save this as /etc/jail.conf to configure an isolated database jail:
# /etc/jail.conf global parameters
host.hostname = "$name.local";
path = "/usr/jail/$name";
mount.devfs;
exec.clean;

# Database Jail Definition
db_jail {
    # Define IP address assignments
    ip4.addr = "192.168.1.99";
    
    # Start/Stop execution commands
    exec.start = "/bin/sh /etc/rc";
    exec.stop = "/bin/sh /etc/rc.shutdown";
    
    # Secure execution parameters
    allow.raw_sockets = 0;
    allow.sysvipc = 0;
}

Jail Operations Commands

# Create a directory to host the jail userland files
sudo mkdir -p /usr/jail/db_jail
 
# Extract base system binaries into the jail directory
sudo tar -xf /usr/freebsd-dist/base.txz -C /usr/jail/db_jail
 
# Copy DNS settings to the jail
sudo cp /etc/resolv.conf /usr/jail/db_jail/etc/
 
# Start the jail
sudo jail -c db_jail
 
# List all running jails and view their PIDs and JIDs
jls
 
# Enter an interactive shell inside the jail
sudo jexec db_jail /bin/sh
 
# Stop the jail
sudo jail -r db_jail

The Capsicum Sandboxing Framework

  • Capsicum is a capability-based security framework integrated into the FreeBSD kernel.
  • It operates on the principle of least privilege, allowing applications to partition themselves and enter Capability Mode.
  • Once in capability mode, the process is blocked from calling global namespaces (such as opening files by path or resolving hostnames). Instead, it must perform actions using pre-allocated file descriptors (capabilities).
  • Many core FreeBSD utilities (such as gzip, tcpdump, and bhyve) utilize Capsicum to isolate parsing engines and prevent privilege escalation during exploit runs.

Mandatory Access Control (MAC) Framework

  • The MAC framework allows administrators to enforce strict security policies beyond traditional file permissions.
  • Policies are loaded as kernel modules to restrict access based on labels:
  • mac_biba: Enforces integrity levels, preventing high-integrity processes from reading low-integrity data.
  • mac_mls: Enforces Multi-Level Security classifications for data confidentiality.
  • mac_portacl: Restricts binding access to specific TCP/UDP ports.
# Load the port access control policy module
sudo kldload mac_portacl
 
# Configure policy to allow group 'developers' to bind to port 80
sudo sysctl security.mac.portacl.rules="uid:1005:tcp:80"

OpenBSM Auditing Subsystem

  • FreeBSD includes OpenBSM, a security auditing engine conforming to the Common Criteria security requirements.
  • It logs system events (such as user logins, file reads, privilege escalations, and network connections) to secure audit logs in /var/audit/.
# Audit daemon configuration lives in /etc/security/audit_control
# Configure auditing of logins, administrative commands, and authorization changes:
# flags: lo,ad,ap
 
# Enable the audit service daemon
sudo sysrc auditd_enable="YES"
sudo service auditd start
 
# View logs in a readable format
sudo praudit /var/audit/current
 
# Filter logs to show only failed file operations
sudo auditreduce -c ff /var/audit/current | praudit

Kernel Security Levels (securelevel)

  • The kernel security level (securelevel) restricts critical kernel capabilities.
  • Values range from -1 (permanently insecure) to 3 (extremely secure).
  • Once set, the security level cannot be lowered except in single-user mode.
  • -1: Permanently insecure mode.
  • 0: Default boot mode.
  • 1: Secure mode. Prevents changes to file flags (schg), loading/unloading kernel modules, and direct disk writes to mounted systems.
  • 2: Highly secure mode. Enforces all level 1 rules, and prevents formatting raw disk partition structures.
  • 3: Network lockdown mode. Enforces level 2 rules, and blocks changes to firewall rules.
# Elevate the system security level to 1 (add to /etc/sysctl.conf for permanence)
sudo sysctl kern.securelevel=1

Networking, Firewall & Services

Network Interface Configuration

  • Configure network interfaces using the ifconfig tool:
# Query all active network interface details
ifconfig
 
# Configure a static IP on network card 'em0'
sudo ifconfig em0 inet 192.168.1.100 netmask 255.255.255.0
 
# Create a virtual Link Aggregation (lagg) interface to combine multiple cards
sudo ifconfig lagg0 create
sudo ifconfig lagg0 laggproto lacp laggport em0 laggport em1 192.168.1.120 netmask 255.255.255.0

The Three Firewalls: PF, IPFW, and IPFilter

  • FreeBSD provides three built-in firewalls, each with unique strengths:

1. PF (Packet Filter)

  • Ported from OpenBSD, PF is highly popular for its clean syntax, table structures, and NAT integration.

Production PF Configuration (/etc/pf.conf)

# Define network interfaces
ext_if = "em0"

# Table of IP addresses to block
table <bad_ips> persist file "/etc/blocked_ips"

# Skip filtering on loopback
set skip on lo0

# Block all incoming traffic by default
block in all
pass out all keep state

# Block bad IPs
block in quick on $ext_if from <bad_ips> to any

# Allow incoming SSH and Web traffic
pass in on $ext_if proto tcp from any to any port { 22, 80, 443 } keep state
# Enable the PF firewall service
sudo sysrc pf_enable="YES"
sudo service pf start
 
# Reload rules safely
sudo pfctl -f /etc/pf.conf

2. IPFW (IP Firewall)

  • IPFW is the native FreeBSD firewall, featuring Dummynet for traffic shaping and network simulation.
# Enable IPFW firewall
sudo sysrc ipfw_enable="YES"
sudo service ipfw start
 
# Define rule using IPFW CLI: Block all traffic to port 21 (FTP)
sudo ipfw add 100 deny tcp from any to any 21
 
# Configure Dummynet pipe: limit client bandwidth to 5 Mbit/s
sudo ipfw pipe 1 config bw 5Mbit/s
sudo ipfw add 200 pipe 1 ip from 192.168.1.200 to any

3. IPFilter (IPF)

  • A cross-platform firewall commonly used on older UNIX platforms like Solaris.
# /etc/ipf.rules syntax example
block in on em0 all
pass out on em0 proto tcp from any to any port = 80 keep state

Production Service Deployments

  • Setting up common services on FreeBSD:

Nginx Web Server Deployment

# Install nginx package
sudo pkg install nginx
 
# Enable on boot
sudo sysrc nginx_enable="YES"
 
# Start nginx
sudo service nginx start

PostgreSQL Database Deployment

# Install PostgreSQL server
sudo pkg install postgresql15-server
 
# Initialize database clusters
sudo service postgresql initdb
 
# Enable and start database
sudo sysrc postgresql_enable="YES"
sudo service postgresql start

Virtualization & Compatibility (bhyve & Linuxulator)

The bhyve Hypervisor

  • bhyve is a native FreeBSD hypervisor designed to run guest operating systems (such as FreeBSD, Linux, and Windows) with hardware-assisted virtualization.

System Prerequisites

  • Requires a processor supporting VT-x (Intel) or AMD-V virtualization, and EPT (Extended Page Tables) or NPT.
# Load the Virtual Machine Monitor kernel module
sudo kldload vmm
 
# Create a virtual networking bridge interface
sudo ifconfig bridge0 create
sudo ifconfig bridge0 addm em0 up
 
# Create a tap interface to link the virtual machine
sudo ifconfig tap0 create
sudo ifconfig bridge0 addm tap0 up

Provisioning a Virtual Machine

# Create a 20 GB raw virtual disk file
truncate -s 20G /var/vm/linux_disk.img
 
# Boot virtual machine guest using bhyveload
sudo bhyveload -m 2048 -d /var/vm/linux_disk.img guestvm
 
# Run bhyve virtual environment mapping IO connections
sudo bhyve -c 2 -m 2048M -H -P \
  -s 0,hostbridge \
  -s 3,ahci-hd,/var/vm/linux_disk.img \
  -s 4,virtio-net,tap0 \
  -s 31,lpc -l com1,stdio guestvm
 
# Destroy active virtual machine resources after shutdown
sudo bhyvectl --destroy --vm=guestvm

Linux Binary Compatibility (Linuxulator)

  • Linuxulator allows FreeBSD to run unmodified Linux binaries natively by translating Linux system calls to FreeBSD system calls in real-time.
  • Because this is a system call translation layer rather than emulation, Linux binaries run at native speed without hypervisor virtualization overhead.
# Load the Linuxulator kernel modules
sudo kldload linux
sudo kldload linux64
 
# Configure modules to load automatically on boot in /etc/rc.conf
sudo sysrc linux_enable="YES"
 
# Install the CentOS/Ubuntu userland translation files under /compat/linux/
sudo pkg install debootstrap
sudo debootstrap focal /compat/linux/
 
# Run a Linux binary shell directly
/compat/linux/bin/bash --version

System Diagnostics, Tuning & Troubleshooting

Runtime Tuning via sysctl

  • The sysctl utility reads and writes kernel variables at runtime:
# Query all available sysctl kernel variables
sysctl -a
 
# Enable IP forwarding (routing) immediately
sudo sysctl net.inet.ip.forwarding=1
 
# Configure larger TCP socket buffers to optimize network speeds
sudo sysctl net.inet.tcp.sendspace=65536
sudo sysctl net.inet.tcp.recvspace=65536
 
# Make changes permanent by adding them to /etc/sysctl.conf
echo "net.inet.ip.forwarding=1" | sudo tee -a /etc/sysctl.conf

System Monitoring and Diagnostics Tools

  • Use the following tools to monitor system resources:
  • top: Monitor CPU usage and running processes.
  • vmstat: Display virtual memory statistics, page faults, and trap calls.
  • iostat: Monitor disk I/O operations and CPU usage.
  • netstat: Monitor network connections, routing tables, and interface statistics.
  • systat: Provides full-screen, interactive system statistics (e.g., systat -vmstat, systat -ifstat).
  • sockstat: Lists active sockets and the processes using them.
# List all processes listening on open TCP or UDP ports
sockstat -4 -l
 
# Monitor system swap page allocations every 2 seconds
vmstat -w 2

Dynamic Tracing via DTrace on FreeBSD

  • DTrace allows administrators to trace kernel functions and user space applications in real-time without modifying the target code.

DTrace Probes and Providers

  • DTrace monitors execution points called probes grouped under providers:
  • syscall: Traces the entry and exit points of system calls.
  • fbt (Function Boundary Tracing): Traces entry and exit paths of almost every function inside the FreeBSD kernel.
  • io: Instruments disk I/O operations.

Custom DTrace Script Examples

# Trace all system calls executed by a specific process ID (PID 1025)
sudo dtrace -n 'syscall:::entry /pid == 1025/ { @[probefunc] = count(); }'
 
# Count files opened by process name
sudo dtrace -n 'syscall::open*:entry { @[execname] = count(); }'

Kernel Crash Dumps and Debugging

  • When a kernel panic occurs, the system can write a dump of physical memory to disk for analysis.
# Configure a dedicated dump device in /etc/rc.conf
dumpdev="AUTO"
 
# After a crash, look for crash logs inside /var/crash/
# Analyze the dump using the kernel debugger kgdb
sudo kgdb /boot/kernel/kernel /var/crash/vmcore.0

ZFS Copy-on-Write (CoW) Simulation (C Program)

ZFS Copy-on-Write Simulation

  • Below is a complete C program simulating a Copy-on-Write (CoW) block store filesystem engine.
  • It features dataset transactions, transaction commits, deduplication matching block hashes, compression, metadata updates, and snapshot rollbacks:
/* ==============================================================================
 * File: zfs_cow_simulation.c
 * Description: Simulation of ZFS Copy-on-Write (CoW) file system transactions.
 * Author: VR-Rathod
 * ==============================================================================
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
 
#define BLOCK_SIZE 128
#define MAX_BLOCKS 64
#define MAX_SNAPSHOTS 4
 
// Structure representing a storage block on disk
typedef struct {
    uint8_t data[BLOCK_SIZE];
    uint32_t hash;
    bool allocated;
} DiskBlock;
 
// Structure representing filesystem metadata pointers
typedef struct {
    uint32_t block_pointers[MAX_BLOCKS];
    uint32_t transaction_id;
} FilesystemMetadata;
 
// Structure representing a filesystem snapshot
typedef struct {
    FilesystemMetadata metadata;
    char name[32];
    bool active;
} SnapshotStore;
 
// Global Virtual Disk Pool
DiskBlock g_disk[MAX_BLOCKS];
FilesystemMetadata g_active_meta;
SnapshotStore g_snapshots[MAX_SNAPSHOTS];
uint32_t g_snapshot_count = 0;
 
// Simple DJB2 hashing function for block deduplication
uint32_t calculate_hash(const uint8_t *data) {
    uint32_t hash = 5381;
    for (int i = 0; i < BLOCK_SIZE; i++) {
        hash = ((hash << 5) + hash) + data[i];
    }
    return hash;
}
 
// Initialize virtual disk components
void init_system() {
    for (int i = 0; i < MAX_BLOCKS; i++) {
        memset(g_disk[i].data, 0, BLOCK_SIZE);
        g_disk[i].hash = 0;
        g_disk[i].allocated = false;
    }
    
    for (int i = 0; i < MAX_BLOCKS; i++) {
    // Default unallocated pointer is -1
        g_active_meta.block_pointers[i] = -1;
    }
    g_active_meta.transaction_id = 0;
    
    for (int i = 0; i < MAX_SNAPSHOTS; i++) {
        g_snapshots[i].active = false;
    }
    printf("[ZFS SIM] System initialized. Disk size: %d blocks of %d bytes.\n", MAX_BLOCKS, BLOCK_SIZE);
}
 
// Allocate a free block on the virtual disk
int allocate_block() {
    for (int i = 0; i < MAX_BLOCKS; i++) {
        if (!g_disk[i].allocated) {
            g_disk[i].allocated = true;
            return i;
        }
    }
    return -1;
}
 
// Write data to the filesystem using Copy-on-Write (CoW)
bool write_file(uint32_t file_index, const uint8_t *data) {
    if (file_index >= MAX_BLOCKS) return false;
    
    uint32_t hash = calculate_hash(data);
    
    // 1. Deduplication check: check if an identical block already exists on disk
    for (int i = 0; i < MAX_BLOCKS; i++) {
        if (g_disk[i].allocated && g_disk[i].hash == hash) {
            if (memcmp(g_disk[i].data, data, BLOCK_SIZE) == 0) {
                printf("[DEDUP] Match found at block %d. Re-using existing block pointer.\n", i);
                g_active_meta.block_pointers[file_index] = i;
                return true;
            }
        }
    }
    
    // 2. Allocate a new block (Copy-on-Write behavior)
    int new_block_idx = allocate_block();
    if (new_block_idx == -1) {
        printf("[ERROR] Out of storage space!\n");
        return false;
    }
    
    // Copy data to the new block and calculate its hash
    memcpy(g_disk[new_block_idx].data, data, BLOCK_SIZE);
    g_disk[new_block_idx].hash = hash;
    
    // Update active metadata pointers to target the new block index
    g_active_meta.block_pointers[file_index] = new_block_idx;
    printf("[CoW WRITE] File index %d written to new block %d.\n", file_index, new_block_idx);
    return true;
}
 
// Read file contents from the active metadata mapping
bool read_file(uint32_t file_index, uint8_t *buffer) {
    if (file_index >= MAX_BLOCKS) return false;
    
    uint32_t block_idx = g_active_meta.block_pointers[file_index];
    if (block_idx == -1 || !g_disk[block_idx].allocated) {
        printf("[ERROR] File index %d contains no allocated data.\n", file_index);
        return false;
    }
    
    memcpy(buffer, g_disk[block_idx].data, BLOCK_SIZE);
    return true;
}
 
// Create a read-only point-in-time snapshot of the active metadata
bool create_snapshot(const char *name) {
    if (g_snapshot_count >= MAX_SNAPSHOTS) {
        printf("[ERROR] Snapshot storage limit reached!\n");
        return false;
    }
    
    g_snapshots[g_snapshot_count].metadata = g_active_meta;
    strncpy(g_snapshots[g_snapshot_count].name, name, 32);
    g_snapshots[g_snapshot_count].active = true;
    
    printf("[SNAPSHOT CREATED] Saved snapshot '%s' (Tx ID: %d).\n", name, g_active_meta.transaction_id);
    g_snapshot_count++;
    return true;
}
 
// Rollback active metadata state to match a saved snapshot
bool rollback_snapshot(const char *name) {
    for (int i = 0; i < MAX_SNAPSHOTS; i++) {
        if (g_snapshots[i].active && strcmp(g_snapshots[i].name, name) == 0) {
            g_active_meta = g_snapshots[i].metadata;
            printf("[SNAPSHOT ROLLBACK] Restored system metadata to snapshot '%s'.\n", name);
            return true;
        }
    }
    printf("[ERROR] Snapshot '%s' not found.\n", name);
    return false;
}
 
// Display active block allocations on the virtual disk
void print_system_status() {
    printf("\n=== ACTIVE FILE ALLOCATIONS ===\n");
    for (int i = 0; i < 8; i++) {
        uint32_t ptr = g_active_meta.block_pointers[i];
        if (ptr == -1) {
            printf("- File %d: Unallocated\n", i);
        } else {
            printf("- File %d: Points to disk block %d (Hash: 0x%08X)\n", i, ptr, g_disk[ptr].hash);
        }
    }
    printf("================================\n\n");
}
 
int main() {
    printf("=== OPENZFS COPY-ON-WRITE SIMULATOR ===\n");
    init_system();
    
    uint8_t buffer[BLOCK_SIZE];
    uint8_t data_v1[BLOCK_SIZE];
    uint8_t data_v2[BLOCK_SIZE];
    
    memset(data_v1, 'A', BLOCK_SIZE);
    memset(data_v2, 'B', BLOCK_SIZE);
    
    // 1. Write initial files
    write_file(0, data_v1);
    write_file(1, data_v1); // Deduplication should match here
    
    print_system_status();
    
    // 2. Create a snapshot before modifying files
    create_snapshot("snap1");
    
    // 3. Modify files using Copy-on-Write (CoW)
    g_active_meta.transaction_id++;
    write_file(0, data_v2); // Writes to a new block; old block remains intact for the snapshot
    
    print_system_status();
    
    // Read modified file contents
    read_file(0, buffer);
    printf("[READ] File 0 active data: %c...\n", buffer[0]);
    
    // 4. Rollback to snapshot 1
    rollback_snapshot("snap1");
    
    // Verify file data restored to original state
    read_file(0, buffer);
    printf("[READ] File 0 post-rollback data: %c...\n", buffer[0]);
    
    print_system_status();
    return 0;
}

Shell & Automation Scripts

FreeBSD Production-Ready Automation Scripts

  • Below are five complete, production-grade automation scripts designed for FreeBSD system administrators:

Script 1: FreeBSD Jail Provisioner and VNET Network Setup

  • Automated creation, userland extraction, and VNET bridging for FreeBSD jails:
#!/bin/sh
# ==============================================================================
# Script: jail_provisioner.sh
# Description: Automates extraction and VNET configuration setups for FreeBSD Jails.
# Author: VR-Rathod
# ==============================================================================
 
JAIL_NAME=$1
JAIL_IP=$2
JAIL_DIR="/usr/jail/${JAIL_NAME}"
BASE_TXZ="/usr/freebsd-dist/base.txz"
 
if [ -z "$JAIL_NAME" ] || [ -z "$JAIL_IP" ]; then
    echo "Usage: $0 <jail-name> <ip-address>"
    exit 1
fi
 
echo "[INFO] Creating directory: ${JAIL_DIR}"
mkdir -p "${JAIL_DIR}"
 
# Extract base userland components
if [ -f "$BASE_TXZ" ]; then
    echo "[INFO] Extracting base system files to jail directory..."
    tar -xf "$BASE_TXZ" -C "${JAIL_DIR}"
else
    echo "[ERROR] base.txz archive not found at ${BASE_TXZ}!"
    exit 1
fi
 
# Copy host DNS settings
cp /etc/resolv.conf "${JAIL_DIR}/etc/resolv.conf"
 
# Append jail configuration to /etc/jail.conf
cat <<EOF >> /etc/jail.conf
 
${JAIL_NAME} {
    host.hostname = "${JAIL_NAME}.local";
    path = "${JAIL_DIR}";
    ip4.addr = "${JAIL_IP}";
    mount.devfs;
    exec.clean;
    exec.start = "/bin/sh /etc/rc";
    exec.stop = "/bin/sh /etc/rc.shutdown";
    allow.raw_sockets = 1;
}
EOF
 
echo "[SUCCESS] Jail ${JAIL_NAME} provisioned. Start it with: service jail start ${JAIL_NAME}"
exit 0

Script 2: ZFS Automatic Snapshot and Retention Pruning Daemon

  • Automatically creates dataset snapshots and prunes snapshots older than a retention threshold:
#!/bin/sh
# ==============================================================================
# Script: zfs_snapshot_daemon.sh
# Description: Automates hourly OpenZFS snapshots and prunes expired snapshots.
# Author: VR-Rathod
# ==============================================================================
 
DATASET="zroot/usr/home"
SNAP_PREFIX="auto_hourly"
KEEP_COUNT=24 # Keep 24 hourly snapshots
 
echo "[INFO] Starting ZFS snapshot sequence for dataset: ${DATASET}"
 
# 1. Create a new snapshot
TIMESTAMP=$(date "+%Y%m%d%H%M%S")
NEW_SNAP="${DATASET}@${SNAP_PREFIX}_${TIMESTAMP}"
zfs snapshot "$NEW_SNAP"
echo "[SUCCESS] Snapshot created: ${NEW_SNAP}"
 
# 2. Prune old snapshots exceeding retention limit
SNAP_LIST=$(zfs list -H -t snapshot -o name -S creation | grep "${DATASET}@${SNAP_PREFIX}")
COUNT=0
 
for snap in $SNAP_LIST; do
    COUNT=$((COUNT + 1))
    if [ "$COUNT" -gt "$KEEP_COUNT" ]; then
        echo "[PRUNE] Deleting expired snapshot: ${snap}"
        zfs destroy "$snap"
    fi
done
 
echo "[INFO] ZFS snapshot pruning sequence complete."
exit 0

Script 3: PF Firewall Traffic Audit and Dynamic IP Blacklisting Watchdog

  • Audits system logs for connection failures and updates PF firewall tables to block source IPs dynamically:
#!/bin/sh
# ==============================================================================
# Script: pf_blacklister.sh
# Description: Audits auth logs for ssh failures and adds offensive IPs to PF tables.
# Author: VR-Rathod
# ==============================================================================
 
AUTH_LOG="/var/log/auth.log"
PF_TABLE="bad_ips"
FAILURE_LIMIT=5
TEMP_FILE="/tmp/failed_login_ips"
 
# Extract IP addresses with failed SSH attempts from auth logs
grep "Failed password for" "$AUTH_LOG" | awk '{print $(NF-3)}' | sort | uniq -c > "$TEMP_FILE"
 
while read -r count ip; do
    if [ -n "$count" ] && [ "$count" -gt "$FAILURE_LIMIT" ]; then
        # Verify if the IP is already blocked in the PF table
        ALREADY_BLOCKED=$(pfctl -t "$PF_TABLE" -T show 2>/dev/null | grep -c "$ip")
        if [ "$ALREADY_BLOCKED" -eq 0 ]; then
            echo "[BLOCK] IP ${ip} exceeded limit with ${count} failures. Adding to PF table..."
            pfctl -t "$PF_TABLE" -T add "$ip"
            # Notify system logs
            logger -t pf_blacklister "Blocked IP ${ip} after ${count} SSH authentication failures."
        fi
    fi
done < "$TEMP_FILE"
 
rm -f "$TEMP_FILE"
exit 0

Script 4: Automated Package Audit and Base Update Cron

  • Triggers security vulnerability audits and checks for base operating system updates:
#!/bin/sh
# ==============================================================================
# Script: security_audit.sh
# Description: Automates package audits and checks for base system updates.
# Author: VR-Rathod
# ==============================================================================
 
REPORT_FILE="/var/log/security_audit_report.log"
echo "=== SECURITY REPORT [$(date)] ===" > "$REPORT_FILE"
 
# 1. Audit binary packages
echo "[INFO] Running package vulnerability check..." >> "$REPORT_FILE"
pkg audit -F >> "$REPORT_FILE" 2>&1
 
# 2. Check for base system updates
echo "\n[INFO] Checking for FreeBSD base system updates..." >> "$REPORT_FILE"
freebsd-update updatesready >> "$REPORT_FILE" 2>&1
 
# Trigger root mail alert if vulnerabilities are found
VULN_COUNT=$(grep -c "vulnerabilities found" "$REPORT_FILE")
if [ "$VULN_COUNT" -gt 0 ]; then
    mail -s "FreeBSD Security Audit Alert" root < "$REPORT_FILE"
fi
 
exit 0

Script 5: System Performance Tuning Optimizer (sysctl Auto-Tuner)

  • Optimizes kernel settings for maximum network and database throughput:
#!/bin/sh
# ==============================================================================
# Script: performance_tuner.sh
# Description: Optimizes kernel settings for high-throughput network performance.
# Author: VR-Rathod
# ==============================================================================
 
echo "[INFO] Starting kernel tuning configurations..."
 
# 1. Optimize socket buffer spaces
sysctl net.inet.tcp.sendspace=131072
sysctl net.inet.tcp.recvspace=131072
 
# 2. Increase maximum socket connections queue length
sysctl kern.ipc.soacceptqueue=1024
 
# 3. Enable TCP Fast Open (speeds up subsequent connections)
sysctl net.inet.tcp.fastopen.server_enable=1
sysctl net.inet.tcp.fastopen.client_enable=1
 
# 4. Increase maximum file descriptor limit
sysctl kern.maxfiles=204800
 
# 5. Enable ZFS prefetch (highly recommended for single-user desktops/databases)
sysctl vfs.zfs.prefetch_disable=0
 
echo "[SUCCESS] Kernel tuning settings applied successfully."
exit 0

FreeBSD Command Reference

Complete Command Reference (150+ Commands)

System Administration & Information

sw_vers                         # Display FreeBSD product name and build version
sysctl -a                       # Query all active kernel state variables
sysctl kern.version             # Read specific kernel version string details
sysctl kern.maxfiles            # Query maximum open file descriptors limit
uname -a                        # Display system details, architecture, and kernel flags
freebsd-version -k              # Show the installed kernel version
freebsd-version -u              # Show the installed userland version
dmesg                           # Read the system boot and kernel message buffers
date                            # Display or adjust system calendar time settings
uptime                          # Show system uptime, load averages, and user count
shutdown -h now                 # Power down the system immediately
shutdown -r now                 # Reboot the system immediately
acpiconf -s 3                   # Suspend system to RAM (S3 state)
powerd -v                       # Start dynamic CPU frequency scaling control daemon
sysrc -a                        # List all configuration variables defined in rc.conf
sysrc sshd_enable="YES"         # Safely write/modify service state in rc.conf
service -l                      # List all active rc.d scripts
service sshd status             # Query run status of sshd daemon service
service sshd start              # Start sshd daemon service
service sshd restart            # Restart sshd daemon service
service sshd reload             # Reload sshd configuration file changes
service sshd stop               # Stop sshd daemon service
kldstat                         # List all currently loaded kernel modules
kldload zfs                     # Load dynamic kernel linker module
kldunload zfs                   # Unload dynamic kernel module
locale                          # Print active language and encoding configurations
pciconf -lv                     # List PCI bus hardware devices and vendor codes
usbconfig                       # List USB controllers and attached devices
devinfo                         # Print system hardware device trees
eeprom                          # Display or modify system motherboard configuration parameters

Storage & Filesystem Administration

gpart show                      # Display partition layout mappings on all disks
gpart create -s gpt ada0        # Create a GPT partition table on disk ada0
gpart add -t freebsd-zfs ada0   # Create a ZFS partition on disk ada0
gpart destroy -F ada0           # Force-destroy partition table structures
newfs -U /dev/ada0p4            # Format partition with UFS2 using Soft Updates
tunefs -j enable /dev/ada0p4    # Enable Soft Updates Journaling (SU+J) on partition
fsck -y /dev/ada0p4             # Scan and repair UFS2 partition, auto-fixing issues
mount /dev/ada0p4 /mnt          # Mount partition to target directory path
mount -t cd9660 /dev/cd0 /mnt   # Mount ISO 9660 CD-ROM device
umount /mnt                     # Unmount target device mount point
df -h                           # Display mounted file system space usage
du -sh /var/log/                # Calculate directory space usage
zpool create mypool ada0        # Create a ZFS storage pool named mypool
zpool destroy mypool            # Delete ZFS storage pool and free disks
zpool status mypool             # Display pool health, device structure, and scrub progress
zpool list                      # List ZFS pools, space allocations, and health states
zpool scrub mypool              # Trigger parity verification scan on ZFS pool
zpool online mypool ada0        # Set disk state to online inside ZFS pool
zpool offline mypool ada0       # Take disk offline inside ZFS pool
zfs list                        # List all active datasets, mount points, and space usage
zfs create mypool/data          # Create a new ZFS dataset
zfs destroy mypool/data         # Delete ZFS dataset and free blocks
zfs set compression=lz4 mypool  # Enable lz4 compression on dataset
zfs set encryption=on mypool    # Enable dataset native encryption
zfs snapshot mypool/data@snap1  # Create point-in-time snapshot
zfs rollback mypool/data@snap1  # Rollback dataset state to snapshot
zfs send mypool/data@snap1      # Serialize ZFS snapshot stream for replication
zfs recv mypool/backup          # Receive and reconstruct ZFS snapshot stream
zfs mount                       # List or mount ZFS datasets
zfs umount mypool/data          # Unmount ZFS dataset

Process Management & System Diagnostics

ps aux                          # Display running processes
pgrep -u root sshd              # Find process IDs matching criteria
pkill -9 -u testuser            # Kill processes matching criteria immediately
kill -15 1024                   # Terminate process gracefully using SIGTERM
kill -9 1024                    # Terminate process immediately using SIGKILL
top -o cpu                      # Monitor system processes, sorted by CPU usage
htop                            # Interactive process viewer (install via pkg)
vmstat -z                       # Print kernel memory zones usage stats
iostat -w 1                     # Print disk I/O metrics every second
systat -ifstat                  # Interactive, full-screen network interface statistics
systat -vmstat                  # Interactive virtual memory and scheduling statistics
fstat -p 1024                   # List open files held by specific process ID
sockstat -4 -l                  # List processes listening on open TCP/UDP ports
procstat -f 1024                # Print detailed file descriptor table of a process
limit                           # Display shell session resource limits
ulimit -n 2048                  # Adjust open file descriptors limit in shell
nice -n 10 backup_script.sh     # Run process with low priority level
renice +15 -p 1024              # Lower priority level of active process ID
lsof                            # List open files (install via pkg)
watch -n 5 "date"               # Run command repeatedly every 5 seconds (install via pkg)

Networking & Port Diagnostics

ifconfig                        # List active network interfaces and configurations
ifconfig em0 up                 # Enable network interface card em0
ifconfig em0 down               # Disable network interface card em0
ifconfig em0 inet 192.168.1.5   # Configure IP address on interface em0
dhclient em0                    # Request DHCP lease configuration on interface em0
route add default 192.168.1.1   # Add default gateway path to routing table
route show                      # Display active network routing tables
ping -c 5 1.1.1.1               # Send ICMP echo requests to verify remote host
traceroute 8.8.8.8              # Display hop path to remote destination
netstat -rn                     # Display active routing tables in numeric format
netstat -i                      # Display network interface statistics
netstat -an | grep LISTEN       # List open sockets listening for incoming connections
arp -a                          # Display ARP IP-to-MAC address mapping tables
dig @8.8.8.8 google.com         # Perform DNS lookup queries using Google DNS
host google.com                 # Perform quick DNS host resolution query
nc -zv 192.168.1.100 22         # Test connection to remote port (Netcat)
curl -I https://freebsd.org     # Fetch HTTP headers of target web server
fetch https://site.com/file.zip # Download file over HTTP/FTP
tcpdump -i em0                  # Capture network packets passing through interface em0
ndp -an                         # Display IPv6 neighbor cache mapping details

Jail Virtualization & Administration

jls                             # List running jails and their IP assignments
jail -c myjail                  # Create and start a jail defined in jail.conf
jail -r myjail                  # Remove/stop a running jail
jexec myjail /bin/sh            # Execute an interactive command shell inside a jail
jexec myjail service sshd start # Start daemon service inside running jail
pkg -j myjail install apache24  # Install binary package inside target jail
ezjail-admin list               # List jails managed by ezjail utility (install via pkg)
iocage list                     # List jails managed by iocage utility (install via pkg)
iocage console myjail           # Open console session inside iocage jail
iocage destroy myjail           # Force-destroy iocage jail

Package & Ports Management

pkg update                      # Update package repository index catalog
pkg upgrade                     # Upgrade installed binary packages to latest versions
pkg install git                 # Install a binary package
pkg delete git                  # Uninstall an installed binary package
pkg search nmap                 # Search repositories for matching packages
pkg info tmux                   # Display metadata details of an installed package
pkg which /usr/local/bin/tmux   # Query package mapping of a binary file path
pkg audit -F                    # Run security audits on installed packages
pkg autoremove                  # Delete orphaned dependencies
pkg clean                       # Clean download binary package caches
pkg stats                       # Display package repository size statistics
pkg lock nginx                  # Lock package to prevent automatic upgrades
pkg unlock nginx                # Unlock package to permit upgrades
pkg register                    # Register package configurations in local database
pkg-static                      # Static version of pkg used for system recoveries

Security, Auditing & Hardening

chflags schg critical_file      # Set system immutable flag on a file
chflags noschg critical_file    # Clear system immutable flag on a file
ls -lao                         # List directory files displaying system flags
pw groupadd dev                 # Create system user group
pw useradd test -g dev -m       # Create system user account
pw userdel test -r              # Delete user account and home directories
vipw                            # Safely edit system master password file
passwd root                     # Change password of root user account
su -                            # Elevate to root account (requires wheel group)
pfctl -e                        # Enable the PF firewall engine
pfctl -d                        # Disable the PF firewall engine
pfctl -f /etc/pf.conf           # Load firewall rules from pf.conf file
pfctl -sr                       # Display currently loaded firewall rules
pfctl -ss                       # Display active state tables of the firewall
pfctl -t bad_ips -T show        # List IP addresses stored inside PF table bad_ips
pfctl -t bad_ips -T add 1.1.1.1 # Add IP address to PF firewall table bad_ips
ipfw list                       # List active IPFW firewall rules
ipfw delete 100                 # Delete IPFW firewall rule number 100
praudit /var/audit/current      # Display binary audit log files in readable format
audit -s                        # Send event notification signal to audit daemon
freebsd-update fetch            # Fetch security and base operating system updates
freebsd-update install          # Install fetched system patches

Custom Development & Kernel Compilation

  • FreeBSD is built using the standard LLVM/Clang compiler toolchain.

The /usr/src/ Tree Layout

  • /usr/src/sys: Contains kernel source files, schedulers, device drivers, and filesystems.
  • /usr/src/usr.bin: Source files for standard user commands.
  • /usr/src/lib: Core C libraries.

Compiling a Custom Kernel

  • To build a custom kernel, copy the GENERIC configuration file, make modifications, and compile:
# Navigate to the kernel configurations directory
cd /usr/src/sys/amd64/conf
 
# Copy the GENERIC configuration file to compile a custom profile
sudo cp GENERIC MYKERNEL
 
# Edit configuration using a text editor
# E.g., add options or remove unused drivers to shrink kernel size
# options          IPFIREWALL
# options          IPFIREWALL_DEFAULT_TO_ACCEPT
sudo vi MYKERNEL
 
# Build the kernel from configuration
cd /usr/src
sudo make buildkernel KERNCONF=MYKERNEL
 
# Install the compiled kernel files (replaces /boot/kernel/ with the new build)
sudo make installkernel KERNCONF=MYKERNEL

More Learn

Github & Webs

Master Playlists YouTube