Controlplane SSH Bootstrap

Practical runbook for making the controlplane jail reachable by SSH and usable as an operator node • 09.03.2026

Scope: This page documents the exact order that worked on the host: inspect first, install only what is missing, create the operator user explicitly with bash, enable base sshd, fix group membership, verify sudo, then disable password dependence.
Important: Real host key fingerprints and generated public keys are intentionally redacted here. Use controlplane as the neutral hostname label. A fully qualified domain is optional for this jail and should not be treated as a bootstrap requirement.

Why This Exists

The earlier bootstrap notes assumed too much. We assumed the clawdie user already existed inside the jail, assumed packages were already present, and assumed a domain-style hostname like ai.clawdie.si was necessary. In practice, none of those should be assumptions.

ItemFinal decision
Jail namecontrolplane
Canonical hostnamecontrolplane
IP10.0.0.100
SSH daemonUse base FreeBSD sshd first
Operator userclawdie in wheel and operator
Sudo model/usr/local/etc/sudoers.d/wheel-nopasswd

Correct Order of Operations

  1. Read the current state before writing anything.
  2. Update packages and install missing operator tools.
  3. Create the operator user if it is missing.
  4. Fix supplementary groups before touching sudo.
  5. Inspect the sudo include model, then add the drop-in.
  6. Enable base sshd and verify it is listening.
  7. Bootstrap SSH key login.
  8. Only then treat the jail as an operator node.
Protocol lesson: auth and sudo work should start with a read step such as ls, cat, grep, id, or groups. The first write should come only after the current shape is confirmed.

1. Package and User Bootstrap

These were the minimum proven commands on the host.

jexec controlplane pkg update
jexec controlplane pkg upgrade -y
jexec controlplane pkg install -y bash sudo tmux curl python3
jexec controlplane pw usershow clawdie >/dev/null 2>&1 || jexec controlplane pw useradd clawdie -m -s /usr/local/bin/bash

Then prepare the home and group membership:

jexec controlplane install -d -o clawdie -g clawdie -m 700 /home/clawdie/.ssh
jexec controlplane pw groupmod wheel -m clawdie
jexec controlplane pw groupmod operator -m clawdie

The operator expectation is explicit now: clawdie should land in a working bash shell, not in /bin/sh.

Verification

jexec controlplane id clawdie
uid=1001(clawdie) gid=1001(clawdie) groups=0(wheel),5(operator),1001(clawdie)

2. Enable Base SSHD

Check the built-in FreeBSD SSH service before considering extra packages.

jexec controlplane which ssh
jexec controlplane which sshd
jexec controlplane ls -l /etc/rc.d/sshd

Then enable it:

jexec controlplane sysrc sshd_enable=YES
jexec controlplane service sshd start
jexec controlplane service sshd status

Observed first start

Generating RSA host key.
3072 SHA256:Z0m3th1n6-F4k3-RS4-K3y controlplane (RSA)
Generating ECDSA host key.
256 SHA256:Z0m3th1n6-F4k3-3CDS4-K3y controlplane (ECDSA)
Generating ED25519 host key.
256 SHA256:Z0m3th1n6-F4k3-3D25519-K3y controlplane (ED25519)
Performing sanity check on sshd configuration.
Starting sshd.

sshd is running as pid 38xxx.

3. First SSH Login and the Password Prompt

At this stage the jail is reachable, but key authentication is not configured yet, so SSH falls back to password login.

[clawdie@osa ~/clawdie-ai]$ ping 10.0.0.100
PING 10.0.0.100 (10.0.0.100): 56 data bytes
64 bytes from 10.0.0.100: icmp_seq=0 ttl=64 time=0.42 ms
64 bytes from 10.0.0.100: icmp_seq=1 ttl=64 time=0.36 ms
^C

[clawdie@osa ~/clawdie-ai]$ ssh 10.0.0.100
The authenticity of host '10.0.0.100 (10.0.0.100)' can't be established.
ED25519 key fingerprint is SHA256:Z0m3th1n6-F4k3-3D25519-K3y.
Warning: Permanently added '10.0.0.100' (ED25519) to the list of known hosts.
(clawdie@10.0.0.100) Password for clawdie@controlplane:

That password prompt is expected until a public key lands in /home/clawdie/.ssh/authorized_keys inside the jail.

4. Inspect Sudo Before Changing It

This is the exact pattern worth keeping. Read the live files first, then add the smallest possible change.

ls /usr/local/etc/sudoers.d
jexec controlplane cat /usr/local/etc/sudoers

The critical line already existed:

@includedir /usr/local/etc/sudoers.d

That made the drop-in path safe:

jexec controlplane ls /usr/local/etc/sudoers.d
jexec controlplane sh -c "printf '%s\n' '%wheel ALL=(ALL:ALL) NOPASSWD: ALL' > /usr/local/etc/sudoers.d/wheel-nopasswd"
jexec controlplane chmod 440 /usr/local/etc/sudoers.d/wheel-nopasswd
jexec controlplane visudo -c

Validation

/usr/local/etc/sudoers: parsed OK
/usr/local/etc/sudoers.d/wheel-nopasswd: parsed OK
Failure mode: if clawdie is not really in wheel, sudo will still ask for a password even though the drop-in parses correctly.

5. Fix the Real Sudo Problem: Group Membership

The first login showed the actual issue clearly:

clawdie@controlplane:~ $ id
uid=1001(clawdie) gid=1001(clawdie) groups=5(operator),1001(clawdie)

After adding wheel and logging in again, the state became correct:

clawdie@controlplane:~ $ id
uid=1001(clawdie) gid=1001(clawdie) groups=0(wheel),5(operator),1001(clawdie)

clawdie@controlplane:~ $ sudo -i
root@controlplane:~ # id
uid=0(root) gid=0(wheel) groups=0(wheel),5(operator)
Result: once clawdie was really in wheel, the NOPASSWD rule worked as expected.

6. SSH Key Bootstrap

The quick path used here was host-to-jail bootstrap first, then later a dedicated automation key can be generated inside controlplane for Ansible.

ssh-copy-id -i /home/clawdie/.ssh/id_ed25519.pub clawdie@10.0.0.100
ssh -o PasswordAuthentication=no clawdie@10.0.0.100

Once that works, password auth can be phased out in sshd_config.

7. What Changed in the Design

8. Minimal Proven Checklist

jexec controlplane pkg update
jexec controlplane pkg upgrade -y
jexec controlplane pkg install -y bash sudo tmux curl python3
jexec controlplane pw usershow clawdie >/dev/null 2>&1 || jexec controlplane pw useradd clawdie -m -s /usr/local/bin/bash
jexec controlplane install -d -o clawdie -g clawdie -m 700 /home/clawdie/.ssh
jexec controlplane pw groupmod wheel -m clawdie
jexec controlplane pw groupmod operator -m clawdie
jexec controlplane sysrc sshd_enable=YES
jexec controlplane service sshd start
jexec controlplane cat /usr/local/etc/sudoers
jexec controlplane sh -c "printf '%s\n' '%wheel ALL=(ALL:ALL) NOPASSWD: ALL' > /usr/local/etc/sudoers.d/wheel-nopasswd"
jexec controlplane chmod 440 /usr/local/etc/sudoers.d/wheel-nopasswd
jexec controlplane visudo -c