ansible-ssh — SSH login + tooling for k8s-management

Summary of the work that configured a key-based SSH login on k8s-management (Proxmox LXC 105) with Ansible, owning both the SSH server and the tools (talosctl/kubectl).

Starting point (what was wrong)

Decisions

Files added / changed

a├├├├├├└n───────s───────ibahrsgRr├││││└lnoeirEo──essqtoAl──/itueuDebsi.pMss├├├└t├└l.ry_Es────o──eyemv.h────o──.mmlam_lclerdsdhttsdtfnseeaae/eagt/rfnsmfssavadkpak.leulslusylrle/al/m./trmttmlyssaesam//is/ilmmnmnaa.sa.iiysiynnmhnm..ld.lyy_y#####mmcmllolitasjnnansafvrshniegi_,gnebs.ttlekdoere/r=.vy9ype9,corp-osakpni+t8rtxhsiat,-vicomanoosatellsnerlsha'edgksc+eet+myhive,ooetnmnrotbeio.e-flccniooecsnmtaefewtt.oitjroi2knn/gasvsmsberr0t)saddress

ssh_server role

tools role

Terraform change (management.tf)

k8s-management-setup.sh now only:

  1. Writes /etc/resolv.conf if empty (so Ansible can apt).
  2. Seeds /root/.ssh/authorized_keys with the control-node public key.

Everything else (sshd, jan, tools) is owned by Ansible.

The container entrypoint is written only when the container is created, so this boot-script change needs a recreate to take effect for a fresh container:

tof--urteaaprplgpaelctye==p-prrroeoxfxmrmoeoxsx_h_v=vifirartltusuaeall_-_eaenunvtvioir-roaonpnmpmerenontvt_e_cco\onnttaaiinneerr..mmaannaaggeemmeenntt\

tofu apply was intentionally not run (it would recreate the running container unnecessarily); the live container is already fully configured.

How to run

cd ansible
ansible-galaxy collection install -r requirements.yml   # once
ansible-playbook site.yml

Target address: hosts.yml points at the container’s DHCP address on the home network (vmbr0), not 10.10.50.10 (that one is only reachable inside vmbr1). If the lease changes:

ansible-playbook site.yml \
  -e "ansible_host=$(cd .. && tofu output -json management | jq -r .wan_ips.eth0)"

Verification (live, on the running container)

SSH login as jan with key-only auth and passwordless sudo:

$juraiosndos=th10j0a0n(@j1a9n2).1g6i8d.=01.010307(j'awnh)oagmrio;upisd=;10s0u0d(oja-nn),w2h7o(asmuid'o)

Tools available to jan:

$CTlasilseohns"tgj:via1tn.V@1e14r9.s22i.o1n6"8:.0".v113.737'.t1a"l,osctlversion-client-short;kubectlversion-clientjson|grepgitVersion'

Effective sshd policy:

$pppaaeuallsrbsllsmksoohiewwwtyouurrarssooudeeootarrtthuss@let1onhrj9gteoa2iinon.nctt1ai6ptc8ria.oot0hni.io1byn3ie7tsn-op/ausssrw/osrbdin/sshd-T|grep-Ei"^(passwordauthentication|permitrootlogin|pubkeyauthentication|allowusers)"'

Playbook run (idempotent):

PkL8AsY-mRaEnCaAgPement:ok=22changed=0unreachable=0failed=0skipped=2

The playbook also asserts, at the end, that PasswordAuthentication is disabled and PermitRootLogin is prohibit-password.

Drift test: /home/jan was reverted to root:root on purpose, which broke key auth as expected; a subsequent ansible-playbook site.yml detected and fixed the ownership (changed=1), and jan could log in again. A following run was back to changed=0.

OpenTofu checks:

Logging in from another server (no local jan account)

The remote login name is always jan; the client does not need a local jan account. It only needs a private key whose public key is authorized for jan on the container.

Verified end-to-end: a throwaway ed25519 key added via ssh_extra_authorized_keys logged in as jan with passwordless sudo (changed=1); after removing it, the normal run returned to changed=0.

Only root and jan are accepted by AllowUsers; a different login name requires creating that user and adding it to sshd_allow_users. Password auth stays disabled, so a key is mandatory. Network path: container eth0 (home network) or 10.10.50.10 from inside vmbr1.

Environment notes

Troubleshooting

ssh 192.168.0.137 -l jan → Permission denied (publickey) from the control node

The key lives in the jan account: /home/jan/.ssh/id_ed25519 (owner jan, mode 600). If the ssh client is run as root@ubuntu26CT, root only looks in /root/.ssh/ (and the agent), finds no key, and offers none — the server then correctly rejects it. The server side is fine (sshd -T shows pubkeyauthentication yes and allowusers ... jan).

Use one of:

# run as the account that owns the key
ssh jan@192.168.0.137

# as root, point ssh at jan's key explicitly
ssh -i /home/jan/.ssh/id_ed25519 jan@192.168.0.137

# or give root its own copy (needs root)
install -d -m 700 /root/.ssh
install -m 600 /home/jan/.ssh/id_ed25519 /root/.ssh/id_ed25519

The ED25519 key fingerprint ... continue connecting? prompt is expected after a container recreate/reboot (new host key); accepting just adds it to known_hosts.