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
        • Establish the Administrator Account
        • Inspect the Effective Server Configuration
        • Apply a Minimal Authentication Policy
        • Decide Whether Forwarding Is Required
        • Validate and Reload
        • Limit Network Exposure with PF
        • Verify Host Identity
        • Monitor Authentication
        • Recovery

        Configure Secure Remote Access with OpenSSH

        Synopsis #

        OpenBSD includes OpenSSH in the base system. Its defaults are maintained with the operating system and should not be replaced by copied cipher lists or generic hardening templates. A conservative remote-access setup uses a tested administrator account, public-key authentication, deliberate forwarding policy, Packet Filter exposure, configuration validation, and an independent recovery console.

        This guide changes authentication only after a key-based administrator session succeeds. Keep the original session and console access available until a second connection works under the final policy.

        For SSH-key-controlled access to a service behind a gateway, see Unlock an Internal Service with an SSH Key .

        Establish the Administrator Account #

        Complete Create an Administrator Account with doas and SSH Keys first. Verify the account from a separate client session:

        ssh -o IdentitiesOnly=yes -o PreferredAuthentications=publickey \
            -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no \
            -i ~/.ssh/id_ed25519 admin@server.example.com
          # Test the intended private key
        doas id
          # Confirm that the account can perform administrative work
        

        Do not continue if either command fails.

        Inspect the Effective Server Configuration #

        The server configuration is sshd_config(5) at /etc/ssh/sshd_config. Many defaults do not appear as active lines in that file. Inspect the effective settings with sshd(8) :

        doas sshd -T | grep -Ei '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|allowtcpforwarding|x11forwarding) '
        

        OpenBSD currently defaults PermitRootLogin to prohibit-password, PasswordAuthentication to yes, and KbdInteractiveAuthentication to yes. The final policy should reflect the host’s actual access requirements rather than assumptions about defaults.

        Apply a Minimal Authentication Policy #

        After key-based administration has been tested, set the following explicit policy to /etc/ssh/sshd_config:

        PermitRootLogin no
        PasswordAuthentication no
        KbdInteractiveAuthentication no
        PubkeyAuthentication yes
        

        Edit existing global values rather than appending duplicate directives: the first value obtained normally takes effect. Place these global directives before the first Match block, and review any included files and matching overrides. This policy disables all remote root login, password authentication, and keyboard-interactive authentication. It does not affect console login.

        Do not add algorithm lists merely to make the configuration look stricter. OpenSSH removes weak defaults and introduces new algorithms through supported system updates. A local list can preserve obsolete choices or prevent future improvements.

        Decide Whether Forwarding Is Required #

        SSH can forward agents, TCP connections, Unix-domain sockets, X11 connections, and tunnel devices. These features are useful administrative tools, but they should match the host’s role.

        For an account that needs only an interactive shell and file transfer, a Match block can restrict forwarding:

        Match User admin
            DisableForwarding yes
            PermitTunnel no
        

        Do not apply this restriction when the account requires port forwarding, agent forwarding, X11 forwarding, or tunnel creation. A Match block continues until another Match or the end of the file, so place global settings above it.

        Set PermitTunnel no to disable tunnel creation. Check the settings and test a new connection.

        Validate and Reload #

        Check the syntax and inspect the effective result before changing the running daemon:

        doas sshd -t
          # Reject syntax or key-file errors
        doas sshd -T -C user=admin,addr=198.51.100.25,host=client.example.com | \
            grep -Ei '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|disableforwarding|permittunnel) '
          # Confirm the administrator settings, including permittunnel no
        doas sshd -T -C user=root,addr=198.51.100.25,host=client.example.com | \
            grep -Ei '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication) '
          # Confirm that the global root-login policy was not placed inside a Match block
        doas rcctl reload sshd
          # Apply the validated configuration without ending established sessions
        

        Keep the existing session open. Start another connection with verbose client logging:

        ssh -v -o IdentitiesOnly=yes -o PreferredAuthentications=publickey \
            -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no \
            -i ~/.ssh/id_ed25519 admin@server.example.com
        

        Confirm login and doas again. Only then close the recovery session.

        Limit Network Exposure with PF #

        If the host uses a default-block pf.conf(5) policy, allow SSH on the intended interface and address. This example permits TCP port 22 on the address assigned to the egress interface group:

        pass in on egress proto tcp to (egress) port ssh
        

        Validate the complete ruleset with pfctl(8) before loading it:

        doas pfctl -nf /etc/pf.conf
          # Parse the file without changing the active ruleset
        doas pfctl -f /etc/pf.conf
          # Load the validated ruleset
        

        Restrict the source address when administration always comes from a stable management network. A changed SSH port may reduce log noise, but it is not an authentication control.

        Verify Host Identity #

        On first connection, verify the server host-key fingerprint through an independent channel. Display fingerprints on the server with ssh-keygen(1) :

        doas ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
        

        If a known-hosts warning appears after a legitimate server rebuild, verify the new fingerprint before removing the old entry.

        Monitor Authentication #

        Follow authentication events in /var/log/authlog:

        doas tail -f /var/log/authlog
        

        Use last(1) to review successful sessions:

        last
        

        Repeated failed attempts from the Internet are expected on a public SSH service. Strong authentication, supported software, limited accounts, and accurate logs matter more than reactive address lists built from short-lived scans.

        Recovery #

        If the new session fails, use the still-open session or console to:

        1. inspect /var/log/authlog;
        2. run sshd -t;
        3. inspect the account’s home, .ssh, and authorized_keys ownership and modes;
        4. compare sshd -T with the intended policy;
        5. revert the last configuration change and reload sshd.

        If every administrative credential is lost, use Recover Access and Reset the Root Password . Maintain at least one independent recovery credential. A FIDO-backed key can improve key protection but does not replace that recovery path.

        Report a bug
        • Synopsis
        • Establish the Administrator Account
        • Inspect the Effective Server Configuration
        • Apply a Minimal Authentication Policy
        • Decide Whether Forwarding Is Required
        • Validate and Reload
        • Limit Network Exposure with PF
        • Verify Host Identity
        • Monitor Authentication
        • Recovery