FreeBSD.software
Home/Guides/OpenSSH on FreeBSD: Secure Shell Review
review·2026-04-09·11 min read

OpenSSH on FreeBSD: Secure Shell Review

In-depth review of OpenSSH on FreeBSD: base system integration, configuration hardening, certificates, jump hosts, agent forwarding, FIDO2 keys, and security best practices.

OpenSSH on FreeBSD: Secure Shell Review

OpenSSH is the most important piece of security software on any FreeBSD system. It is the primary remote access method for servers, the transport layer for file transfers, the tunneling mechanism for port forwarding, and the authentication framework for automated deployments. Unlike most software reviewed on this site, OpenSSH is not a package you install -- it ships in FreeBSD's base system, maintained alongside the kernel and userland as a core component. This means it is updated through freebsd-update, not pkg, and its integration with the operating system is deeper than any third-party package. This review covers OpenSSH's capabilities on FreeBSD, configuration hardening, certificate-based authentication, jump hosts, agent forwarding, FIDO2 hardware key support, and security best practices for production deployments.

What OpenSSH Does

OpenSSH provides encrypted remote access and secure file transfer over untrusted networks. It replaced the plaintext protocols (telnet, rsh, rcp, ftp) that were standard on Unix systems before the late 1990s.

Core capabilities:

  • Remote shell access -- ssh user@host opens an encrypted terminal session on the remote system.
  • File transfer -- scp and sftp transfer files over the SSH protocol. rsync uses SSH as its transport.
  • Port forwarding -- tunnel TCP connections through the SSH connection, both local-to-remote and remote-to-local.
  • Dynamic proxying -- SOCKS proxy via ssh -D, routing arbitrary traffic through the SSH tunnel.
  • Key-based authentication -- public key cryptography replaces passwords. Private keys never leave the client.
  • Certificate authentication -- SSH certificates signed by a CA, enabling centralized trust without distributing individual public keys.
  • Agent forwarding -- use local SSH keys on remote servers without copying private keys.
  • Jump hosts -- transparently proxy through intermediate servers to reach hosts on private networks.
  • FIDO2/U2F -- hardware security key authentication with FIDO2-compatible devices (YubiKey, SoloKey).
  • Multiplexing -- share a single TCP connection across multiple SSH sessions for reduced latency.

OpenSSH is developed by the OpenBSD project and ported to other operating systems as "Portable OpenSSH." FreeBSD tracks Portable OpenSSH closely and integrates it into the base system.

OpenSSH in the FreeBSD Base System

OpenSSH is part of FreeBSD's base system, not a package. This has important implications:

  • Updates come through freebsd-update, not pkg upgrade. When a critical OpenSSH vulnerability is announced, the fix arrives via a FreeBSD security advisory and base system update.
  • Configuration lives at /etc/ssh/, not /usr/local/etc/ssh/.
  • The binary is at /usr/bin/ssh (client) and /usr/sbin/sshd (server), not under /usr/local/.
  • The rc.d script is at /etc/rc.d/sshd, managed with service sshd start/stop/restart.

Check the installed version:

sh
ssh -V

As of FreeBSD 14.2, the base system ships OpenSSH 9.x. FreeBSD updates OpenSSH regularly, typically within weeks of upstream releases for security fixes.

Enabling sshd

The SSH server is enabled during FreeBSD installation if you select it. To enable it manually:

sh
sysrc sshd_enable="YES" service sshd start

Configuration Hardening

The default OpenSSH configuration on FreeBSD is reasonable but not hardened for production. The server configuration file is /etc/ssh/sshd_config.

Hardened sshd_config

sh
# /etc/ssh/sshd_config - Production hardened configuration # Protocol and listening Port 22 AddressFamily inet ListenAddress 0.0.0.0 # Authentication PermitRootLogin prohibit-password PasswordAuthentication no ChallengeResponseAuthentication no KbdInteractiveAuthentication no PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys # Disable unused authentication methods KerberosAuthentication no GSSAPIAuthentication no HostbasedAuthentication no PermitEmptyPasswords no # Key exchange, ciphers, and MACs (restrict to modern algorithms) KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com # Host keys (prefer Ed25519) HostKey /etc/ssh/ssh_host_ed25519_key HostKey /etc/ssh/ssh_host_rsa_key # Session settings MaxAuthTries 3 MaxSessions 5 LoginGraceTime 30 ClientAliveInterval 300 ClientAliveCountMax 2 # Restrict access AllowUsers admin deploy DenyUsers root # Logging LogLevel VERBOSE SyslogFacility AUTH # Miscellaneous X11Forwarding no PrintMotd no AcceptEnv LANG LC_* Subsystem sftp /usr/libexec/sftp-server -f AUTH -l INFO

Apply the configuration:

sh
sshd -t service sshd reload

Always run sshd -t to test the configuration before reloading. A syntax error will prevent sshd from restarting, locking you out of the server.

Key Hardening Decisions Explained

