Secure Shell (SSH) Client Config Editor
Edit an SSH client config in your browser, reorganize Host blocks, test wildcard matches, and review lint, security, and diff reports.SSH Config Summary
Current status
| Host | Domain | Keys | Wildcard | Copy |
|---|---|---|---|---|
| {{ r.host }} | {{ r.domain || '—' }} | {{ r.keyCount }} | {{ r.wild ? 'Yes' : 'No' }} | |
| No rows | ||||
| Host | Issue | Copy |
|---|---|---|
| {{ w.host }} | {{ w.issue }} | |
| No issues found. | ||
| Severity | Host | Issue | Recommendation | Copy |
|---|---|---|---|---|
| {{ finding.severityLabel }} | {{ finding.host || 'Global' }} | {{ finding.issue }} | {{ finding.recommendation }} | |
|
No security findings
The current Host blocks do not trigger the configured SSH safety checks.
|
||||
| Directive | Hosts | Unique values | Missing | Example value | Copy |
|---|---|---|---|---|---|
| {{ row.key }} | {{ row.hostCount }} | {{ row.uniqueValues }} | {{ row.missingHosts }} | {{ row.sampleValue || '—' }} | |
|
No directive insights
Add Host blocks with directives to populate the coverage ledger.
|
|||||
A client SSH config is a local routing map for the names people type after ssh. It can turn ssh prod-app into a real hostname, a non-default user, a port, a private key, and a jump-host path. That convenience is valuable, but the file often grows by copying old blocks, adding temporary tunnels, and leaving broad defaults in place after the immediate problem is solved.
OpenSSH reads configuration in a strict order. Command-line options come first, then the user config, then the system config, and for most parameters the first value found wins. Inside a config file, this makes order matter: a specific Host app-01 block should usually appear before a broad Host * block so the specific setting has the first chance to set a value. Wildcards, negated patterns, and conditional Match sections make the file compact, but they also make it easy to believe a block applies differently than it really does.
Several terms matter before editing. A Host line names one or more aliases or patterns. A directive such as User, Port, IdentityFile, or ProxyJump sets client behavior for that matched alias. Include can pull in more config text, while Match applies settings only when a condition is true. A single config file may therefore be only part of the final answer that ssh uses.
| Common change | Why it helps | Mistake to avoid |
|---|---|---|
| Adding a host alias | Replaces a long hostname, user, port, and key combination with one short name. | Forgetting HostName and relying on an alias that only works in one DNS environment. |
| Using a wildcard block | Applies repeated defaults to a whole group such as *.internal. |
Putting a broad pattern before more specific blocks that should override it. |
| Routing through a jump host | Keeps private hosts reachable through a bastion without long command lines. | Mixing old and new jump settings so traffic follows an unexpected path. |
| Relaxing host-key checks | May unblock a temporary lab or rebuild during troubleshooting. | Carrying StrictHostKeyChecking no into normal use where host identity should be verified. |
A useful edit is not only a cleaner file. It should also make the effective behavior easier to predict: which alias matches, which value is chosen first, which key is offered, which tunnel listens where, and which shortcuts need a second look before the config is copied into regular use.
How to Use This Tool:
- Paste or drop one OpenSSH client config into SSH config source. The editor reads Host blocks, directive rows, top comments,
Includelines, andMatchlines that are visible in the text you provide. - Use Host filter and Group hosts by when the file is large. Filtering searches aliases, directive names, directive values, users, target hostnames, and jump-host values without changing the generated config.
- Open a Host block to edit its pattern and directive rows. Add a row for a directive such as
HostName,User,IdentityFile,ProxyJump,LocalForward, or a custom key when your SSH version supports it. - Turn on advanced options only when they match your intended output: alphabetical host sorting, canonical directive casing, directive sorting, repeated-key de-duplication, preserved non-Host lines, or a generated header comment.
- Use Match tester with a sample alias such as
web-01.internal. The count should change when a wildcard or negated token matches the sample name. - Review Generated Config, Host Inventory, Lint Report, Security Review, Directive Insights, and Config Diff before copying or downloading the final text.
Interpreting Results:
The generated config is the edited text you can copy into your own workflow, not an automatic change to your real SSH files. Treat the reports as a review checklist. A lint warning usually means the config is harder to maintain or compare. A security finding means a setting can weaken host identity checks, widen a tunnel, rely on passwords, expose an agent, or increase the impact of a compromised account.
The diff deserves special attention after sorting, case normalization, duplicate removal, or non-Host preservation changes. A small-looking order change can change which value OpenSSH chooses first. If the generated text moves a broad Host * block upward, compare the affected aliases before using that output.
| Result area | Useful signal | Check before trusting it |
|---|---|---|
| Generated Config | The current edited Host blocks with selected formatting and preservation options applied. | Confirm the block order and any removed duplicate directives still match the behavior you wanted. |
| Lint Report | Empty Host patterns, empty values, duplicate keys, empty blocks, and catch-all ordering warnings. | A warning may be intentional during a migration, but it should not be accidental. |
| Security Review | Root user shortcuts, missing identity files, password authentication, relaxed host-key checks, agent forwarding, and exposed forwards. | The report is conservative. Lab, recovery, and bastion setups may still need a setting that looks risky. |
| Directive Insights | How widely each directive appears, how many distinct values it has, and which hosts are missing it. | Different host groups often need different keys, ports, or jump hosts, so variation is not automatically a problem. |
| Config Diff | Added, removed, and unchanged lines compared with the imported baseline text. | For very large files, verify the final config with your normal SSH test path before replacing a working file. |
Technical Details:
OpenSSH client configuration is a sequence of keyword and argument lines. A Host line starts a section that applies until the next Host or Match line. More than one pattern may follow Host, separated by whitespace. A pattern can use * for any string and ? for one character; a pattern starting with ! excludes a match even when another pattern on the same line would include it.
The order rule is the main reason SSH config edits need careful review. For most parameters, OpenSSH uses the first value it obtains, so a later block cannot always override an earlier one. Broad defaults normally belong near the end, and specific aliases normally belong near the beginning. Conditional Match sections, included files, command-line options, system-wide config, and hostname canonicalization can all affect the final result outside the text being edited.
Transformation Core:
The editor treats visible Host sections as the editable units and then reconstructs a text config from those units. Non-Host lines can be preserved, but they are not expanded or executed.
| Stage | What happens | Important boundary |
|---|---|---|
| Read text | Visible comments before the first Host block, Include lines, Match lines, Host patterns, and directive rows are recognized. |
Blank lines and comments inside Host blocks are not treated as editable directive rows. |
| Edit Host blocks | Host patterns and directive key-value rows can be added, duplicated, removed, sorted, normalized, and filtered for review. | The filter only narrows the review list; it does not remove hidden rows from the generated config. |
| Prepare output | Selected formatting options decide host order, directive order, key casing, duplicate-key handling, preserved non-Host text, and the optional header comment. | De-duplication keeps the last repeated directive within a Host block after key normalization. |
| Compare output | The generated text is compared with the imported baseline to show additions, removals, and unchanged lines. | Diff output is text comparison, not a live ssh evaluation of every included or system-level setting. |
Rule Core:
The review rules focus on patterns that commonly cause wrong connections or weaker defaults. They are prompts for human review, not proof that a config is broken.
| Rule | Finding type | Why it matters |
|---|---|---|
Host * appears before later Host blocks |
Lint warning | A broad default can set a value before a later, more specific block is reached. |
| Duplicate directive in one Host block | Lint warning | Repeated keys make the intended value harder to audit and can hide stale settings. |
User root or PasswordAuthentication yes |
High security finding | Direct root access and password login increase the damage from credential theft or misrouting. |
StrictHostKeyChecking no |
High security finding | Changed or impersonated hosts are easier to miss when host-key verification is disabled. |
ForwardAgent yes |
Medium security finding | A compromised remote host may be able to use the forwarded agent during the session. |
LocalForward or RemoteForward bound to 0.0.0.0 or * |
Medium security finding | The tunnel may listen beyond loopback or a deliberately restricted address. |
Directive Coverage:
Directive insights count how consistently a setting appears across Host blocks. The missing count is a simple coverage check:
A high missing count is not automatically wrong. For example, only hosts behind a bastion may need ProxyJump, and only hosts that use a non-default account may need User. It is most useful for spotting accidental gaps in policies that should be consistent, such as identity files, host-key settings, or timeout defaults.
Privacy and Limits:
SSH configs can reveal hostnames, internal domains, usernames, bastion names, local paths, and tunnel addresses. The editor parses the pasted or dropped config text in the browser and does not need a server-side lookup to produce the generated config or reports. Use the same care you would use with any sensitive admin text on a shared browser or managed machine.
The review is limited to the visible text you provide. It does not read files named by Include, apply system-wide config, run ssh, contact hosts, verify private keys, confirm DNS, or prove that a jump host is reachable. Use the generated output as a review aid, then test the affected aliases in your normal SSH environment before replacing a working config.
Worked Examples:
Clean a personal config
Paste the current config, group by domain suffix, and filter for IdentityFile. If several production hosts lack an explicit key while similar hosts include one, add or correct those rows, then compare the diff before copying the generated config.
Check a wildcard with an exception
For a pattern such as *.internal !db.internal, enter app.internal and then db.internal in the match tester. The app host should match while the database host should be excluded by the negated token.
Review a jump-host migration
Filter for ProxyJump, inspect which hosts still use the old bastion, and check the security review for agent forwarding or missing identity files. Directive insights can show whether the new jump setting is present on every host that should use it.
Troubleshoot a suspicious diff
If the diff changes more lines than expected after sorting or normalization, turn off one advanced option at a time and compare again. Pay special attention to repeated keys, because duplicate removal keeps only the last value in a Host block.
FAQ:
Does this edit my actual ~/.ssh/config file?
No. It generates text for you to review, copy, or download. Replace your real config only after checking the lint, security, and diff results.
Why does Host * usually belong near the end?
OpenSSH usually uses the first value it obtains for a parameter. A broad default near the top can set a value before a later Host block has a chance to provide a more specific one.
Are all security findings mistakes?
No. A lab, migration, or emergency repair may deliberately use a risky setting. The finding means the setting is worth checking before it becomes a permanent default.
Why does a pasted config lose some comments or blank lines?
The editor focuses on editable Host blocks and directive rows. Turn on preserved non-Host lines when you need top comments, Include lines, Match lines, and other visible non-Host text carried into the generated output.
Can included files change the final SSH behavior?
Yes. Include and Match rules can depend on files, hostnames, users, commands, networks, and SSH version behavior outside the pasted text. Review the generated config in the context of the full client setup.
Glossary:
- Host block
- A client config section that applies to aliases or patterns listed after a
Hostkeyword. - Directive
- A keyword and value pair, such as
User deployorPort 2222, that changes client behavior for a matched host. - HostName
- The real destination name or address used after a short alias has matched.
- ProxyJump
- A directive that routes a connection through one or more jump hosts before reaching the final target.
- StrictHostKeyChecking
- A directive that controls how the client handles new or changed server host keys.
- Match
- A conditional section that applies settings only when criteria such as host, user, command, or network conditions are satisfied.