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
        • Design Considerations
        • Configuration
          • Baseline system settings (both sites)
          • PF allowances for IKEv2 and ESP (both sites)
          • Site-to-site IKEv2 with PSK
          • WireGuard Deployments
        • Verification
        • Troubleshooting
        • See Also

        VPN and Cryptographic Tunneling

        Synopsis #

        Build site-to-site virtual private networks (VPNs) and encrypted host-to-host tunnels with IKEv2 using the base system iked(8) and the kernel IPsec stack ipsec(4) , with NAT traversal, protected-traffic selectors, and diagnostic tools. A complete road-warrior deployment using the in-kernel wg(4) interface is maintained separately. Runtime management uses ikectl(8) , packet filtering is handled by pf.conf(5) and pfctl(8) , and link inspection uses tcpdump(8) . The interface for inspecting cleartext IPsec traffic is enc(4) .

        Use these patterns to interconnect sites over untrusted networks, to publish internal services across providers securely, or to replace legacy tunnels with modern cryptography.

        Design Considerations #

        • Selectors and scope. Define traffic by networks (for example, 10.0.0.0/24 to 10.20.0.0/24) rather than any. Keep selectors minimal and symmetric on both peers.
        • Authentication. Pre-shared key (PSK) is simplest for site-to-site. Certificates scale better and are preferred where third-party trust or revocation is needed.
        • NAT traversal. Permit UDP ports 500 and 4500 and protocol ESP on WAN. IKEv2 NAT-T is automatic when address translation is detected.
        • Routing. Enable only the address-family forwarding required by the protected networks, then add the corresponding static or dynamic routes.
        • Performance. Prefer AES-GCM proposals to offload integrity to the cipher. Keep MTU and MSS in mind where encapsulation crosses constrained links.
        • Operations. Ensure time sync on all peers (for example, with ntpd(8) ). Log IKE and PF events during rollout.

        Configuration #

        The examples assume:

        • Site A WAN: 198.51.100.10, LAN: 10.0.0.0/24
        • Site B WAN: 203.0.113.10, LAN: 10.20.0.0/24

        Adjust interface names and addresses to match the deployment.

        Baseline system settings (both sites) #

        doas sh <<'ROOT'
        printf '%s\n' 'net.inet.ip.forwarding=1' >> /etc/sysctl.conf
          # Persist IPv4 forwarding for the IPv4 protected networks
        sysctl net.inet.ip.forwarding=1
          # Apply IPv4 forwarding immediately
        ROOT
        

        The example carries IPv4 only. Do not enable IPv6 forwarding without an IPv6 routing and PF policy.

        PF allowances for IKEv2 and ESP (both sites) #

        Permit IKE (UDP 500/4500) and ESP on the WAN, and allow traffic between the protected subnets on the inside. Syntax is defined in pf.conf(5) .

        ## /etc/pf.conf - minimal allowances for IKEv2/IPsec
        
        set skip on lo
        
        wan     = "em0"           # adjust
        lan_net = "{ 10.0.0.0/24, 10.20.0.0/24 }"
        
        block all
        
        # IKE and IPsec on the WAN
        pass in on $wan proto udp to ($wan) port { 500, 4500 } keep state
        pass in on $wan proto esp keep state
        pass out on $wan proto udp from ($wan) to any port { 500, 4500 } keep state
        pass out on $wan proto esp from ($wan) keep state
        
        # Merge LAN ingress/egress allowances for the protected subnets into the main policy.
        # Tunnel-mode outer headers between the two example gateways
        pass on enc0 proto ipencap from 198.51.100.10 to 203.0.113.10 keep state (if-bound)
        pass on enc0 proto ipencap from 203.0.113.10 to 198.51.100.10 keep state (if-bound)
        
        # Permit protected subnets before encapsulation and after decryption
        pass on enc0 from 10.0.0.0/24 to 10.20.0.0/24 keep state (if-bound)
        pass on enc0 from 10.20.0.0/24 to 10.0.0.0/24 keep state (if-bound)
        

        Use the actual gateway addresses, including those seen on enc0 when NAT is involved. Keep every enc0 state bound to that interface so it cannot allow unencrypted WAN traffic after an IPsec SA expires. Allow the tunnel headers and protected inner packets separately. Limit outgoing WAN UDP to the gateway address and IKE/NAT-T ports.

        Reload and confirm with pfctl(8) .

        doas pfctl -f /etc/pf.conf
        doas pfctl -sr | egrep 'udp .* (500|4500)|proto esp|enc0'
        

        Site-to-site IKEv2 with PSK #

        Configuration is in iked.conf(5) . One side initiates (active), the other listens (passive). Proposals below use AES-GCM.

        Site A (initiator) #

        ## /etc/iked.conf - Site A
        
        ikev2 "s2s-a2b" active esp from 10.0.0.0/24 to 10.20.0.0/24 \
            peer 203.0.113.10 \
            ikesa enc aes-256-gcm prf hmac-sha2-256 group modp2048 \
            childsa enc aes-256-gcm \
            psk "change-this-shared-secret"
        

        Site B (responder) #

        Set peer to Site A’s WAN address. The from and to networks identify the traffic the tunnel protects.

        ## /etc/iked.conf - Site B
        
        ikev2 "s2s-b2a" passive esp from 10.20.0.0/24 to 10.0.0.0/24 \
            peer 198.51.100.10 \
            ikesa enc aes-256-gcm prf hmac-sha2-256 group modp2048 \
            childsa enc aes-256-gcm \
            psk "change-this-shared-secret"
        

        Enable and start iked(8) on both peers with rcctl(8) :

        doas chmod 600 /etc/iked.conf
        doas iked -n && doas rcctl enable iked
          # Start at boot
        doas rcctl start iked
          # Launch now (initiator will dial the responder)
        

        If either peer is behind NAT, IKEv2 will encapsulate ESP in UDP 4500 automatically (NAT-T). Ensure the upstream allows those ports.

        WireGuard Deployments #

        Configure a Road-Warrior WireGuard VPN covers keys, persistent interfaces, allowed IP ranges, routes, PF rules, and the return path. Use that guide for the complete client and gateway setup.

        Verification #

        • IKEv2 state and flows with ikectl(8) :
        doas ikectl show sa
          # IKE_SA and CHILD_SA state, SPIs, lifetimes
        doas ipsecctl -sf
          # Traffic selectors currently installed
        
        • Path testing:
        ping -n -c 3 10.20.0.1
          # Test the protected path from Site A to Site B
        
        • PF and routes:
        doas pfctl -vvsr | egrep 'udp .* (500|4500)|proto esp'
          # Confirm IKEv2 and ESP allowances
        netstat -rn | grep '10\.20\.0\.'
          # Confirm the protected-network route
        

        Troubleshooting #

        • No IKE negotiation. Verify UDP 500/4500 reachability and that the responder is in passive mode. Inspect logs in /var/log/daemon for iked.
        • Selector mismatch. If one side uses 10.0.0.0/24 to 10.20.0.0/24 and the other uses 10.0.0.0/24 to 10.0.0.0/24, CHILD_SA will not install. Align from/to networks. Check ipsecctl -sf.
        • NAT or path asymmetry. Ensure upstreams carry UDP 4500 unchanged and that return traffic follows the same egress. For IPsec, enc0 rules should allow the protected subnets.
        • MTU black holes. If large transfers stall, clamp MSS on the plaintext IPsec path during testing in PF (match on enc0 scrub (max-mss 1380)) and refine after measuring path MTU.
        • Clock skew. Certificates and IKE lifetimes are time-sensitive. Ensure NTP is working with ntpd(8) .

        See Also #

        • Networking
        • OpenBGPD
        • Related: Classic and Lightweight Tunnels
        • Related: Hardening and Operational Safety
        Report a bug
        • Synopsis
        • Design Considerations
        • Configuration
          • Baseline system settings (both sites)
          • PF allowances for IKEv2 and ESP (both sites)
          • Site-to-site IKEv2 with PSK
          • WireGuard Deployments
        • Verification
        • Troubleshooting
        • See Also