PasswordAuthentication no -- the single most impactful hardening step. Passwords can be brute-forced. SSH keys cannot be (with adequate key length). Disable password authentication on every production server.

PermitRootLogin prohibit-password -- allows root login via SSH keys but not passwords. For maximum security, set to no and use sudo or doas from a regular user account.

Cipher and KEX restrictions -- removes older algorithms (3DES, CBC modes, SHA1-based MACs) that have known weaknesses. The listed algorithms are all modern, fast, and secure.

LogLevel VERBOSE -- logs key fingerprints and authentication details, useful for auditing who accessed the server and with which key.

Key Management

Generating Keys

Generate an Ed25519 key (recommended):

sh
ssh-keygen -t ed25519 -C "user@hostname"

Generate an RSA key (for compatibility with older systems):

sh
ssh-keygen -t rsa -b 4096 -C "user@hostname"

Ed25519 keys are shorter, faster, and cryptographically stronger than RSA keys of equivalent security level. Use Ed25519 unless you need RSA compatibility.

Deploying Keys

Copy a public key to a remote server:

sh
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@remote-server

Or manually append to the remote server's ~/.ssh/authorized_keys.

Key Restrictions

Restrict what a key can do in ~/.ssh/authorized_keys:

sh
command="/usr/local/bin/backup-script",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAA... backup-key

This key can only run the backup script. No interactive shell, no port forwarding. Essential for automated backup, deployment, and monitoring keys.

Certificate-Based Authentication

SSH certificates solve the key distribution problem. Instead of copying public keys to every server, you sign keys with a Certificate Authority (CA). Servers trust the CA, and any key signed by the CA is accepted.

Create an SSH CA

sh
ssh-keygen -t ed25519 -f /etc/ssh/ca_key -C "SSH CA"

Sign a User Key

sh
ssh-keygen -s /etc/ssh/ca_key -I user@example.com -n admin,deploy -V +52w ~/.ssh/id_ed25519.pub

This creates a certificate (~/.ssh/id_ed25519-cert.pub) valid for 52 weeks, authorizing the user to log in as admin or deploy.

Configure Servers to Trust the CA

Add to /etc/ssh/sshd_config:

sh
TrustedUserCAKeys /etc/ssh/ca_key.pub

Copy the CA public key to /etc/ssh/ca_key.pub on every server. Now any user with a certificate signed by this CA can log in without having their individual public key in authorized_keys.

Sign Host Keys

Sign the server's host key so clients can verify the server's identity without TOFU (Trust On First Use):

sh
ssh-keygen -s /etc/ssh/ca_key -I mail.example.com -h -V +52w /etc/ssh/ssh_host_ed25519_key.pub

Add to /etc/ssh/sshd_config:

sh
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub

On the client, add the CA to ~/.ssh/known_hosts:

sh
@cert-authority *.example.com ssh-ed25519 AAAA...ca_public_key...

No more "The authenticity of host cannot be established" warnings. The client verifies the host certificate against the CA.

Certificate Advantages

  • No authorized_keys management -- add or revoke access by signing or revoking certificates. No file distribution.
  • Expiration -- certificates expire automatically. Forgotten keys do not linger forever.
  • Principal-based access -- certificates specify which usernames the holder can use, providing fine-grained access control.
  • Host verification -- eliminates TOFU for host key verification, preventing man-in-the-middle attacks on first connection.

Jump Hosts (ProxyJump)

Access servers on private networks through an intermediate bastion host:

sh
ssh -J bastion.example.com internal-server

Configure in ~/.ssh/config:

sh
Host internal-* ProxyJump bastion.example.com User admin Host bastion.example.com User jump IdentityFile ~/.ssh/id_ed25519

Now ssh internal-db transparently connects through the bastion. The bastion never sees the traffic to the internal server -- it only forwards TCP bytes.

Multi-Hop

Chain multiple jump hosts:

sh
ssh -J bastion1,bastion2 target-server

Agent Forwarding

SSH agent forwarding allows you to use your local SSH keys on a remote server without copying them:

sh
ssh -A bastion.example.com

On the bastion, you can now ssh internal-server using keys from your local machine.

Security warning: agent forwarding exposes your local SSH agent to the remote server. A compromised remote server could use your agent to authenticate to other servers. Use ProxyJump instead of agent forwarding when possible, as it does not expose the agent.

For cases where agent forwarding is necessary, restrict which keys the agent forwards:

sh
ssh-add -c ~/.ssh/id_ed25519

The -c flag requires confirmation on each use of the key through the agent.

FIDO2 Hardware Key Support

OpenSSH 8.2+ supports FIDO2/U2F hardware security keys (YubiKey 5, SoloKey, Google Titan). This provides the strongest authentication -- the private key material never leaves the hardware device.

Generate a FIDO2 Key

Insert your hardware key and run:

sh
ssh-keygen -t ed25519-sk -C "user@hostname-yubikey"

