| name | ssh-configuration |
| description | Configure SSH servers and clients securely. Manage keys, tunnels, and config files. Use when setting up secure remote access. |
| license | MIT |
| metadata | {"author":"devops-skills","version":"1.0"} |
SSH Configuration
Secure SSH server and client configuration for production environments, including key management, hardened sshd settings, bastion host architecture, tunneling, and multiplexing.
When to Use
- Setting up secure remote access to Linux or Unix servers
- Hardening SSH daemon configuration to meet compliance requirements
- Configuring bastion / jump hosts for private network access
- Creating SSH tunnels for secure port forwarding
- Managing SSH keys for teams or automated deployments
- Troubleshooting connection, authentication, or performance issues
Prerequisites
- OpenSSH client installed locally (
ssh -V to verify)
- OpenSSH server installed on target (
sshd)
- Root or sudo access on the server for sshd_config changes
- Firewall rules allowing TCP port 22 (or custom SSH port)
Key Generation and Management
ssh-keygen -t ed25519 -C "jane@example.com" -f ~/.ssh/id_ed25519
ssh-keygen -t rsa -b 4096 -C "jane@example.com" -f ~/.ssh/id_rsa_legacy
ssh-keygen -t ed25519 -C "ci-deploy-key" -f ~/.ssh/ci_deploy -N ""
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
ssh-add -l
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-add -t 28800 ~/.ssh/id_ed25519
ssh-add -D
ssh-keygen -p -m PEM -f ~/.ssh/id_rsa_legacy
ssh-keygen -lf ~/.ssh/id_ed25519.pub
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_new -C "jane@example.com rotated $(date +%Y-%m)"
ssh-copy-id -i ~/.ssh/id_ed25519_new.pub user@server
SSH Client Configuration (~/.ssh/config)
# Global defaults applied to all hosts
Host *
AddKeysToAgent yes
IdentitiesOnly yes
ServerAliveInterval 60
ServerAliveCountMax 3
TCPKeepAlive yes
Compression yes
# Production servers via bastion
Host bastion
HostName bastion.example.com
User ops
IdentityFile ~/.ssh/id_ed25519
Port 22
Host prod-web-*
User deploy
IdentityFile ~/.ssh/id_ed25519
ProxyJump bastion
Port 22
Host prod-web-1
HostName 10.0.1.10
Host prod-web-2
HostName 10.0.1.11
# Staging accessed directly
Host staging
HostName staging.example.com
User deploy
IdentityFile ~/.ssh/id_ed25519_staging
# Database tunnel through bastion
Host db-tunnel
HostName 10.0.2.50
User dba
ProxyJump bastion
LocalForward 5432 localhost:5432
# GitHub deploy key
Host github-deploy
HostName github.com
User git
IdentityFile ~/.ssh/github_deploy_key
IdentitiesOnly yes
# Connection multiplexing for faster repeated connections
Host fast-*
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
mkdir -p ~/.ssh/sockets
chmod 700 ~/.ssh/sockets
Hardened Server Configuration (/etc/ssh/sshd_config)
Port 22
Protocol 2
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
MaxAuthTries 3
MaxSessions 5
LoginGraceTime 30
AllowGroups ssh-users ops-team
ChallengeResponseAuthentication no
KerberosAuthentication no
GSSAPIAuthentication no
AllowTcpForwarding yes
AllowAgentForwarding no
X11Forwarding no
PermitTunnel no
ClientAliveInterval 300
ClientAliveCountMax 2
UsePAM yes
UseDNS no
PermitEmptyPasswords no
PermitUserEnvironment no
SyslogFacility AUTH
LogLevel VERBOSE
Subsystem sftp /usr/lib/openssh/sftp-server -f AUTH -l INFO
Match User sftponly
ForceCommand internal-sftp
ChrootDirectory /home/%u
AllowTcpForwarding no
AllowAgentForwarding no
X11Forwarding no
sshd -t
systemctl restart sshd
Bastion Host Setup
AllowTcpForwarding yes
PermitOpen 10.0.0.0/8:22 10.0.0.0/8:5432
Match User jump-user
PermitTTY no
ForceCommand /usr/sbin/nologin
AllowTcpForwarding yes
ssh -J ops@bastion.example.com deploy@10.0.1.10
ssh -o ProxyCommand="ssh -W %h:%p ops@bastion.example.com" deploy@10.0.1.10
ssh -J ops@bastion,deploy@10.0.1.10 dba@10.0.2.50
SSH Tunneling
ssh -L 5432:10.0.2.50:5432 ops@bastion.example.com -N
ssh -R 8080:localhost:3000 user@server -N
ssh -D 1080 user@server -N
ssh -fN -L 5432:10.0.2.50:5432 ops@bastion.example.com
ps aux | grep "ssh -fN" | grep -v grep
kill <pid>
autossh -M 0 -f -N -L 5432:10.0.2.50:5432 ops@bastion.example.com \
-o "ServerAliveInterval=30" -o "ServerAliveCountMax=3"
Agent Forwarding (Use with Caution)
ssh -A user@bastion
ssh deploy@10.0.1.10
ssh -J ops@bastion deploy@10.0.1.10
SSH Key Restrictions in authorized_keys
# Restrict a key to a specific command only (backup key)
command="/usr/local/bin/run-backup.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAA... backup@example.com
# Restrict a key to specific source IPs
from="10.0.0.0/24,192.168.1.0/24" ssh-ed25519 AAAA... admin@example.com
# Read-only SFTP key with chroot
command="internal-sftp",no-port-forwarding,no-pty ssh-ed25519 AAAA... sftp-upload@example.com
Troubleshooting
| Symptom | Diagnostic Command | Common Fix |
|---|
| Connection refused | ss -tlnp | grep 22 on server | Ensure sshd is running; check firewall rules |
| Permission denied (publickey) | ssh -vvv user@server | Verify key is in authorized_keys, permissions 600/700 |
| Host key verification failed | ssh-keygen -R server | Remove stale host key; verify server identity |
| Connection timeout | ssh -o ConnectTimeout=5 user@server | Check network path, security groups, NACLs |
| Slow SSH login | Check UseDNS in sshd_config | Set UseDNS no; check reverse DNS |
| Broken pipe / dropped sessions | Add ServerAliveInterval 60 to config | Configure keepalive on both client and server |
| Agent forwarding not working | ssh-add -l on bastion | Ensure -A flag used and agent has keys loaded |
| Tunnel port already in use | ss -tlnp | grep <port> | Kill existing tunnel or use a different local port |
Related Skills
linux-administration -- General Linux system administration
user-management -- Managing the users who connect via SSH
systemd-services -- Managing sshd as a systemd service
performance-tuning -- Network tuning for SSH performance