{{ summaryTitle }}
{{ summaryValue }}
{{ summaryLine }}
{{ badge.label }}{{ badge.value }}
SSH client configuration source and hostname test
Edit one config up to 200 KB. Comments, blank lines, Include lines, and opaque Match sections are preserved.
{{ sourceMeta }}
{{ fileStatus || 'Drop one SSH config or text file onto the editor.' }}
Use the alias typed after ssh, such as app-01 or bastion. Leave blank to skip matching.
{{ workflowFeedback }}
{{ handoffStatus }}
Off preserves source spelling. On changes only recognized directive names.
{{ params.normalize_keys ? 'Enabled' : 'Disabled' }}
Off preserves line order. On creates stable within-block comparisons.
{{ params.sort_keys ? 'Enabled' : 'Disabled' }}
Off preserves duplicates for review. On removes later repeated keys within each Host block.
{{ params.dedupe_keys ? 'Enabled' : 'Disabled' }}
Off leaves the first source line unchanged.
{{ params.include_header ? 'Enabled' : 'Disabled' }}
{{ generatedConfig }}
LevelScopeFindingNext actionCopy
{{ row.level }}{{ row.scope }}{{ row.finding }}{{ row.action }}
Host patternsHostNameUserDirectivesTest matchCopy
{{ row.patterns }}{{ row.hostname || '—' }}{{ row.user || '—' }}{{ row.directive_count }}{{ row.match_label }}

An SSH client configuration turns short destination names into connection instructions. A block such as Host app-prod can supply the real hostname, login name, identity file, jump host, keepalive settings, and host-key policy that the client should use. This is convenient, but it also means a connection may behave very differently from the command that appears in a terminal.

Order matters because OpenSSH obtains most option values only once. A specific block near the top can set a value before a later Host * block is considered. Putting broad defaults first may therefore prevent a more specific block from taking effect. Repeated directives inside one block create a similar review problem: the later line may look like an override even though the earlier value normally wins.

Host block
A group of settings selected by one or more destination patterns.
Positive pattern
A name or wildcard such as app-* that can include a destination in a block.
Negated pattern
A pattern beginning with ! that excludes a matching destination, even when another pattern matches.
Match section
A conditional section that may depend on details beyond a hostname, including the final destination, user, command, or local execution context.

Config cleanup is safest when formatting changes are separated from behavior changes. Normalizing directive spelling can make a file easier to scan. Sorting directives changes their position, and removing duplicates changes the text that will be handed to OpenSSH. Comments, blank lines, included files, and conditional sections also carry operational context that a simple editor cannot fully evaluate.

A lint pass is therefore a preparation step, not proof that a connection is correct or secure. Before replacing a working config, inspect the generated text, ask OpenSSH for the effective settings with ssh -G destination, and test the actual account and destination under the same command-line options you intend to use.

How to Use This Tool:

Begin with one client config and a destination alias you actually use. Keep the editing switches off for the first review so the generated text stays close to the source.

  1. Paste the config into SSH client config or load one text-like file up to 200 KB. Remove NUL characters and make sure the file contains at least one Host block if the input warning remains.
  2. Enter a single alias in Test hostname, such as app-01. The host inventory marks blocks whose positive patterns match and whose negated patterns do not.
  3. Review duplicate, ordering, and security findings before enabling edits. Turn on Canonical directive case, Directive ordering, Duplicate handling, or Managed header only for the changes you want.
    Sorting moves parsed directives ahead of comments and other preserved lines within a Host block. Compare the generated config before using it.
  4. Copy the generated config to a temporary location, then run ssh -G destination with the real alias and command-line options. Resolve unexpected HostName, User, IdentityFile, ProxyJump, or forwarding values before replacing the active file.

Interpreting Results:

Treat the generated config as the proposed artifact and the review findings as focused warnings. A clean bounded review means none of the implemented checks fired; it does not mean that included files, conditional Match rules, DNS, keys, server policy, or authentication will work.

  • High calls out StrictHostKeyChecking no or off, which disables host-key confirmation.
  • Review marks choices such as accept-new, agent forwarding, or explicit password authentication that need an intentional trust decision.
  • Warning covers structural concerns such as repeated keys, empty blocks, or a catch-all block before a more specific block.
  • Info identifies bounded behavior, including preserved Match sections that were not conditionally evaluated.

Technical Details:

OpenSSH reads client settings from several sources and generally uses the first value obtained for each parameter. Configuration files are processed from top to bottom, while a destination may match more than one Host block. That combination makes rule order part of the effective configuration.

Rule Core:

SSH client config review and hostname matching rules
Rule Applied behavior Important boundary
Block recognition Lines beginning with Host start parsed host blocks. Comments, blank lines, and other raw text remain preserved. At least one parsed Host block is required.
Wildcard test * matches any character sequence and ? matches one character, without regard to letter case. At least one positive pattern must match; any matching ! pattern rejects the block.
Duplicate review Directive names are compared without regard to case inside each parsed Host block. Removing duplicates keeps the first occurrence and removes later occurrences, including directives that may be intentionally repeatable.
Conditional text Match sections and Include lines are retained in the generated text. The conditions are not evaluated and included files are not loaded.

Transformation Core:

With every editing switch off, trailing whitespace at the end of the full source is removed and the rest of the text is left in source order. Optional changes are applied within parsed Host blocks.

Optional SSH client config transformations
Option Transformation Preserved content
Canonical directive case Recognized directive names are rewritten to their manual-page spelling. Values, indentation, and separators remain unchanged.
Directive ordering Parsed directives are sorted alphabetically, with original line number breaking ties. Non-directive lines stay in the block but follow the sorted directives.
Duplicate handling Later occurrences of the same case-insensitive key are removed within a block. The first occurrence is retained.
Managed header One identifying comment is inserted at the start. No directive value or matching rule is changed by the comment.

The hostname test accepts one value of at most 253 characters and rejects whitespace. It models only the visible Host patterns; it does not expand percent tokens, canonicalize hostnames, follow includes, apply Match conditions, or merge system-wide defaults.

Privacy and Limits:

The config text and selected file are processed in the browser. Included paths are not fetched, and the hostname test does not make an SSH connection.

  • Config files can expose internal hostnames, usernames, jump hosts, key paths, forwarding rules, and network layout. Remove sensitive values before sharing review output.
  • The parser preserves unfamiliar or conditional text but cannot prove that OpenSSH will accept every line.
  • Host-key, agent-forwarding, and password-authentication findings are focused cautions rather than a complete SSH security audit.

Worked Example:

Specific host after catch-all defaults

Suppose Host * appears first with User ops, followed by Host app-prod with User deploy. The review warns that the catch-all block precedes a specific block because OpenSSH will normally keep the first user value it obtains. Moving the general block after app-prod, then checking ssh -G app-prod, confirms whether the effective user is now deploy.

References: