--- title: SSH Config and Key Management domain: linux category: networking tags: - ssh - keys - security - linux - remote-access status: published created: 2026-03-08 updated: 2026-04-07T21:55 --- # SSH Config and Key Management SSH is how you get into remote servers. Key-based authentication is safer than passwords and, once set up, faster too. The `~/.ssh/config` file is what turns SSH from something you type long commands for into something that actually works the way you want. ## The Short Answer ```bash # Generate a key (use ed25519 — it's faster and more secure than RSA now) ssh-keygen -t ed25519 -C "yourname@hostname" # Copy the public key to a server ssh-copy-id user@server-ip # SSH using a specific key ssh -i ~/.ssh/id_ed25519 user@server-ip ``` ## Key Generation ```bash # ed25519 — preferred ssh-keygen -t ed25519 -C "home-laptop" # RSA 4096 — use this if the server is old and doesn't support ed25519 ssh-keygen -t rsa -b 4096 -C "home-laptop" ``` The `-C` comment is just a label — use something that tells you which machine the key came from. Comes in handy when you look at `authorized_keys` on a server and need to know what's what. Keys land in `~/.ssh/`: - `id_ed25519` — private key. **Never share this.** - `id_ed25519.pub` — public key. This is what you put on servers. ## Copying Your Key to a Server ```bash # Easiest way ssh-copy-id user@server-ip # If the server is on a non-standard port ssh-copy-id -p 2222 user@server-ip # Manual way (if ssh-copy-id isn't available) cat ~/.ssh/id_ed25519.pub | ssh user@server-ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys" ``` After copying, test that key auth works before doing anything else, especially before disabling password auth. ## SSH Config File `~/.ssh/config` lets you define aliases for servers so you can type `ssh myserver` instead of `ssh -i ~/.ssh/id_ed25519 -p 2222 admin@192.168.1.50`. ``` # ~/.ssh/config # Home server Host homelab HostName 192.168.1.50 User admin IdentityFile ~/.ssh/id_ed25519 Port 22 # Remote VPS Host vps HostName vps.yourdomain.com User ubuntu IdentityFile ~/.ssh/vps_key Port 2222 # Jump host pattern — SSH through a bastion to reach internal servers Host internal-server HostName 10.0.0.50 User admin ProxyJump bastion.yourdomain.com # Default settings for all hosts Host * ServerAliveInterval 60 ServerAliveCountMax 3 IdentityFile ~/.ssh/id_ed25519 ``` After saving, `ssh homelab` connects with all those settings automatically. ## Managing Multiple Keys One key per machine you connect from is reasonable. One key per server you connect to is overkill for personal use but correct for anything sensitive. ```bash # List keys loaded in the SSH agent ssh-add -l # Add a key to the agent (so you don't type the passphrase every time) ssh-add ~/.ssh/id_ed25519 # On macOS, persist the key in Keychain ssh-add --apple-use-keychain ~/.ssh/id_ed25519 ``` The SSH agent stores decrypted keys in memory for the session. You enter the passphrase once and the agent handles authentication for the rest of the session. ## Server-Side: Authorized Keys Public keys live in `~/.ssh/authorized_keys` on the server. One key per line. ```bash # Check permissions — wrong permissions break SSH key auth silently chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys ``` If key auth isn't working and the config looks right, permissions are the first thing to check. ## Gotchas & Notes - **Permissions must be right.** SSH ignores `authorized_keys` if the file or directory is world-writable. `chmod 700 ~/.ssh` and `chmod 600 ~/.ssh/authorized_keys` are required. - **ed25519 over RSA.** ed25519 keys are shorter, faster, and currently considered more secure. Use them unless you have a compatibility reason not to. - **Add a passphrase to your private key.** If your machine is compromised, an unprotected private key gives the attacker access to everything it's authorized on. A passphrase mitigates that. - **`ServerAliveInterval` in your config** keeps connections from timing out on idle sessions. Saves you from the annoyance of reconnecting after stepping away. - **Never put private keys in cloud storage, Git repos, or Docker images.** It happens more than you'd think. ## Windows OpenSSH: Admin User Key Auth Windows OpenSSH has a separate key file for users in the `Administrators` group. Regular `~/.ssh/authorized_keys` is **ignored** for admin users unless the `Match Group administrators` block in `sshd_config` is disabled. ### Where keys go | User type | Key file | |---|---| | Regular user | `C:\Users\\.ssh\authorized_keys` | | Admin user | `C:\ProgramData\ssh\administrators_authorized_keys` | ### Setup (elevated PowerShell) 1. **Enable the Match block** in `C:\ProgramData\ssh\sshd_config` — both lines must be uncommented: ``` Match Group administrators AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys ``` 2. **Write the key file without BOM** — PowerShell 5 defaults to UTF-16LE or UTF-8 with BOM, both of which OpenSSH silently rejects: ```powershell [System.IO.File]::WriteAllText( "C:\ProgramData\ssh\administrators_authorized_keys", "ssh-ed25519 AAAA... user@hostname`n", [System.Text.UTF8Encoding]::new($false) ) ``` 3. **Lock down permissions** — OpenSSH requires strict ACLs: ```powershell icacls "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "SYSTEM:(F)" /grant "Administrators:(F)" ``` 4. **Restart sshd:** ```powershell Restart-Service sshd ``` ### Troubleshooting - If key auth silently fails, check `Get-WinEvent -LogName OpenSSH/Operational -MaxEvents 10` - Common cause: BOM in the key file or `sshd_config` — PowerShell file-writing commands are the usual culprit - If the log says `User not allowed because shell does not exist`, the `DefaultShell` registry path is wrong — see [WSL default shell troubleshooting](../../05-troubleshooting/networking/windows-openssh-wsl-default-shell-breaks-remote-commands.md) ## See Also - [linux-server-hardening-checklist](../../02-selfhosting/security/linux-server-hardening-checklist.md) - [managing-linux-services-systemd-ansible](../process-management/managing-linux-services-systemd-ansible.md)