Docs / Security

Fail-closed host verification

NetShell checks who a server really is before it sends a single secret — and if the answer is wrong, the connection fails closed and never leaks your credentials.

The risk: who are you actually talking to?

When you type a hostname or IP, nothing about that address guarantees the machine answering is the one you meant. An attacker on the same network, a poisoned DNS entry, or a misconfigured router can quietly stand between you and your server — a classic man-in-the-middle (MITM) attack. If your SSH client hands over a password or a private-key signature to that impostor, the attacker now holds the keys to your real infrastructure. Host verification exists to make sure the server proves its identity first.

How SSH proves a server's identity

Every SSH server has its own host key — a public/private key pair that belongs to the machine, not to any user. During the connection handshake the server presents its public host key and cryptographically proves it holds the matching private key. That proof is what lets a client say "this really is the same box I trusted last time." NetShell records the host key the first time you connect and compares it on every connection afterward.

Trust on first use (TOFU)

NetShell uses a trust-on-first-use model. The first time you connect to a host, NetShell has nothing to compare against, so it shows you the server's host key and asks you to approve it. Once you approve, that key is pinned to the connection and stored on the device. From then on, NetShell silently verifies that the server keeps presenting the same key.

  • First connection: you're shown the new host key and asked to trust it.
  • Every later connection: NetShell compares the presented key against the one you pinned — a match connects you straight through.
  • A mismatch: NetShell stops and warns you that the key changed, because that can mean a MITM attack.
Tip. If you can, verify a brand-new host key out of band — for example, run ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub on the server's console and compare the fingerprint before you approve. TOFU is only as strong as that first approval.

Verification happens during the handshake — before credentials

This is the part that matters most. NetShell validates the host key inside the SSH handshake, before the authentication phase begins. Your password, key passphrase, or private-key signature is never transmitted to a server that hasn't passed verification. Many naive flows check the host only after a session is up — by then the secret is already on the wire. NetShell deliberately gates trust at handshake time so an unknown or changed host can be rejected with nothing sensitive sent.

Fail closed on unknown or changed keys

NetShell's default is to fail closed. If a host key is unknown (and you don't approve it) or has changed from what you pinned, the connection is refused rather than allowed through. There is no silent "accept anything" path: a security decision that controls whether credentials leave your device never defaults to permissive. When verification can't be satisfied, the safe outcome — no connection, no leaked secret — is the one you get.

  • Unknown key: you're prompted to review and explicitly approve before anything proceeds.
  • Changed key: the connection is blocked and you're warned, so you can investigate before trusting.
  • No approval: the handshake is abandoned and credentials stay sealed in the Keychain.

What a changed key really means

A host key that suddenly differs is worth taking seriously. Common benign causes are a server rebuild, an OS reinstall, or a deliberate key rotation by an administrator. The dangerous cause is a MITM attacker substituting their own key to intercept your traffic. NetShell can't tell these apart for you — that's why it stops and hands the decision back to you. Confirm the change is expected (ask whoever manages the box, or check the fingerprint on the console) before you approve the new key. If you weren't expecting a change, treat it as hostile until proven otherwise.

Verification across multi-hop and jump hosts

When you chain through a jump host, every hop in the chain is a separate SSH server with its own host key — and NetShell applies the same fail-closed verification to each one. A bastion you connect through is verified just like a final destination, so an attacker can't slip into the middle of a tunnel any more than they can at the front door. The same protection extends to the SFTP browser and other features that open SSH connections under the hood.

Managing your trusted hosts

Trusted host keys are stored locally on each device. They are deliberately kept device-local and do not sync — unlike your connections and your private keys, host trust is a per-device decision and isn't propagated through iCloud. That means each iPhone, iPad, or Mac builds its own known-hosts trust on first connection, and revoking trust on one device doesn't depend on the others.

  • Approve: trust a host the first time you connect, after reviewing its key.
  • Re-verify: when a key changes, you decide per-connection whether the new key is legitimate.
  • Reset: removing or reinstalling a host's stored trust simply triggers a fresh first-use approval next time you connect.

Because host trust is separate from credentials, your passwords and keys stay protected in the hardware-backed iOS Keychain and sync only through Apple's end-to-end encrypted iCloud Keychain — never through the same path as host trust. See iCloud Keychain sync and Encryption for the full picture.

Where it fits in NetShell's defenses

Host verification is one layer of several. It guards the front door so credentials never reach an impostor; the destructive-command guard intercepts dangerous commands like rm -rf or DROP TABLE before they hit the wire; and the Face ID lock reseals the app after it's been idle. Together they're built so a single mistake doesn't hand over your servers. NetShell is a free SSH client for iPhone, iPad & Mac with no telemetry by default — you can download it on the App Store.