Start OpenSSH from the FreeBSD installer
2026-11-02 - It takes more than one command
Tag: FreeBSD
Introduction
This article explains how to start an OpenSSH server from the FreeBSD installer. It is usually quite easy to do on Linux, but on FreeBSD it requires a few commands that I want to document here. My use case is a web KVM or virtual machine VNC or SPICE interface that restrict copy/paste operations during rescue or install operations.
Procedure
First, boot the installation media normally then select “Shell” on the first menu screen. Then set up the network however is appropriate in your situation, for example:
dhclient vtnet0
Set up OpenSSH:
mkdir -p /tmp/sshd/etc/ssh
ssh-keygen -A -f /tmp/sshd
fetch -o /tmp/sshd/authorized_keys https://git.adyxax.org/adyxax.keys
cat > /tmp/sshd/sshd_config <<'EOF'
Port 22
HostKey /tmp/sshd/etc/ssh/ssh_host_ed25519_key
HostKey /tmp/sshd/etc/ssh/ssh_host_rsa_key
PermitRootLogin without-password
PasswordAuthentication no
AuthorizedKeysFile /tmp/sshd/authorized_keys
PidFile /tmp/sshd/sshd.pid
StrictModes no
EOF
/usr/sbin/sshd -f /tmp/sshd/sshd_config
Then SSH in with (updating the port and hostname to your circumstances):
ssh -o UserKnownHostsFile=/dev/null -p10022 root@localhost
I like to ignore these one time use host keys in rescue/install situations.
How it works
The main thing we need to work around is that the installation media is mounted read-only, and is missing a working minimal configuration. When using a Linux installation media, you can usually just start sshd and it works with a default environment and default SSH host keys, but not on FreeBSD.
The snippet above creates a temporary environment for OpenSSH under /tmp by creating SSH host keys, fetching my SSH public key from my Forgejo instance (you could do the same from GitHub), then writing a minimal configuration.
In this configuration, one surprising thing might be the StrictModes no
option: it is necessary because we are under /tmp which is world writable.
PermitRootLogin is necessary because root is the only account, and we cannot
set a password on a read-only /. Also a PidFile is needed because the
default /var/run is read-only too.
Finally, sshd refuses to start without specifying its full path.
Optional: how to paste such a snippet efficiently
As mentioned in the introduction, my use case is a web KVM or virtual machine VNC or SPICE interface that restrict copy/paste operations during rescue or install operations. This makes typing that many lines of commands and configuration quite inconvenient!
My usual solution to this is xdotool, but it can be unreliable when paired
with a web KVM. These usually eat newline characters and you need to throttle
the input a bit for it to work properly. I use the following xdotype wrapper
script:
#!/bin/sh
# usage: xdotype FILE (or: cmd | xdotype -)
# You have 2 seconds to focus the window you want to target
set -eu
sleep 2
while IFS= read -r line || [ -n "$line" ]; do
[ -n "$line" ] && xdotool type --clearmodifiers --delay 60 -- "$line"
xdotool key --clearmodifiers Return
sleep 0.3
done < "${1:-/dev/stdin}"
Conclusion
Starting OpenSSH from the FreeBSD installation media only takes a little work, but I am glad I finally took the time to document these steps for future me.