Skip to content
ohsudo, Home

SSH Config Generator

A tidy ~/.ssh/config with hosts, keys and jump hosts.

● Runs 100% in your browser — nothing you type leaves this page.

Hosts

bastion

What you type: ssh <alias>

An alias above, or user@host:port. Empty = connect directly.

web01

What you type: ssh <alias>

An alias above, or user@host:port. Empty = connect directly.

For every host (Host *)
~/.ssh/config
# Generated by OhSudo — https://ohsudo.com/tools/ssh-config-generator/
# ssh uses the first value it finds for each option: specific hosts first, Host * last.
Host bastion
HostName bastion.example.com
User deploy
IdentityFile ~/.ssh/id_ed25519
Host web01
HostName 10.0.1.21
User deploy
IdentityFile ~/.ssh/id_ed25519
# Connect through this host first (it must be reachable from here)
ProxyJump bastion
# Defaults for every host
Host *
# Offer only the key set above, not every key in the agent (avoids "Too many authentication failures")
IdentitiesOnly yes
# Ask for the key passphrase once, then keep the key in the agent
AddKeysToAgent yes
# Send a keepalive every 60 s; give up after 3 missed answers
ServerAliveInterval 60
ServerAliveCountMax 3

Install it

$ mkdir -p ~/.ssh && chmod 700 ~/.ssh
$ nano ~/.ssh/config
$ chmod 600 ~/.ssh/config
$ ssh -G web01 | grep -E '^(hostname|user|port|identityfile|proxyjump) '
$ ssh web01

Linux and macOS. On Windows the file is %USERPROFILE%\.ssh\config. ssh -G shows what ssh will really use for a host, without connecting.

The address bar updates as you go, so you can bookmark or share the result.

How to use it

  1. Add a host for every server you connect to. The alias is what you’ll type: ssh web01 instead of ssh -i ~/.ssh/work_key -p 2222 deploy@203.0.113.21.
  2. Fill in the address, the user and — if it isn’t 22 — the port. Point IdentityFile at the private key (no .pub).
  3. For servers you can only reach through a bastion, put the bastion’s alias in Jump through. ssh web01 then hops through it on its own.
  4. Save the result as ~/.ssh/config (mode 600) and check it with ssh -G <alias>.

What you get

Every option the generator writes is checked with a real OpenSSH client (ssh -G) for every combination of settings.

Common commands

Terminal window
ssh -G web01 | grep -E '^(hostname|user|port|identityfile|proxyjump) ' # what ssh will really use
ssh -v web01 # watch the connection, key by key
ssh -J bastion deploy@10.0.1.21 # one-off jump, without a config
scp ./app.tar.gz web01:/tmp/ # scp, rsync and git use the same aliases
rsync -avz ./site/ web01:/var/www/site/
ssh-copy-id -i ~/.ssh/id_ed25519.pub web01 # install your public key on the server

Warning

Agent forwarding is not needed for jump hosts. With ProxyJump your keys never leave your machine. ForwardAgent yes lets anyone with root on that server use your keys while you’re connected, so turn it on only for servers you trust, and only when you need your keys on the server (for example git pull from a private repo).

FAQ

Why is my setting ignored?

Because an earlier block already set it. For every option, ssh keeps the first value it reads — from the command line, then ~/.ssh/config top to bottom, then /etc/ssh/ssh_config. A Host * block at the top of the file wins over everything below it. ssh -G <alias> shows the values ssh will actually use.

Permission denied (publickey) after adding the config?

Check that IdentityFile points to the private key, that the matching .pub is in ~/.ssh/authorized_keys on the server, and the permissions on both sides. The full checklist is in SSH Permission denied (publickey). If ssh says the host key changed instead, see REMOTE HOST IDENTIFICATION HAS CHANGED.

Does Ansible use this file?

Yes. Ansible connects with OpenSSH by default, so aliases, users, keys and ProxyJump from ~/.ssh/config apply to its connections too — unless the inventory sets them (ansible_user, ansible_port…), which wins. If a host is UNREACHABLE, test it first with plain ssh <alias> — see Ansible UNREACHABLE.

Where is the file on Windows?

The OpenSSH client built into Windows 10 and 11 reads %USERPROFILE%\.ssh\config (for example C:\Users\you\.ssh\config), with the same syntax.

How do I keep work running if SSH drops?

Run it inside tmux: see the tmux Cheat Sheet.

Articles

Learn more

Missing sudo password
Infrastructure as Code

Ansible "Missing sudo password": give it the password safely, or allow the user properly

Fix Ansible "Missing sudo password": use --ask-become-pass, ansible-vault for the become password, or NOPASSWD in sudoers, plus "Incorrect sudo password" and timeouts.

Beginner · 4 min read

Too many authentication failures
Linux

SSH "Too many authentication failures": your agent offers too many keys

Fix SSH "Received disconnect … Too many authentication failures": the agent offers every key before the right one. Use IdentitiesOnly and IdentityFile.

Beginner · 4 min read

UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh
Infrastructure as Code

Ansible "UNREACHABLE! Failed to connect to the host via ssh": find the real SSH error

Fix Ansible UNREACHABLE: read the SSH error in the message, check the inventory, reproduce with -vvv and plain ssh, then fix keys, users or host keys.

Beginner · 4 min read

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
Security

SSH "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!": check it, then fix known_hosts

Fix the SSH host key warning safely: find out why the key changed, verify the new fingerprint on the server, then remove the old key with ssh-keygen -R.

Beginner · 3 min read

Permission denied (publickey)
Linux

SSH "Permission denied (publickey)": how to find the real cause

Fix SSH "Permission denied (publickey)": read the server log, fix ~/.ssh permissions, check the key and sshd_config, and handle SELinux on RHEL.

Intermediate · 4 min read