vps-security-hardening skill
Audit and harden VPS security — fail2ban, SSH hardening, firewall setup
Is the vps-security-hardening skill safe?
Read the findings before you install it. We read 2 files in the folder on 2026-09-28.
- high
SKILL.md:33Reads credential files (SSH keys, cloud or package-manager tokens) that a skill has no normal reason to touch.
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N '' -C "user@machine" - medium
SKILL.md:131Edits shell startup files, cron or launch agents, so something runs again after the skill is done.
sudo systemctl enable fail2ban
Install the vps-security-hardening skill
A skill is a folder. Copy it into your agent's skills folder and the agent loads it when the task matches its description.
git clone --depth 1 https://github.com/kevinnft/ai-agent-skills.git /tmp/ai-agent-skills mkdir -p ~/.claude/skills cp -r /tmp/ai-agent-skills/skills/devops/vps-security-hardening ~/.claude/skills/vps-security-hardening
In the Claude apps, zip the folder and upload it from the Skills settings. The folder on GitHub
The instructions your agent would load
SKILL.md as published, without the frontmatter. Read it on GitHub
VPS Security Hardening
Audit and harden VPS security with fail2ban (brute-force protection), SSH hardening, and optional firewall setup.
When to Use
- New VPS setup (initial hardening)
- Security audit requested
- SSH brute-force attacks detected
- User wants to "secure VPS" or "protect server"
Prerequisites: Establishing SSH Access
Before hardening, ensure you can SSH into the VPS.
If Password Auth is Disabled (PublicKey only)
VPS providers often disable password auth by default. You need to add your SSH key first.
Option 1: Via VPS Web Console (Recommended)
- Generate SSH key locally (if not exists):
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N '' -C "user@machine"
cat ~/.ssh/id_ed25519.pub- Login to VPS via web console (provider dashboard → Console/Terminal)
- Add public key to VPS:
mkdir -p ~/.ssh
echo "ssh-ed25519 AAAA... user@machine" >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys- Test from local machine:
ssh root@VPS_IPOption 2: Via Provider Dashboard
Most providers (DigitalOcean, Vultr, Biznet, etc.) have "Add SSH Key" in dashboard:
- Copy public key (cat ~/.ssh/id_ed25519.pub)
- Paste into provider's SSH key management
- Rebuild/restart VPS (some providers require this)
Option 3: Enable Password Auth Temporarily
Only if web console is unavailable:
- Login via web console
- Edit SSH config:
echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config.d/99-temp-password.conf
systemctl reload sshd- SSH in with password, add your key
- Remove temp config:
rm /etc/ssh/sshd_config.d/99-temp-password.conf
systemctl reload sshdCommon Pitfall: sshpass with PublicKey-Only VPS
Problem: sshpass -p 'password' ssh user@host fails with "Permission denied (publickey)" even with correct password.
Why: VPS has PasswordAuthentication no in sshd_config — password auth is disabled at server level.
Solution: Use web console to add SSH key first (see Option 1 above).
Workflow
Phase 1: Security Audit
- Check running processes
ps aux --sort=-%mem | head -20
systemctl list-units --type=service --state=running- Check listening ports
sudo ss -tulpn
sudo netstat -tulpn- Check for rootkits/malware
# Hidden processes
ps aux | wc -l
ls /proc | grep -E '^[0-9]+$' | wc -l
# Recent failed logins
sudo grep "Failed password" /var/log/auth.log | tail -20- Check user accounts
cat /etc/passwd | grep -E '/bin/(bash|sh)$'
sudo lastlog- Resource usage
free -h
df -h
uptimePhase 2: Install fail2ban
# Install
sudo apt-get update
sudo apt-get install -y fail2ban
# Enable and start
sudo systemctl enable fail2ban
sudo systemctl start fail2banPhase 3: Configure fail2ban
Create /etc/fail2ban/jail.local:
[DEFAULT]
bantime = 3600 # Ban for 1 hour
findtime = 600 # Count failures in last 10 minutes
maxretry = 5 # Ban after 5 failures
[sshd]
enabled = true
port = 22
logpath = /var/log/auth.log
maxretry = 5Restart:
sudo systemctl restart fail2ban
sudo fail2ban-client status sshdPhase 4: SSH Hardening
Create /etc/ssh/sshd_config.d/99-hardening.conf:
# Disable root login
PermitRootLogin no
# Enable public key auth
PubkeyAuthentication yes
# Disable empty passwords
PermitEmptyPasswords no
# Limit auth attempts
MaxAuthTries 3
# Disable X11 forwarding
X11Forwarding no
# Disable TCP forwarding
AllowTcpForwarding no
# Disable agent forwarding
AllowAgentForwarding no
# Set login grace time
LoginGraceTime 30
# Limit sessions
MaxSessions 2
# Strong ciphers only
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
# Strong MACs only
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
# Strong key exchange
KexAlgorithms curve25519-sha256,diffie-hellman-group-exchange-sha256Test and reload:
sudo sshd -t
sudo systemctl reload sshdPhase 5: Verify
# fail2ban status
sudo fail2ban-client status sshd
# SSH config
sudo sshd -T | grep -E '(permitrootlogin|maxauthtries|x11forwarding)'
# Check banned IPs
sudo fail2ban-client get sshd banipImportant: Password vs SSH Key Decision
DO NOT automatically disable password authentication!
Check First
# Check if user has SSH keys
cat ~/.ssh/authorized_keys
# Check how user is currently connected
sudo grep "Accepted" /var/log/auth.log | tail -5Decision Logic
More skills from kevinnft/ai-agent-skills
- Aaddyosmani-tddDrives development with tests. Use when implementing any logic, fixing any bug, or changing any behavior. Use when you need to prove that code works, when a bug report arrives, or when you're about to modify existing functionality.
- AairtableAirtable REST API via curl. Records CRUD, filters, upserts.
- Aapi-and-interface-designGuides stable API and interface design. Use when designing APIs, module boundaries, or any public interface. Use when creating REST or GraphQL endpoints, defining type contracts between modules, or establishing boundaries between frontend and backend.
- Aapi-monitoring-botsBuild monitoring bots that poll APIs and send notifications on state changes (new listings, price alerts, status updates)
- Aapple-notesManage Apple Notes via memo CLI: create, search, edit.
- Aapple-remindersApple Reminders via remindctl: add, list, complete.
- Aarchitecture-diagramDark-themed SVG architecture/cloud/infra diagrams as HTML.
- AarxivSearch arXiv papers by keyword, author, category, or ID.
- Aascii-artASCII art: pyfiglet, cowsay, boxes, image-to-ascii.
- Aascii-videoASCII video: convert video/audio to colored ASCII MP4/GIF.
- AaudiocraftAudioCraft: MusicGen text-to-music, AudioGen text-to-sound.
- CaxolotlAxolotl: YAML LLM fine-tuning (LoRA, DPO, GRPO).