Secure Shell (SSH) Client Config Editor
Edit an SSH client config locally, test Host wildcards, preserve Match and Include text, and flag risky or duplicate directives before use.{{ summaryTitle }}
{{ generatedConfig }}
| Level | Scope | Finding | Next action | Copy |
|---|---|---|---|---|
| {{ row.level }} | {{ row.scope }} | {{ row.finding }} | {{ row.action }} |
| Host patterns | HostName | User | Directives | Test match | Copy |
|---|---|---|---|---|---|
| {{ 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.
Hostblock- 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. Matchsection- 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.
- 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
Hostblock if the input warning remains. - 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. - 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
Hostblock. Compare the generated config before using it. - Copy the generated config to a temporary location, then run
ssh -G destinationwith 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 nooroff, 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
Matchsections 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:
| 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.
| 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:
- ssh_config manual page, OpenBSD.
- How to show SSH client configuration, Simplified Guide.