For a resident key (stored on the hardware key, usable without the key file):

sh
ssh-keygen -t ed25519-sk -O resident -C "user@hostname-yubikey"

Using FIDO2 Keys

FIDO2 keys work like regular SSH keys but require physical interaction (touch) with the hardware key for each authentication:

sh
ssh -i ~/.ssh/id_ed25519_sk user@server

The user touches the hardware key when prompted. If the key is not plugged in, authentication fails. This provides two-factor authentication (something you have + physical presence) without additional software.

FreeBSD Client Requirements

Ensure the security/libfido2 library is available:

sh
pkg install libfido2

FreeBSD's base OpenSSH is compiled with FIDO2 support. Verify:

sh
ssh -Q key | grep sk

If sk-ssh-ed25519@openssh.com appears, FIDO2 is supported.

Connection Multiplexing

Reuse a single SSH connection for multiple sessions, reducing TCP handshake and key exchange overhead:

sh
# ~/.ssh/config Host * ControlMaster auto ControlPath ~/.ssh/sockets/%r@%h-%p ControlPersist 600

Create the sockets directory:

sh
mkdir -p ~/.ssh/sockets chmod 700 ~/.ssh/sockets

The first SSH connection to a host opens a master connection. Subsequent connections to the same host reuse the master, connecting instantly without re-authenticating. ControlPersist 600 keeps the master alive for 10 minutes after the last session closes.

SSH Tunneling on FreeBSD

Local Port Forwarding

Access a remote service through a local port:

sh
ssh -L 5432:localhost:5432 db-server

Now psql -h localhost connects to the PostgreSQL instance on db-server through the encrypted tunnel.

Remote Port Forwarding

Expose a local service to the remote network:

sh
ssh -R 8080:localhost:3000 remote-server

Users on remote-server can access your local development server at localhost:8080.

SOCKS Proxy

Route browser traffic through a remote server:

sh
ssh -D 1080 proxy-server

Configure your browser to use localhost:1080 as a SOCKS5 proxy. All browser traffic is encrypted and exits through proxy-server.

Security Best Practices Summary

  1. Disable password authentication. Use keys only.
  2. Use Ed25519 keys. Shorter, faster, stronger than RSA.
  3. Deploy SSH certificates for environments with more than 10 servers.
  4. Restrict ciphers and KEX algorithms to modern algorithms only.
  5. Use FIDO2 hardware keys for administrative access to critical infrastructure.
  6. Prefer ProxyJump over agent forwarding to avoid exposing your SSH agent.
  7. Set AllowUsers or AllowGroups to restrict which accounts can log in via SSH.
  8. Log at VERBOSE level for audit trails.
  9. Monitor /var/log/auth.log for brute force attempts and unauthorized access.
  10. Keep FreeBSD updated -- freebsd-update fetch install includes OpenSSH security patches.

Verdict

OpenSSH is not optional on FreeBSD -- it is the foundation of remote system administration. Its integration as a base system component means it receives the same maintenance priority as the kernel. The certificate infrastructure, FIDO2 support, jump host capabilities, and connection multiplexing make it far more than a simple remote shell tool.

The most important action for any FreeBSD sysadmin is hardening the default configuration: disable password authentication, restrict algorithms, limit user access, and deploy key-based or certificate-based authentication. These steps, which take minutes to implement, eliminate the vast majority of SSH-based attacks.


Frequently Asked Questions

Should I change the SSH port from 22?

Changing the port reduces automated scanning noise in logs but is not a security measure. Determined attackers scan all ports. Focus on disabling password authentication and using strong keys instead of relying on port obscurity.

How do I revoke an SSH certificate?

Create a Key Revocation List (KRL): ssh-keygen -k -f /etc/ssh/revoked_keys -s /etc/ssh/ca_key /path/to/revoked_cert.pub. Add RevokedKeys /etc/ssh/revoked_keys to sshd_config. The revoked certificate is immediately rejected.

Can I use OpenSSH from ports instead of the base system?

Yes, security/openssh-portable is available in ports. However, running a different OpenSSH version than the base system adds complexity. The base system version is recommended unless you need a feature not yet imported.

How do I audit who logged in and when?

Set LogLevel VERBOSE in sshd_config. This logs the key fingerprint used for each authentication. Cross-reference fingerprints with known keys to identify which user (or automation) accessed the system. Logs are in /var/log/auth.log.

Does OpenSSH support two-factor authentication on FreeBSD?

Yes, through multiple methods: FIDO2 hardware keys (built-in), Google Authenticator PAM module (security/pam_google_authenticator), or Duo Security (security/duo). FIDO2 is the strongest option and requires no additional software on the server.

How do I transfer files securely?

Use scp for simple transfers: scp file.txt user@server:/path/. Use sftp for interactive sessions. Use rsync -e ssh for incremental transfers and directory synchronization. All use the SSH transport for encryption.

Get more FreeBSD guides

Weekly tutorials, security advisories, and package updates. No spam.