Forked from NetBSD. Theo de Raadt is the founder and leader of the OpenBSD project. The source tree was imported into CVS on October 18, 1995.
Software and ideas developed or maintained by the OpenBSD project: https://www.openbsd.org/innovations.html
Choose your repository at: https://www.openbsd.org/anoncvs.html
Browse the source tree in your browser and read each file's revision history: https://cvsweb.openbsd.org
# How to read a man page, for example foo(5) ?
man 5 foo
Or view it on your browser at: https://man.openbsd.org
Platforms: https://www.openbsd.org/plat.html
Real-world dmesgs: NYC*BUG dmesgd
Really simple, ready in 5 minutes (KISS). Most of the time, pressing Enter at each question gives a good default install.
Get more information: https://www.openbsd.org/faq/faq4.html
For a full unattended install/upgrade process, you can easily use autoinstall(8).
OpenBSD uses FFS2 (Enhanced Fast File System) by default.
Read: newfs(8)
| /etc/myname | Default hostname |
| /etc/mygate | Default gateway |
| /etc/hosts | Known hosts on the network |
| /etc/resolv.conf | Resolver (DNS), maintained by resolvd(8) |
| /etc/hostname.if | Configuration for each network interface, for example: /etc/hostname.bge0 |
Read: myname(5), mygate(5), hostname.if(5), resolv.conf(5), resolvd(8), hosts(5)
# Display the current configuration of network interfaces
ifconfig
# Set DHCP for 're0' interface, on the fly
ifconfig re0 inet autoconf
# Perform network (re)initialisation
sh /etc/netstart
Your interface name depends on your hardware. Checkifconfigoutput and read the relevant man page (e.g.man iwx,man bge).
## File: /etc/hostname.re0
inet 192.168.0.58 255.255.255.0
Don't forget to run sh /etc/netstart re0 to apply changes to running system.
With a static address, set the default gateway in /etc/mygate.
## File: /etc/hostname.bge0
inet autoconf
Don't forget to run sh /etc/netstart bge0 to apply changes to running system.
# First, see a list of available wireless networks:
ifconfig iwx0 scan
## File: /etc/hostname.iwx0
nwid ACCESS_POINT_NAME wpakey THE_SECRET_KEY
inet autoconf
# Or, for multiple access points
join AT_HOME wpakey THE_SECRET_KEY
join AT_WORK wpakey THE_SECRET_KEY
inet autoconf
Don't forget to run sh /etc/netstart iwx0 to apply changes to running system.
# Show the routing table (ipv4)
route -n show -inet
# Show the routing table (ipv6)
route -n show -inet6
# Delete all gateway entries from the routing table
route -n flush
On a server you reach through a router, route -n flush also removes the default route, and your SSH session goes with it.
Read: route(8)
# Disable PF (removes all filtering)
pfctl -d
# Check the rules, always before loading them
pfctl -nf /etc/pf.conf
# Enable PF and load the rules
pfctl -ef /etc/pf.conf
# Just load the rules (apply changes)
pfctl -f /etc/pf.conf
# View the loaded rules
pfctl -s rules
Read: pfctl(8)
## File: /etc/pf.conf
# Protect a laptop (allow only ping/ssh from anywhere, IPv4 only)
# SSH protected by source limiter
set skip on lo
source limiter "ssh-protect" id 1 \
entries 10000 limit 3 rate 5/60
block log all
pass in on egress inet proto icmp all icmp-type echoreq
pass in on egress inet proto tcp from any to any port ssh \
source limiter "ssh-protect"
pass out
Read: pf.conf(5)
# Watch PF logs
tcpdump -nettti pflog0
# Watch traffic on egress (no DNS resolution)
tcpdump -n -i egress
# Filter by host / by port
tcpdump -n host 192.168.1.100
tcpdump -n port 22
# Watch DNS queries
tcpdump -n udp port 53
# Save capture to file / read it back
tcpdump -w capture.pcap -i egress
tcpdump -r capture.pcap
Read: tcpdump(8)
Network Management with the OpenBSD Packet Filter Toolset
(EuroBSDCon 2026)
# Manually
user [add|del|info|mod] foobar
# Add a user and create the home directory
user add -m foobar
# Add users interactively
adduser
# Remove users interactively
rmuser
Read: adduser(8), rmuser(8), user(8)
group [add|del|info|mod] foobar
Members in wheel group can use su(1) to become root.
Read: group(8), group(5), rmgroup(8)
## File: /etc/doas.conf
# Permit the user 'marc' to reboot the box
permit nopass marc as root cmd /sbin/reboot
# Check the file syntax
doas -C /etc/doas.conf
# As marc, check the rule for this command (prints: permit nopass)
doas -C /etc/doas.conf /sbin/reboot
# Marc can now reboot the box
$ doas /sbin/reboot
Read: doas(1), doas.conf(5)
## File: /etc/installurl
# By default, it already contains an OpenBSD mirror server URL
https://cdn.openbsd.org/pub/OpenBSD
# Search for packages
pkg_info -Q foobar
# For example, to install Squid
pkg_add squid
# Update packages
pkg_add -u
Look in /usr/local/share/doc/pkg-readmes for extra documentation.
Read: pkg_info(1), pkg_add(1), installurl(5)
# List packages installed
pkg_info
# List files installed by a package
pkg_info -L foobar
# View install-message for a specific package
pkg_info -M foobar
Read: pkg_info(1), packages(7)
# Delete a Package
pkg_delete foobar
# Show unused dependencies
pkg_delete -an
# Delete unused dependencies
pkg_delete -a
# Delete all except 'nginx' (read the output, then rerun without -n)
pkg_delete -nX nginx
Read: pkg_delete(1)
fw_update
Firmware is downloaded from release-specific directories at: https://firmware.openbsd.org/firmware
Read: fw_update(8)
rcctl [enable|disable|start|stop|reload|restart] foobar
# For example, to start the apmd(8) daemon for CPU scaling, you might do
rcctl enable apmd
rcctl set apmd flags -A
rcctl start apmd
Read: rcctl(8), rc.conf(8), rc.conf.local(8)
rcctl ls on
Read: rcctl(8)
Read: rc(8), rc.firsttime(8), rc.local(8), rc.securelevel(8)
# 1. Port 80 server only in /etc/httpd.conf (next slide)
rcctl enable httpd
rcctl start httpd
# 2. Get the certificate (replace example.com first)
cp /etc/examples/acme-client.conf /etc/
acme-client -v example.com
# 3. Add the tls server, test, reload
httpd -n && rcctl reload httpd
# 4. Renew automatically, in root's crontab
~ * * * * acme-client example.com && rcctl reload httpd
Read: httpd(8), httpd.conf(5), acme-client(1), acme-client.conf(5)
## File: /etc/httpd.conf
server "example.com" {
listen on * port 80
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
location "*" {
block return 301 "https://$HTTP_HOST$REQUEST_URI"
}
}
server "example.com" {
listen on * tls port 443
tls certificate "/etc/ssl/example.com.fullchain.pem"
tls key "/etc/ssl/private/example.com.key"
}
Site files go in /var/www/htdocs. Read: httpd.conf(5)
## Inside a server block of /etc/httpd.conf
# Response headers ("always" adds them to 4xx/5xx errors too)
header set "X-Content-Type-Options" "nosniff" always
header set "X-Frame-Options" "DENY" always
# Refuse requests on a header (AI crawlers, scanners),
# but a User-Agent is easy to fake
header block "User-Agent" "*GPTBot*" 403
header block "User-Agent" "*ClaudeBot*" 403
header drop "User-Agent" "*WPScan*"
New in 8.0: httpd sets its own headers, no relayd needed for that. Read: httpd.conf(5)
# Check CPU support, get vmm-firmware, enable the hypervisor
dmesg | egrep '(VMX/EPT|SVM/RVI)'
fw_update
rcctl enable vmd
rcctl start vmd
# Create a disk, boot install80.iso (2 VCPUs, local network)
vmctl create -s 20G disk.qcow2
vmctl start -m 1G -p 2 -L -i 1 -r install80.iso -d disk.qcow2 myvm
# List VMs, attach the console (leave with ~.), stop
vmctl show
vmctl console myvm
vmctl stop myvm
Read: vmm(4), vmd(8), vmctl(8), vm.conf(5)
Any security or reliability fixes can be found at:
https://www.openbsd.org/errata.html
Errata patches are generated for the 2 last releases (7.9, 8.0).
Use syspatch(8) to update your kernel and userland. Binary patches are generated for the 2 last releases only, on amd64, arm64 and i386.
And pkg_add -u to update packages.
One release at a time. To upgrade 7.8 to 8.0, follow: https://www.openbsd.org/faq/upgrade79.html
and then
https://www.openbsd.org/faq/upgrade80.html
sysupgrade(8) upgrades OpenBSD to the next release or a new snapshot.
pkg_add sysclean
sysclean only lists. It removes nothing. Review the output, then delete what you no longer need.
| The most important to know! | |
|---|---|
| / | Root directory |
| /home | User home directories |
| /root | Default home directory for the superuser |
| /mnt | A temporary mount point |
| /etc | System configuration files and scripts |
| /etc/examples | Example configuration files for base system daemons |
| /etc/skel | (dot) files for new accounts |
| /etc/signify | Key files used for signify(1) |
| /tmp | Cleaned after a reboot |
| /var/tmp | Symbolic link to the system /tmp |
| /var/log | Log files |
| /var/run | pid, socket files, utmp, dmesg.boot |
| /var/db | Database files |
| /var/www | chroot directory for httpd(8) |
| /var/www/htdocs | Web repository for httpd(8) |
| /usr/local | Third-party software goes here |
| /usr/src | BSD and/or local source files |
Read: hier(7)
/bsd
The kernel itself, loaded into memory at boot. At each boot, KARL (Kernel Address Randomized Link) relinks a new /bsd in random order for the next boot, so every boot runs a unique kernel.
On a multiprocessor machine, the installer renames /bsd to /bsd.sp, then /bsd.mp to /bsd.
/obsd
Previous kernel, saved when you build and install a kernel yourself (release(8)). If the new kernel fails to boot, start the previous one from the boot(8) prompt with boot /obsd.
/bsd.sp
Kernel executable for single processor machines.
/bsd.mp
Kernel executable for multiprocessor machines.
/bsd.rd
Installation kernel. Its built-in RAM disk holds tools that run without an external file system, so it is useful for system maintenance too.
config(8) can enable, disable or change devices in a kernel binary, with no recompile. The same editor is available at boot: type boot -c at the prompt, see boot_config(8).
These edits are lost on upgrade and block kernel relinking. Keep them in bsd.re-config(5) instead.
sysctl.conf(5) sysctl variables to set at system startup
sysctl(8) get or set kernel state
&
config(8) modify a kernel
| machdep.lidaction=0 | do nothing |
| machdep.lidaction=1 | suspend (deep sleep) |
| machdep.lidaction=2 | hibernate (memory saved to swap, then power off) |
Make it permanent in/etc/sysctl.conf, see/etc/examples/sysctl.conffor moremachdepvariables.
Read: acpibtn(4), sysctl.conf(5), sysctl(8)
doas pkg_check -F |
Checks that there are no other random objects under /usr/local |
doas dmesg -s |
Review rc(8) system startup messages |
ldd foobar |
List dynamic object dependencies |
df -h |
See disk usage |
top -s .1 |
Check load (cpu/mem) |
Read: pkg_check(8), dmesg(8), ldd(1), ld.so(1), df(1), top(1)
reset |
reset your terminal when it gets messed up by control sequences |
rcctl ls on |
what is enabled on your system |
doas rcctl ls started |
what is running on your system |
Read: reset(1), rcctl(8)
ktrace -f ping.out \ |
trace the process |
kdump -f ping.out |
interprets the data from ktrace into a human readable format |
Read: ktrace(1), kdump(1)
| screenfetch | Display system information in the terminal |
| w3m | Text-based web browser |
| noice | minimalistic file browser |
| pstree | List processes as a tree |
| testdisk | Scan and repair disk partitions |
FAQ: https://www.openbsd.org/faq/
Manual page: afterboot(8)
Web IRC Channel: #openbsd on Libera.Chat
Mailing list: misc@
You can manage your OpenBSD mailing list membership at lists.openbsd.org.
It's time to create your own OpenBSD VM!
Join us on Telegram!
(Nice people, I promise.)