Files
MajorWiki/01-linux/networking/ssh-config-key-management.md
majorlinux 5af934a6c6 wiki: update SSH docs with bash.exe default shell fix and Windows admin key auth
- ssh-config-key-management: add Windows OpenSSH admin user key auth section
  (administrators_authorized_keys, BOM-free writing, ACL requirements)
- windows-openssh-wsl-default-shell: add bash.exe as recommended fix (Option 1),
  demote PowerShell to Option 2, add shell-not-found diagnostic tip
- windows-sshd-stops-after-reboot: fix stale wsl.exe reference to bash.exe
- index/README: update Recently Updated table and article descriptions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 22:01:36 -04:00

185 lines
6.2 KiB
Markdown

---
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\<user>\.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)