Merge branch 'code/majorrig/wiki-ssh-magicdns-article'

This commit is contained in:
Marcus Summers 2026-06-11 20:12:34 -04:00
commit 513d94aa84
3 changed files with 129 additions and 0 deletions

View file

@ -18,6 +18,7 @@ Practical fixes for common Linux, networking, and application problems.
- [Postfix header_checks Can't Act on Milter-Added Headers (Use Sieve)](networking/postfix-header-checks-vs-milter-headers.md)
- [Dovecot Phantom Mailboxes from .dovecot.lda-dupes (mail_home Overlapping the Maildir Root)](networking/dovecot-mail-home-maildir-root-phantom-mailboxes.md)
- [Tailscale SSH: Unexpected Re-Authentication Prompt](networking/tailscale-ssh-reauth-prompt.md)
- [SSH Alias Falls Through to MagicDNS — Host-Key Verification Failure (No `Host` Block)](networking/ssh-missing-host-block-magicdns-host-key-failure.md)
- [iOS Tailscale Clients Report HostName="localhost" — Breaks /etc/hosts Generators](networking/tailscale-status-json-hostname-localhost-ios.md)
- [rsync over Tailscale: Hung in TCP Teardown After Transfer Completes](networking/rsync-tailscale-teardown-stall.md)
- [Windows OpenSSH: WSL Default Shell Breaks Remote Commands](networking/windows-openssh-wsl-default-shell-breaks-remote-commands.md)

View file

@ -0,0 +1,127 @@
---
title: "SSH Alias Falls Through to MagicDNS — Host-Key Verification Failure (No `Host` Block)"
domain: selfhosting
category: troubleshooting
tags:
- ssh
- ssh-config
- tailscale
- magicdns
- known-hosts
- host-key
- troubleshooting
status: published
created: 2026-06-11
updated: 2026-06-11
---
# SSH Alias Falls Through to MagicDNS — Host-Key Verification Failure (No `Host` Block)
## The Problem
You `ssh` to a host you've reached many times before, but now it dies before any
auth happens:
```
$ ssh MyMac
ssh_askpass: exec(/usr/libexec/openssh/ssh-askpass): No such file or directory
Host key verification failed.
```
On a headless box (WSL, a server, a CI runner) there's no askpass binary, so the
prompt can't even be shown — SSH just aborts. Connecting **by Tailscale IP** works
fine:
```
$ ssh user@100.74.124.81 # works
$ ssh MyMac # Host key verification failed
```
## Why It Happens
There is **no `Host MyMac` block in `~/.ssh/config` at all** — and there never was.
The connection only ever worked by IP, or interactively (where you clicked through
the first-connect `yes` prompt without noticing).
When no `Host` block matches, SSH uses the literal argument as the hostname. With
Tailscale MagicDNS, `MyMac` (or `mymac`) resolves to the node — so the *connection*
succeeds — but the host key it presents is checked against `known_hosts` under the
name **`mymac`**, which has no entry. Meanwhile the key you actually trust is stored
under the **IP**:
```
$ ssh-keygen -F 100.74.124.81 # found — line 67
$ ssh-keygen -F mymac # nothing
```
So strict host-key checking has nothing to match, tries to prompt to accept the
"new" key, and on a headless host that prompt fails → `Host key verification failed`.
Confirm there's no block (and that `ssh -G` is just echoing defaults):
```
$ ssh -G MyMac | grep -E '^(hostname|user|port) '
hostname mymac # lowercased literal — NOT an explicit HostName
user youruser # your local username default — not from a block
port 22 # default
```
If `hostname` equals the arg you typed (just lowercased) and `user` is your local
login name, there is no matching `Host` block.
## The Fix
Add an explicit `Host` block that **pins the IP** that `known_hosts` already trusts.
This matches the convention every other host in a Tailscale fleet should follow —
pin the `100.x` address, not the MagicDNS name:
```sshconfig
Host MyMac mymac
HostName 100.74.124.81
User youruser
IdentityFile ~/.ssh/id_ed25519
```
Now `ssh MyMac` resolves to `100.74.124.81`, whose key is in `known_hosts`, and the
check passes with no prompt. Verify non-interactively:
```
$ ssh -o BatchMode=yes MyMac 'hostname'
mymac.majorlan
```
`BatchMode=yes` disables every prompt — if it returns the hostname cleanly, the key
is trusted and a real key authenticated.
**Don't over-pin the identity.** Run `ssh -v user@<IP> true` and check the
`Will attempt key` / accepted-key lines first. A workstation often authenticates
with the *default* `id_ed25519`, not a fleet key — if `id_ed25519_fleet` isn't even
offered, don't put it in the block.
## Cleanup: Stale `known_hosts` Cruft
Drive-by `ssh` attempts leave junk entries like `mymac-2` (auto-suffixed names from
old keys). They never match anything once you pin the IP. Purge them:
```
$ ssh-keygen -R mymac-2
```
## How to Diagnose This
1. `ssh -o BatchMode=yes <alias> true` — if it fails with `Host key verification
failed` (not `Permission denied`), it's a host-key problem, not auth.
2. `ssh -G <alias> | grep -E '^(hostname|user|port) '` — if `hostname` is just your
typed arg and there's no real `HostName`, there's no `Host` block.
3. `ssh-keygen -F <name>` vs `ssh-keygen -F <ip>` — find which name actually holds
the trusted key. Pin whichever one `known_hosts` has (usually the IP).
## Why This Gotcha Is Invisible
It only surfaces on a host with **no askpass** (headless / WSL / cron). On a desktop,
the first-connect prompt appears, you hit `yes`, an entry gets written under the
MagicDNS name, and it "just works" — masking the fact that no `Host` block exists and
the IP-keyed entry is the only durable trust. Move the same config to a headless box
and the missing block becomes a hard failure. Related: SSH only applies `Host` blocks
by **literal pattern match**, so connecting by IP also skips them — see *Ansible Fails
with Permission Denied While `ssh <alias>` Works (Host Alias Bypass)*.

View file

@ -132,5 +132,6 @@ updated: 2026-05-15T09:00
* [wget/curl: URLs with Special Characters Fail in Bash](05-troubleshooting/wget-url-special-characters.md)
* [Ansible: Check Mode False Positives in Verify/Assert Tasks](05-troubleshooting/ansible-check-mode-false-positives.md)
* [Ansible Fails with Permission Denied While `ssh <alias>` Works (Host Alias Bypass)](05-troubleshooting/ansible-ssh-host-alias-bypass.md)
* [SSH Alias Falls Through to MagicDNS — Host-Key Verification Failure (No `Host` Block)](05-troubleshooting/networking/ssh-missing-host-block-magicdns-host-key-failure.md)
* [Ghost EmailAnalytics Lag Warning — What It Means and When to Worry](05-troubleshooting/ghost-emailanalytics-lag-warning.md)
* [claude-mem: --setting-sources Empty Arg Bug (Claude Code 2.1.x)](05-troubleshooting/claude-mem-setting-sources-empty-arg.md)