OpenBSD Handbook

    Theme
    • Part I. Install & Configure
      • Introduction to OpenBSD
      • Installing OpenBSD
      • The X Window System
      • Networking on OpenBSD
      • System Configuration
      • OpenBSD Basics
      • Managing Software: Packages and Ports
    • Part II. Daily Operations
      • OpenBSD Desktop Environments
      • Multimedia
      • Printing
      • Linux Compatibility
      • Windows Compatibility
      • Games
    • Part III. System Administration
      • Virtualization
      • Storage and File Systems
      • Updating and Upgrading
      • Localization
      • The OpenBSD Boot Process
      • Security
    • Part IV. Networking & Daemons
      • Services
        • Database
          • MariaDB
          • PostgreSQL
          • Redis
          • memcached
        • Directory
          • YP (NIS)
          • LDAP
        • File
          • NFS
          • Samba
        • FTP Services
          • ftpd
          • ProFTPD
          • vsftpd
          • Pure-FTPd
          • TFTP
        • Mail
          • OpenSMTPD Mail Server
          • Dovecot IMAP and POP3 Server
          • Postfix
          • Exim
          • Rspamd
        • Name
          • Unbound DNS Resolver
          • NSD Authoritative DNS Server
          • BIND DNS Server
        • Networking
          • OpenBGPD
          • rad
          • DHCP on OpenBSD
          • slaacd
        • Web
          • Apache HTTP Server
          • nginx Web Server
          • OpenBSD httpd Web Server
          • relayd Reverse Proxy
        • Logging
          • syslogd
        • Monitoring
          • SNMP
        • Remote Access
          • Audit OpenSSH
          • OpenSSH Server
        • File Synchronization
          • rsync
        • Messaging
          • RabbitMQ Message Broker
        • Time
          • NTP Time Synchronization
        • Load Balancing
          • Build Redundant Load-Balanced Gateways
          • Load Balance Services with NAT or DSR
          • Build an HA HTTPS Load Balancer
      • PF
        • pfctl cheat sheet
        • PF Anchors
        • PF Filter Rules
        • PF Forwarding
        • PF Lists and Macros
        • PF Load Balancing
        • PF Logging
        • PF NAT
        • PF Options
        • PF Policies
        • PF Shortcuts
        • PF Tables
      • Advanced Networking
        • High Availability and State Replication
        • Multi-WAN and Policy-Based Routing
        • VPN and Cryptographic Tunneling
        • Classic and Lightweight Tunnels
        • IPv6 at Scale
        • QoS and Traffic Shaping
        • MPLS and Label Distribution
        • Network Services at Scale
        • Virtualization and Host Networking
        • Large-Scale L2 and L3 Design
        • Telemetry, Logging, and Flow Export
        • Hardening and Operational Safety
        • Reference Architectures
        • Troubleshooting Playbooks
      • Serial Communication
    • Part V. Miscellaneous
      • Virtualization Cheat Sheet
      • OpenBSD Cheatsheet
      • How-to Guides
        • Installation and First Boot
          • Complete the First 30 Minutes After Installation
          • Check Hardware Compatibility Before Installing
          • Bootstrap Wi-Fi Firmware Without Ethernet
          • Run OpenBSD as a Virtual Machine Guest
          • Install OpenBSD on a VPS or Cloud Server
          • Install OpenBSD with Full-Disk Encryption
          • Dual-Boot OpenBSD on a UEFI System
          • Automate OpenBSD Installation with Autoinstall and PXE
        • Desktops and Laptops
          • Set Up OpenBSD as a Laptop or Workstation
          • Configure Laptop Power Management
          • Troubleshoot Web Browsers on OpenBSD
          • Use Plan 9 Tools on OpenBSD
          • Build a Minimal Desktop with suckless Tools
          • Install Z shell (zsh)
        • Networking and Remote Access
          • Create an Administrator Account with doas and SSH Keys
          • Configure Secure Remote Access with OpenSSH
          • Use FIDO Security Keys with OpenSSH
          • Configure Wi-Fi Roaming and Wired Failover
          • Troubleshoot PF, NAT, and Routing
          • Route Multiple VLANs with PF
          • Configure a Road-Warrior WireGuard VPN
          • Route IPv6 Networks without NAT
          • Test OpenBGPD with Two Providers
          • Unlock an Internal Service with an SSH Key
          • Build a Simple Router and Firewall
        • Servers and Services
          • Set Up WordPress on OpenBSD
          • Build a Mail Server with OpenSMTPD, Dovecot, and Rspamd
        • Security, Maintenance and Recovery
          • Establish a Conservative Security Baseline
          • Recover Access and Reset the Root Password
          • Collect OpenBSD Diagnostic Evidence
          • Troubleshoot Package Installation and Update Failures
          • Schedule Recurring Maintenance
          • Monitor an OpenBSD System
          • Back Up and Restore an OpenBSD System
          • Configure softraid RAID1
          • Recover an OpenBSD System That Does Not Boot
        • Building, Automation and Virtual Machines
          • Manage OpenBSD with Ansible
          • Build Third-Party Software from Ports
          • Build OpenBSD from Source
          • Plan a Docker Workload Migration to OpenBSD
      • OpenBSD for Linux Users
      • OpenBSD for FreeBSD Users
      • OpenBSD for macOS Users
    • OpenBSD FAQ
    • OpenBSD Architectures
      • OpenBSD Package Search
        • Synopsis
        • Choose the Execution Account
        • Write a Non-Interactive Script
        • Test the Exact Account and Environment
        • Install a User Crontab Entry
        • Use the Daily, Weekly, and Monthly Framework
        • Direct and Test Maintenance Mail
        • Account for Systems That Sleep or Power Off
        • Remove or Recover a Job

        Schedule Recurring Maintenance

        Synopsis #

        OpenBSD uses cron(8) for scheduled commands and runs the base-system daily, weekly, and monthly maintenance scripts from root’s crontab. Local jobs should run as the least-privileged suitable account, use explicit paths, prevent unintended overlap, and report failure to a monitored mailbox.

        This guide adds and tests one non-interactive job, then explains when to use a user crontab or a daily.local file. Keep credentials in protected files and leave the base /etc/daily, /etc/weekly, and /etc/monthly scripts unchanged.

        Choose the Execution Account #

        Run each job as the account that owns its files and has the service permissions it needs. Use root only for tasks that need access to root-owned files, devices, or system controls. A package daemon’s own account or a dedicated service account is normally safer for application work.

        Before scheduling the job, define:

        • the files and commands it may read or change;
        • its maximum expected runtime;
        • whether two instances may run concurrently;
        • where ordinary output and errors will go;
        • how a missed run will be detected;
        • how the job will be disabled and its effects reversed.

        Write a Non-Interactive Script #

        Place multi-step logic in a reviewed script instead of embedding it in one long crontab line. This example creates a read-only filesystem-capacity check:

        #!/bin/sh
        
        PATH=/bin:/usr/bin:/sbin:/usr/sbin
        export PATH
        
        exec df -h
        

        Install it with explicit ownership and mode:

        doas install -o root -g wheel -m 750 check-filesystems /usr/local/libexec/check-filesystems
        

        Use absolute paths for locally installed programs because cron does not read interactive shell profiles. Load secrets from a root- or service-owned file with restrictive permissions, or use the application’s supported credentials mechanism. Do not place passwords, tokens, or private keys in the crontab command.

        Test the Exact Account and Environment #

        Run the script as its intended account before scheduling it. For a root job:

        doas env -i HOME=/root LOGNAME=root USER=root PATH=/bin:/usr/bin:/sbin:/usr/sbin /usr/local/libexec/check-filesystems
        

        The minimal environment exposes hidden dependencies on a working directory, shell profile, terminal, agent, or unset variable. Confirm the exit status as well as the displayed output:

        echo $?
        

        An exit status of zero must mean success for monitoring and cron-mail policy to work correctly.

        Install a User Crontab Entry #

        Edit the intended account’s crontab with crontab(1) . For root:

        doas crontab -e
        

        OpenBSD crontab(5) supports -s before the command to prevent overlapping instances. The following entry runs at 03:17 and mails output to the local admin alias:

        SHELL=/bin/sh
        PATH=/bin:/usr/bin:/sbin:/usr/sbin
        MAILTO=admin
        
        17 3 * * * -s /usr/local/libexec/check-filesystems
        

        Cron logs command execution. By default, command output is mailed to the crontab owner or MAILTO. Do not set an empty MAILTO merely to silence an unexplained failure. The OpenBSD-specific -n command flag mails output only when the command fails. Use it only after checking that the script returns a nonzero exit status on failure.

        List the installed entry without editing it:

        doas crontab -l
        

        System /etc/crontab entries contain an additional user field. User crontabs do not. Prefer crontab -e for a job owned by one account rather than mixing local jobs into the system file.

        Use the Daily, Weekly, and Monthly Framework #

        daily(8) documents the base maintenance scripts. Their output is mailed to root, so root mail must resolve to an account that is actually read.

        Do not edit /etc/daily, /etc/weekly, or /etc/monthly. Add site-specific work to:

        • /etc/daily.local;
        • /etc/weekly.local;
        • /etc/monthly.local.

        These local files run before the corresponding base script. They are suitable for short system-wide checks and documented variables such as ROOTBACKUP or CHECKFILESYSTEMS. A long-running application task is usually clearer in its own service-account crontab.

        For example, /etc/daily.local can enable the documented no-write filesystem check:

        CHECKFILESYSTEMS=1
        

        This runs fsck(8) with -n, which checks without writing repairs.

        Direct and Test Maintenance Mail #

        The periodic scripts and cron depend on local mail delivery. Map root and local operational aliases to a monitored account in /etc/mail/aliases, then rebuild the aliases with newaliases(8) .

        Send a deliberate test from the scheduled account and confirm receipt before relying on silent success. Also review /var/cron/log and local mail after the first scheduled run.

        Account for Systems That Sleep or Power Off #

        Cron does not automatically replay every job missed while a workstation was suspended or powered off. The daily(8) manual specifically warns that periodic scripts may never run on hosts that are not available at their scheduled times.

        For such a host, select a schedule during normal uptime, run a startup check that determines whether work is due, or move the task to an always-on management system. Any catch-up mechanism must record the last successful completion and remain safe when invoked more than once.

        Remove or Recover a Job #

        Disable a failing job by commenting out or removing only its crontab entry, then preserve its output and logs for diagnosis. Do not delete the script or its data before determining whether it was interrupted mid-change.

        After correction, rerun the script manually with the minimal environment, reinstall the crontab, and watch one scheduled execution. Remove obsolete scripts, credential files, lock state, and aliases only after confirming that no remaining job references them.

        Report a bug
        • Synopsis
        • Choose the Execution Account
        • Write a Non-Interactive Script
        • Test the Exact Account and Environment
        • Install a User Crontab Entry
        • Use the Daily, Weekly, and Monthly Framework
        • Direct and Test Maintenance Mail
        • Account for Systems That Sleep or Power Off
        • Remove or Recover a Job