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
        • Preparation: Name Resolution in the httpd Chroot
        • Install Required Packages
        • Configure PHP and PHP-FPM
        • Configure httpd
        • Initialize MariaDB
        • Download and Install WordPress
        • Create the WordPress Database and User
        • Configure WordPress
        • Complete the Installation
        • References

        Set Up WordPress on OpenBSD

        Synopsis #

        Deploy WordPress on OpenBSD with the base web server httpd(8) , PHP-FPM from packages, and MariaDB from packages. OpenBSD runs the web server in a chroot(2) at /var/www, so name resolution and interprocess communication must work from within that environment.

        Privileged commands use doas; configure administrative access first.

        Preparation: Name Resolution in the httpd Chroot #

        Ensure that processes running inside /var/www can resolve hostnames. Create the chroot’s /etc and provide resolver configuration per resolv.conf(5) . Optionally create /etc/hosts entries per hosts(5) .

        doas sh <<'ROOT'
        install -d -o root -g wheel -m 0755 /var/www/etc
        cp -p /etc/resolv.conf /var/www/etc/resolv.conf
        install -d -o root -g wheel -m 0755 /var/www/etc/ssl
        cp -p /etc/ssl/cert.pem /var/www/etc/ssl/cert.pem
        printf '127.0.0.1\tlocalhost\n' > /var/www/etc/hosts
        ROOT
        

        The resolver file enables DNS and the CA bundle enables HTTPS certificate verification from the PHP chroot. Refresh these copies when the host resolver configuration or trust bundle changes.

        Install Required Packages #

        Install PHP 8.3, the default PHP branch in OpenBSD 8.0, with matching extensions, MariaDB server and client tools, and basic utilities. Selecting the same PHP branch for every extension avoids mixing incompatible modules.

        doas pkg_add php%8.3 php-curl%8.3 php-mysqli%8.3 \
            php-zip%8.3 php-gd%8.3 php-intl%8.3 \
            mariadb-server mariadb-client unzip
        

        Configure PHP and PHP-FPM #

        The package installs /etc/php-8.3.ini. Enable the installed extension configurations with symbolic links:

        doas sh <<'ROOT'
        cd /etc/php-8.3.sample
        for module in curl mysqli zip gd intl; do
            ln -sf ../php-8.3.sample/$module.ini ../php-8.3/
        done
        ROOT
        

        PHP-FPM reads /etc/php-fpm.conf, which already defines a www pool and includes /etc/php-fpm.d/*.conf. Edit the existing pool rather than adding a second [www] definition. Confirm these settings in /etc/php-fpm.conf, retaining its other process-management settings:

        doas vi /etc/php-fpm.conf
        
        [www]
        user = www
        group = www
        
        listen = /var/www/run/php-fpm.sock
        listen.owner = www
        listen.group = www
        listen.mode  = 0660
        
        chroot = /var/www
        

        Check the configuration, then enable and start the PHP-FPM daemon:

        doas php-fpm-8.3 -t
        doas rcctl enable php83_fpm
        doas rcctl start php83_fpm
        
          # Verify the service is enabled
        doas rcctl ls on | grep php
        
          # Verify the service is running
        doas rcctl check php83_fpm
        

        See rcctl(8) for service management.

        Configure httpd #

        Create /etc/httpd.conf with a single server stanza. The FastCGI socket path is relative to the chroot; PHP-FPM listens at /var/www/run/php-fpm.sock, which appears as /run/php-fpm.sock to httpd(8) . Refer to httpd.conf(5) for directive details.

        doas vi /etc/httpd.conf
        
        types { include "/usr/share/misc/mime.types" }
        
        server "default" {
            listen on egress port 80
            root "/wordpress"
            directory index index.php
        
            location "*.php" {
                fastcgi socket "/run/php-fpm.sock"
            }
        }
        

        Start and enable the web server:

        doas rcctl enable httpd
        doas rcctl start httpd
        
          # Verify the service is enabled
        doas rcctl ls on | grep httpd
        
          # Verify the service is running
        doas rcctl check httpd
        

        For a public site, configure HTTPS with a trusted certificate before completing setup or logging into administration. Follow the httpd TLS instructions and keep the WordPress document root and FastCGI location. Use plain HTTP only for isolated local testing.

        Initialize MariaDB #

        Initialize the database, start the server, and run the secure setup program. These tools are provided by the MariaDB packages.

        doas mariadb-install-db
        doas mkdir -p /var/run/mysql
        doas chown _mysql:_mysql /var/run/mysql/
        doas rcctl enable mysqld
        doas rcctl start mysqld
        doas mariadb-secure-installation
        

        See MariaDB for additional configuration and diagnostics.

        Download and Install WordPress #

        Fetch the latest WordPress release, extract it, and place it under the httpd document root inside the chroot.

        cd /tmp
        ftp https://wordpress.org/latest.zip
        doas unzip latest.zip
        doas mv wordpress /var/www/
        

        For improved security, keep WordPress core files read-only to the web server. A safe default is ownership by root:wheel, with write access granted only to directories that must be writable at runtime (typically wp-content/uploads; optionally plugin-specific cache/upgrade paths).

        doas find /var/www/wordpress ! -name wp-config.php -exec chown -h root:wheel {} \;
        doas find /var/www/wordpress -type d -exec chmod 755 {} \;
        doas find /var/www/wordpress -type f ! -name wp-config.php -exec chmod 644 {} \;
        
        # Runtime-writable content (minimum required)
        doas install -d -o www -g www -m 0755 /var/www/wordpress/wp-content/uploads
        
        # Optional: only if a plugin/theme requires write access
        doas install -d -o www -g www -m 0755 /var/www/wordpress/wp-content/cache
        doas install -d -o www -g www -m 0755 /var/www/wordpress/wp-content/upgrade
        

        Avoid making the entire document root writable by www. When updates are performed through the admin UI, temporarily relax permissions only for required paths, then restore read-only ownership.

        (ftp(1) is available in the OpenBSD base system. See ftp(1) .)

        Create the WordPress Database and User #

        Connect to MariaDB and create a database and a dedicated user account with privileges limited to that database. Replace StrongPassword with a strong, unique database password.

        doas mysql -u root -p
        
        CREATE DATABASE wordpress;
        CREATE USER 'wordpress'@'127.0.0.1' IDENTIFIED BY 'StrongPassword';
        GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'127.0.0.1';
        FLUSH PRIVILEGES;
        EXIT;
        

        Using 127.0.0.1 ensures TCP is used, which avoids reliance on the server’s UNIX socket from within the httpd chroot.

        Configure WordPress #

        Copy the sample configuration and edit the database parameters. Use the loopback address 127.0.0.1 for the database host to avoid socket path issues across the chroot boundary.

        doas install -o root -g www -m 0640 /var/www/wordpress/wp-config-sample.php /var/www/wordpress/wp-config.php
        doas vi /var/www/wordpress/wp-config.php
        
        /** WordPress database name */
        define('DB_NAME', 'wordpress');
        
        /** Database username */
        define('DB_USER', 'wordpress');
        
        /** Database password */
        define('DB_PASSWORD', 'StrongPassword');
        
        /** Database hostname (use TCP) */
        define('DB_HOST', '127.0.0.1');
        

        wp-config.php contains the database password. Keep its owner as root:www and mode as 0640 so PHP-FPM can read it without making it world-readable. Keep these settings when changing core-file permissions. See the WordPress configuration-file security guidance .

        Complete the Installation #

        Open the site’s HTTPS address in a browser. Follow the setup wizard to create the administrator account and enter the site details.

        If permissions prevent writes, confirm that the document root is /var/www/wordpress, that uploads are writable by www, and that PHP-FPM is running and reachable at /run/php-fpm.sock from the chroot.

        References #

        Consult the Handbook-hosted manual pages for base utilities and configuration files discussed in this chapter:

        • httpd(8)
        • httpd.conf(5)
        • rcctl(8)
        • ftp(1)
        • resolv.conf(5)
        • hosts(5)
        Report a bug
        • Synopsis
        • Preparation: Name Resolution in the httpd Chroot
        • Install Required Packages
        • Configure PHP and PHP-FPM
        • Configure httpd
        • Initialize MariaDB
        • Download and Install WordPress
        • Create the WordPress Database and User
        • Configure WordPress
        • Complete the Installation
        • References