OpenBSD Handbook

    • Part I. Install & Configure
      • Introduction
      • Installing OpenBSD
      • The X Window System
      • Networking
      • System Configuration
      • OpenBSD Basics
      • Managing Software: Packages and Ports
    • Part II. Daily Operations
      • Graphical Environments
      • Multimedia
      • Printing
      • Linux Compatibility
      • Windows Compatibility
      • Games
    • Part III. System Administration
      • Security
      • Virtualization
      • Storage and File Systems
      • Updating and Upgrading
      • Localization
      • The OpenBSD Boot Process
    • Part IV. Networking & Daemons
      • Services
        • Database
          • MariaDB
          • PostgreSQL
          • Redis
          • memcached
        • Directory
          • YP (NIS)
          • LDAP
        • File
          • NFS
          • Samba
        • FTP Services
          • ftpd
          • ProFTPD
          • vsftpd
          • TFTP
        • Mail
          • Dovecot
          • smtpd
          • Postfix
          • Exim
          • Rspamd
        • Name
          • Named
          • Unbound
          • NSD
        • Networking
          • OpenBGPD
          • rtadvd
          • DHCP
          • slaacd
        • Web
          • Apache
          • nginx
          • httpd
          • relayd
        • Logging
          • syslogd
        • Monitoring
          • SNMP
        • Remote Access
          • Audit OpenSSH
          • sshd
        • File Synchronization
          • rsync
        • Messaging
          • RabbitMQ
        • Time
          • NTP
      • 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
      • Howto
        • Install Z shell (zsh)
        • Set Up WordPress
        • Build a Simple Router and Firewall
      • OpenBSD for Linux Users
      • OpenBSD for FreeBSD Users
      • OpenBSD for macOS Users
    • Package Search
      sshd
      • Synopsis
      • Service Management
      • Configuration Basics
      • Client Configuration
        • Generate an SSH Key Pair
        • Load Keys into ssh-agent (optional)
        • Install the Public Key on the Server
        • Per-Host Client Configuration
        • Interactive Login and Remote Command Execution
        • Secure Copy (scp)
        • SFTP File Transfers
        • Known Hosts and First-Use Validation
        • Common Options for Reliability and Performance
      • Hardening
        • Integrate Algorithm Policy with ssh-audit
        • Access Control
        • Authentication and Multi-Factor Options
        • Subsystem Isolation and Chrooted SFTP
      • Monitoring and Troubleshooting

      sshd

      Synopsis #

      sshd is the OpenSSH daemon that accepts incoming SSH connections and provides encrypted remote shell access and secure file transfer. On OpenBSD, sshd is part of the base system and is enabled by default after installation. Typical uses include secure administration, file transfer via sftp(1) and scp(1), remote command execution, and secure tunneling.

      For service control, use rcctl(8) . For configuration, edit sshd_config(5) . The daemon benefits from pledge(2) , unveil(2) , and network control with pf(4) .

      Service Management #

      Enable at boot and start immediately with rcctl(8) :

      # rcctl enable sshd
      # rcctl start sshd
      # rcctl status sshd
      

      Host keys are generated during installation. If any are missing, create them with ssh-keygen(1) :

      # ssh-keygen -A
      

      Configuration Basics #

      The daemon reads /etc/ssh/sshd_config. One directive is permitted per line, and lines beginning with # are comments. Validate changes with sshd(8) and restart via rcctl(8) .

      # sshd -t
      # rcctl restart sshd
      

      A concise baseline configuration:

      Port 22
      AddressFamily any
      ListenAddress 0.0.0.0
      ListenAddress ::
      
      PermitRootLogin no
      PasswordAuthentication no
      ChallengeResponseAuthentication no
      PubkeyAuthentication yes
      
      # Access control
      AllowUsers admin
      
      # Session hygiene
      ClientAliveInterval 300
      ClientAliveCountMax 2
      
      # Subsystem (enabled by default)
      Subsystem sftp /usr/libexec/sftp-server
      

      This configuration disables root login and password-based authentication, enables public key authentication, limits access to a specific account, and sets conservative keepalive parameters. Adjust ListenAddress as required.

      Client Configuration #

      The OpenBSD base system includes the client programs ssh(1) , sftp(1) , and scp(1) . This section covers key creation, key installation, and common client operations. Client-side configuration is read from ssh_config(5) .

      Generate an SSH Key Pair #

      Create an Ed25519 key pair with an identifying comment. Use ssh-keygen(1) . Protect the private key with a passphrase.

      $ ssh-keygen -t ed25519 -C "[admin@example.com](mailto:admin@example.com)" -f \~/.ssh/id\_ed25519
      

      For hardware-backed security keys (FIDO/U2F), generate an ed25519-sk key:

      $ ssh-keygen -t ed25519-sk -C "[admin@example.com](mailto:admin@example.com)" -f \~/.ssh/id\_ed25519\_sk
      

      Ensure appropriate permissions on the .ssh directory and files:

      $ chmod 700 \~/.ssh
      $ chmod 600 \~/.ssh/id\_\* \~/.ssh/id\_\*.pub
      

      Load Keys into ssh-agent (optional) #

      An agent can hold decrypted keys in memory. Start the agent and add the key with ssh-agent(1) and ssh-add(1) .

      $ eval "\$(ssh-agent -s)"
      $ ssh-add \~/.ssh/id\_ed25519
      

      Install the Public Key on the Server #

      If the ssh-copy-id helper is available on the client system, it can append the public key to the remote account’s ~/.ssh/authorized_keys. The utility is not part of OpenBSD base; when installed, usage is:

      $ ssh-copy-id [admin@host.example.com](mailto:admin@host.example.com)
      

      When ssh-copy-id is not available, append the public key over SSH using standard tools:

      $ ssh [admin@host.example.com](mailto:admin@host.example.com) 'mkdir -p \~/.ssh && chmod 700 \~/.ssh && touch \~/.ssh/authorized\_keys && chmod 600 \~/.ssh/authorized\_keys'
      $ cat \~/.ssh/id\_ed25519.pub | ssh [admin@host.example.com](mailto:admin@host.example.com) 'cat >> \~/.ssh/authorized\_keys'
      

      To verify the first connection and record the server host key, connect once and confirm the fingerprint. For non-interactive retrieval, ssh-keyscan(1) can populate ~/.ssh/known_hosts:

      $ ssh-keyscan -t ed25519 host.example.com >> \~/.ssh/known\_hosts
      

      Per-Host Client Configuration #

      Create a host stanza in ~/.ssh/config to define defaults for a target. See ssh_config(5) .

      Host prod
      HostName host.example.com
      User admin
      Port 22
      IdentityFile \~/.ssh/id\_ed25519
      IdentitiesOnly yes
      ForwardAgent no
      ForwardX11 no
      

      After saving the file, connect with a short alias:

      $ ssh prod
      

      Interactive Login and Remote Command Execution #

      Establish an interactive session or execute a single remote command with ssh(1) .

      $ ssh [admin@host.example.com](mailto:admin@host.example.com)
      $ ssh [admin@host.example.com](mailto:admin@host.example.com) 'uname -a'
      

      Secure Copy (scp) #

      Transfer files or directories. Use -r for recursive copies.

      $ scp ./report.txt [admin@host.example.com](mailto:admin@host.example.com):/home/admin/
      $ scp -r ./site/ [admin@host.example.com](mailto:admin@host.example.com):/var/www/
      $ scp [admin@host.example.com](mailto:admin@host.example.com):/var/log/daemon /tmp/daemon.log
      

      SFTP File Transfers #

      Open an interactive SFTP session or perform one-off transfers with sftp(1) .

      $ sftp [admin@host.example.com](mailto:admin@host.example.com)
      sftp> pwd
      sftp> lpwd
      sftp> put ./archive.tar.gz /home/admin/
      sftp> get /etc/daily /tmp/daily
      sftp> mkdir /home/admin/uploads
      sftp> ls -l /home/admin
      sftp> exit
      

      Non-interactive SFTP can transfer files directly:

      $ sftp [admin@host.example.com](mailto:admin@host.example.com):/etc/daily /tmp/daily
      $ sftp /var/log/messages [admin@host.example.com](mailto:admin@host.example.com):/home/admin/
      

      Known Hosts and First-Use Validation #

      On first connection, ssh(1) will prompt to trust the server host key and append it to ~/.ssh/known_hosts. To pre-validate, compare the presented fingerprint with one generated on the server:

      
      # On the server (run as root to read host keys):
      
      # ssh-keygen -l -f /etc/ssh/ssh\_host\_ed25519\_key.pub
      

      Common Options for Reliability and Performance #

      Control connection reuse and timeouts in ~/.ssh/config:

      Host \*
      ServerAliveInterval 60
      ServerAliveCountMax 2
      ControlMaster auto
      ControlPersist 5m
      ControlPath \~/.ssh/cm-%r@%h:%p
      

      ControlMaster enables multiplexing over a single TCP connection; subsequent sessions to the same host start faster and avoid repeated authentication.

      Hardening #

      Integrate Algorithm Policy with ssh-audit #

      Inventory and assess offered algorithms with ssh-audit. See the companion chapter: /ssh-audit . Based on audit findings, restrict key exchange (KEX), host-key, and MAC algorithms in sshd_config(5) .

      A conservative, broadly compatible policy:

      # Key exchange
      KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,\
      diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,\
      diffie-hellman-group-exchange-sha256
      
      # MACs (encrypt-then-MAC variants)
      MACs umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,\
      hmac-sha2-512-etm@openssh.com
      
      # Host key algorithms (server authentication)
      HostKeyAlgorithms ssh-ed25519,rsa-sha2-256,rsa-sha2-512
      

      When reducing HostKeyAlgorithms, ensure HostKey file directives reference only retained types (for example, omit ssh_host_ecdsa_key if ECDSA is disabled). Validate and reload:

      # sshd -t
      # rcctl restart sshd
      

      To curate Diffie–Hellman group-exchange parameters, filter /etc/ssh/moduli to entries of at least 3071 bits; see moduli(5) .

      # awk '$5 >= 3071' /etc/ssh/moduli > /etc/ssh/moduli.safe
      # mv -f /etc/ssh/moduli.safe /etc/ssh/moduli
      # rcctl restart sshd
      

      Re-run ssh-audit after each change and review for unintended regressions.

      Access Control #

      Restrict exposure and narrow the authenticated population.

      # Bind to explicit addresses and non-standard port if required
      Port 22
      ListenAddress 192.0.2.10
      # ListenAddress 2001:db8::10
      
      # Permit only specific users or groups
      AllowUsers admin opsuser
      # or:
      # AllowGroups wheel ops
      

      With pf(4) , limit ingress to trusted sources. See the PF chapters and the pfctl cheat sheet at /pf/cheat_sheet/ .

      # Example PF fragment (context-dependent)
      block in on egress proto tcp to port ssh
      pass  in on egress proto tcp from 198.51.100.0/24 to port ssh
      

      Reload with pfctl(8) :

      # pfctl -f /etc/pf.conf
      

      Authentication and Multi-Factor Options #

      OpenSSH supports several approaches to multi-factor authentication without external PAM modules.

      1. Public key + password (two independent factors). Require both a private key and a password using sshd_config(5) AuthenticationMethods.

        PubkeyAuthentication yes
        PasswordAuthentication yes
        AuthenticationMethods publickey,password
        

        This setting denies access unless both factors succeed.

      2. Security keys (FIDO/U2F). Security-key-backed keys (for example, sk-ssh-ed25519@openssh.com) provide possession-plus-touch verification. Generate on the client with ssh-keygen(1) :

        $ ssh-keygen -t ed25519-sk -f ~/.ssh/id_ed25519_sk
        

        Ensure that server policy allows the corresponding public key algorithm (do not exclude sk-ssh-ed25519@openssh.com if PubkeyAcceptedAlgorithms is restricted) and that public key authentication remains enabled.

      3. Keyboard-interactive second factors via BSD Authentication. OpenBSD uses bsd_auth(3) rather than PAM. Additional BSD Auth backends can supply one-time codes (for example, TOTP) via keyboard-interactive. After installing and configuring an appropriate backend, require a second factor with:

        KbdInteractiveAuthentication yes
        AuthenticationMethods publickey,keyboard-interactive
        

        Backend selection and provisioning are backend-specific and outside the scope of this chapter.

      Additional hardening measures:

      # Reduce brute-force surface
      MaxAuthTries 3
      LoginGraceTime 30
      MaxStartups 10:30:100
      
      # Disable features not required
      PermitTunnel no
      AllowAgentForwarding no
      AllowTcpForwarding no
      X11Forwarding no
      GatewayPorts no
      PrintMotd no
      UseDNS no
      

      Subsystem Isolation and Chrooted SFTP #

      Constrain SFTP-only accounts with a chroot and the internal SFTP subsystem:

      Match User sftpjailed
          ChrootDirectory /home/sftpjailed
          ForceCommand internal-sftp
          AllowTcpForwarding no
          X11Forwarding no
      

      The chroot directory must be owned by root and must not be writable by the target account; see details in sshd_config(5) .

      Monitoring and Troubleshooting #

      Check service status and listen sockets:

      # rcctl check sshd
      # sockstat -4 -6 | grep sshd
      

      Inspect authentication logs (facility auth):

      # tail -f /var/log/authlog
      

      Common issues include syntax errors (sshd -t), incorrect permissions on ~/.ssh or authorized_keys, missing public keys, or firewall policy blocking the port.

      Fix user key permissions:

      $ chmod 700 ~/.ssh
      $ chmod 600 ~/.ssh/authorized_keys
      $ chown "$USER":"$USER" ~/.ssh ~/.ssh/authorized_keys
      
      Report a bug
      • Synopsis
      • Service Management
      • Configuration Basics
      • Client Configuration
        • Generate an SSH Key Pair
        • Load Keys into ssh-agent (optional)
        • Install the Public Key on the Server
        • Per-Host Client Configuration
        • Interactive Login and Remote Command Execution
        • Secure Copy (scp)
        • SFTP File Transfers
        • Known Hosts and First-Use Validation
        • Common Options for Reliability and Performance
      • Hardening
        • Integrate Algorithm Policy with ssh-audit
        • Access Control
        • Authentication and Multi-Factor Options
        • Subsystem Isolation and Chrooted SFTP
      • Monitoring and Troubleshooting