SSH Hardening Skill
Secure SSH access to VPS servers by implementing industry-standard hardening practices.
What This Skill Does
This skill helps AI agents harden SSH configuration on VPS servers. SSH is the primary entry point for server management, making it a critical attack vector. Proper SSH hardening prevents unauthorized access, brute-force attacks, and credential theft.
Key capabilities:
-
Create non-root users with sudo privileges
-
Generate and configure SSH key authentication
-
Disable password-based authentication
-
Disable root login over SSH
-
Configure security settings in sshd_config
-
Test configuration before applying
When to Use
Use this skill when you need to:
-
Set up a new VPS server with secure SSH access
-
Replace password authentication with SSH keys
-
Disable root login for security compliance
-
Harden an existing server against brute-force attacks
-
Fix security audit findings related to SSH
-
Implement principle of least privilege
Critical understanding: Root can do anything. One typo, one compromised session, and your entire system is gone. Passwords can be guessed. SSH keys can't be brute-forced in any practical timeframe.
Prerequisites
-
Root or existing sudo user access to the server
-
SSH access to the server (keep current session open!)
-
SSH client on local machine (ssh, ssh-keygen, ssh-copy-id)
-
Terminal access to local machine
SSH Hardening Steps
Step 1: Create Non-Root User
CRITICAL: Complete this step and test before disabling root login!
Create a new user for daily operations:
Create user (replace 'deployer' with desired username)
sudo adduser deployer
Enter a strong password when prompted.
Add user to sudo group:
sudo usermod -aG sudo deployer
Test sudo access before proceeding:
Switch to new user
su - deployer
Test sudo
sudo whoami
Should output: root
Exit back to original user
exit
Step 2: Generate SSH Key Pair (Local Machine)
On your local machine (not the server), generate an SSH key:
ssh-keygen -t ed25519 -C "your-email@example.com"
Key type explained:
-
ed25519
-
Modern, secure, fast (recommended)
-
Alternative: rsa -b 4096 for older systems
When prompted:
-
Press Enter to save to default location (~/.ssh/id_ed25519 )
-
Enter a strong passphrase (recommended) or leave empty
Step 3: Copy SSH Key to Server
From your local machine, copy the public key to the server:
ssh-copy-id deployer@your-server-ip
Enter the user's password when prompted.
Manual alternative (if ssh-copy-id is unavailable):
On local machine, display public key
cat ~/.ssh/id_ed25519.pub
On server, as the new user
mkdir -p ~/.ssh chmod 700 ~/.ssh nano ~/.ssh/authorized_keys
Paste the public key, save and exit
chmod 600 ~/.ssh/authorized_keys
Step 4: Test SSH Key Authentication
CRITICAL: Test in a NEW terminal window, keep existing session open!
ssh deployer@your-server-ip
You should connect without entering a password (or only your SSH key passphrase).
If connection fails, DO NOT proceed to Step 5! Debug the issue first.
Step 5: Harden SSH Configuration
WARNING: Make these changes carefully. Test in a new terminal before closing existing sessions!
Edit SSH daemon configuration:
sudo nano /etc/ssh/sshd_config
Update or add these settings:
Disable root login
PermitRootLogin no
Disable password authentication
PasswordAuthentication no
Disable empty passwords
PermitEmptyPasswords no
Limit authentication attempts
MaxAuthTries 3
Allow only specific users (optional but recommended)
AllowUsers deployer
Use only SSH protocol 2
Protocol 2
Disable X11 forwarding (unless needed)
X11Forwarding no
Set login grace time
LoginGraceTime 60
Disable host-based authentication
HostbasedAuthentication no
Optional advanced settings:
Change default port (security through obscurity, optional)
Port 2222
Disable agent forwarding (unless needed)
AllowAgentForwarding no
Disable TCP forwarding (unless needed)
AllowTcpForwarding no
Set idle timeout
ClientAliveInterval 300
ClientAliveCountMax 2
Step 6: Test Configuration
Test the configuration file for syntax errors:
sudo sshd -t
No output means the configuration is valid.
Step 7: Restart SSH Service
CRITICAL: Test in a new terminal BEFORE restarting!
Test connection in NEW terminal first
ssh deployer@your-server-ip
If successful, restart SSH (in original terminal)
sudo systemctl restart sshd
Verification:
sudo systemctl status sshd
Step 8: Verify Root Login is Disabled
Try to connect as root (should fail):
ssh root@your-server-ip
Expected result: Permission denied (publickey)
Configuration Reference
AllowUsers vs AllowGroups
Restrict SSH access to specific users or groups:
Option 1: Specific users
AllowUsers deployer admin
Option 2: Users in specific group
AllowGroups sshusers
Port Changes
Changing the default SSH port (22) reduces noise from automated scanners:
Port 2222
Remember to:
-
Update firewall rules before restarting SSH
-
Use the new port when connecting: ssh -p 2222 user@host
Key-Based Authentication Only
Ensure these settings work together:
PubkeyAuthentication yes PasswordAuthentication no ChallengeResponseAuthentication no UsePAM yes
Security Best Practices
-
Always test before closing sessions - Keep one session open until verified
-
Use SSH key passphrases - Adds another layer of security
-
Limit user access - Use AllowUsers or AllowGroups
-
Monitor authentication logs - Check /var/log/auth.log regularly
-
Use fail2ban - Add automated banning for repeated failed attempts
-
Regular key rotation - Periodically generate new keys
-
Disable unused features - X11Forwarding, TCP forwarding, etc.
Troubleshooting
Locked Out of Server
Prevention is key:
-
Always keep one session open when making changes
-
Test in a new terminal before closing existing sessions
-
Have console access via hosting provider's control panel
Recovery:
-
Use hosting provider's console/VNC access
-
Revert changes to /etc/ssh/sshd_config
-
Restart sshd service
SSH Key Not Working
Check file permissions on server
ls -la ~/.ssh/
Should show:
drwx------ .ssh/
-rw------- authorized_keys
Fix permissions if needed
chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys
Check SSH logs
sudo tail -f /var/log/auth.log
Connection Refused After Changes
Check SSH service status
sudo systemctl status sshd
View recent errors
sudo journalctl -u sshd -n 50
Test configuration
sudo sshd -t
Common Mistakes to Avoid
-
❌ Closing all SSH sessions before testing new configuration
-
❌ Disabling password auth before setting up SSH keys
-
❌ Not testing sudo access for new user
-
❌ Typos in sshd_config causing service failure
-
❌ Forgetting to restart sshd after changes
-
❌ Not updating firewall when changing SSH port
Additional Resources
See references/sshd-config.md for complete sshd_config reference.
See scripts/setup-ssh-hardening.sh for automated setup script.
Related Skills
-
firewall-configuration
-
Restrict SSH port access
-
fail2ban-setup
-
Auto-ban brute-force attempts
-
auto-updates
-
Keep SSH patched against vulnerabilities