--- name: ssh-key-bootstrap-no-sshpass description: "Bootstrap passwordless SSH from a dev box to fleet hosts when sshpass/expect are unavailable, using OpenSSH SSH_ASKPASS_REQUIRE=force so the password never touches disk." --- # Passwordless SSH bootstrap without sshpass/expect Use when you must install your pubkey on remote hosts but `sshpass` and `expect` are not installed, and you only have a password. Modern OpenSSH (>= 8.4) can drive the password prompt from a helper program, so the password flows through the **process env only** — never a file. ## Procedure 1. **Generate a key** (if none): ```bash ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N "" -C "host-deploy-$(date +%Y%m%d)" ``` 2. **Create an askpass helper** that echoes the password from an env var (the helper itself stores NO secret): ```bash printf '#!/bin/sh\necho "$DEPLOY_PW"\n' > /tmp/askpass.sh chmod 700 /tmp/askpass.sh ``` 3. **Copy the pubkey**, forcing the askpass path and detaching from the TTY with `setsid` (ssh only uses SSH_ASKPASS when there is no controlling TTY, unless `SSH_ASKPASS_REQUIRE=force`): ```bash env DEPLOY_PW='' \ SSH_ASKPASS=/tmp/askpass.sh \ SSH_ASKPASS_REQUIRE=force \ setsid ssh-copy-id -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 user@host ``` Pass the password via the `env` argument (transient), never in a committed file or shell history. 4. **Add host aliases** in `~/.ssh/config` so deploy scripts resolve names: ``` Host myhost HostName 10.0.0.5 User deployuser IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes ``` 5. **Verify** key auth with no prompt: ```bash ssh -o BatchMode=yes myhost 'echo OK; hostname' ``` `BatchMode=yes` fails fast if a password would be required — a clean success proves the key works. ## Gotchas - Without `SSH_ASKPASS_REQUIRE=force`, ssh ignores SSH_ASKPASS when a TTY is present and just prompts interactively (hangs in a non-interactive tool). - `setsid` detaches the controlling terminal — required on older OpenSSH even with `force`, harmless otherwise. - The helper must be executable (`chmod 700`) and print ONLY the password. - `IdentitiesOnly yes` stops ssh offering other agent keys that could be rejected before yours, avoiding "Too many authentication failures". - Passwordless **sudo** on the target is a separate concern (NOPASSWD / `FRANK_SUDO_PW`); this skill only covers SSH key auth.