Claude
Skills
Sign in
Back

ssh-hardening

Included with Lifetime
$97 forever

Harden SSH configuration on VPS servers by disabling root login, enforcing SSH key authentication, and creating non-root sudo users to prevent unauthorized access.

Generalscripts

What this skill does


# 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:

```bash
# Create user (replace 'deployer' with desired username)
sudo adduser deployer
```

Enter a strong password when prompted.

Add user to sudo group:

```bash
sudo usermod -aG sudo deployer
```

**Test sudo access** before proceeding:

```bash
# 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:

```bash
ssh-keygen -t ed25519 -C "[email protected]"
```

**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:

```bash
ssh-copy-id deployer@your-server-ip
```

Enter the user's password when prompted.

**Manual alternative** (if ssh-copy-id is unavailable):

```bash
# 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!

```bash
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:

```bash
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:

```bash
sudo sshd -t
```

No output means the configuration is valid.

### Step 7: Restart SSH Service

**CRITICAL:** Test in a new terminal BEFORE restarting!

```bash
# Test connection in NEW terminal first
ssh deployer@your-server-ip

# If successful, restart SSH (in original terminal)
sudo systemctl restart sshd
```

**Verification:**

```bash
sudo systemctl status sshd
```

### Step 8: Verify Root Login is Disabled

Try to connect as root (should fail):

```bash
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:**

1. Update firewall rules before restarting SSH
2. 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

1. **Always test before closing sessions** - Keep one session open until verified
2. **Use SSH key passphrases** - Adds another layer of security
3. **Limit user access** - Use AllowUsers or AllowGroups
4. **Monitor authentication logs** - Check `/var/log/auth.log` regularly
5. **Use fail2ban** - Add automated banning for repeated failed attempts
6. **Regular key rotation** - Periodically generate new keys
7. **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

```bash
# 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

```bash
# 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](references/sshd-config.md) for complete sshd_config reference.

See [scripts/setup-ssh-hardening.sh](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

Related in General