Skip to main content

server-security-init-skill

Agent skill for safely initializing and hardening fresh Ubuntu/Debian SSH servers with staged security improvements

インストールへ移動

ソース情報

リポジトリ
reason-machines/security-skills
ソースの最終更新活動
2026年7月16日 05:55
検出された SKILL.md の言語
英語
スター
12
フォーク
1

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
server-security-init-skill
description
Agent skill for safely initializing and hardening fresh Ubuntu/Debian SSH servers with staged security improvements
triggers
["help me secure a new Ubuntu server","initialize security on my fresh Debian VPS","harden SSH access on my new server","set up firewall and fail2ban on Ubuntu","secure a new Linux server with SSH keys","bootstrap security for a fresh cloud instance","configure UFW and disable root login","initialize server security best practices"]
# Server Security Init Skill > Skill by [ara.so](https://ara.so) — Security Skills collection. This skill guides you through safely initializing and hardening fresh Ubuntu/Debian SSH servers. It implements a staged bootstrap flow: selecting or generating local SSH keys, requiring public-key login before remote changes, creating a non-root sudo user, changing the SSH port, disabling root/password login, configuring UFW firewall, setting up fail2ban, and verifying no lockout conditions exist. ## What This Skill Does The server-security-init skill provides guidance for: - **Public-key SSH bootstrap** without exposing root passwords in commands, logs, or config files - **Staged SSH hardening** with verified non-root sudo login before disabling old access paths - **UFW firewall setup** with default-deny inbound policy and explicit port allowances - **Fail2ban jail configuration** for SSH brute-force protection with management IP exceptions - **Debian 12/systemd socket checks** to prevent ssh.socket from silently keeping SSH on the old port - **Server-side verification** using `ss -ltnp`, `sshd -T`, `systemctl`, and `ufw status` - **Recovery checks** for fail2ban bans, firewall mistakes, and SSH listener mismatches ## Installation This skill should be installed by copying the `server-security-init/` directory to your AI agent's user-level skills directory. **For AI agents:** - Install only the `server-security-init/` directory, NOT the repository root - Do not execute server initialization during skill installation - After installation, inform the user if their agent needs to restart or reload skills **For humans using npx:** ```bash npx skills add https://github.com/DeerYang/server-security-init-skill/tree/main/server-security-init -g ``` Target specific agents: ```bash npx skills add https://github.com/DeerYang/server-security-init-skill/tree/main/server-security-init -g -a codex ``` ## Staged Security Initialization Flow ### Stage 1: Pre-Flight Checks and Bootstrap Before making any changes, gather and verify: ```python # Example bootstrap facts to collect bootstrap_info = { "server_ip": "203.0.113.42", "current_user": "root", "ssh_port": 22, "management_ips": ["198.51.100.5"], # Your current IP "local_ssh_key": "~/.ssh/id_ed25519", "target_user": "admin", "target_ssh_port": 2222 } ``` **Verify existing SSH key or generate:** ```bash # Check for existing key ls -la ~/.ssh/id_ed25519.pub # Generate if needed (DO NOT automate this without user confirmation) ssh-keygen -t ed25519 -C "server-bootstrap-$(date +%Y%m%d)" -f ~/.ssh/id_ed25519 ``` **Test password-based root SSH access (initial):** ```bash ssh -p 22 root@203.0.113.42 'echo "SSH accessible"' ``` ### Stage 2: Install Public Key Copy your public key to the server: ```bash # Using ssh-copy-id (prompts for password) ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 22 root@203.0.113.42 # Or manually ssh -p 22 root@203.0.113.42 'mkdir -p ~/.ssh && chmod 700 ~/.ssh' cat ~/.ssh/id_ed25519.pub | ssh -p 22 root@203.0.113.42 'cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys' ``` **Verify public-key login works:** ```bash ssh -i ~/.ssh/id_ed25519 -p 22 root@203.0.113.42 'echo "Public key works"' ``` **CRITICAL:** Do not proceed until public-key authentication is verified. ### Stage 3: Create Non-Root Sudo User ```bash # Create user and grant sudo ssh -i ~/.ssh/id_ed25519 -p 22 root@203.0.113.42 << 'EOF' adduser --disabled-password --gecos "Admin User" admin usermod -aG sudo admin echo "admin ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/admin chmod 440 /etc/sudoers.d/admin EOF ``` **Copy SSH key to new user:** ```bash ssh -i ~/.ssh/id_ed25519 -p 22 root@203.0.113.42 << 'EOF' mkdir -p /home/admin/.ssh cp /root/.ssh/authorized_keys /home/admin/.ssh/ chown -R admin:admin /home/admin/.ssh chmod 700 /home/admin/.ssh chmod 600 /home/admin/.ssh/authorized_keys EOF ``` **Verify new user sudo access:** ```bash ssh -i ~/.ssh/id_ed25519 -p 22 admin@203.0.113.42 'sudo echo "Sudo works"' ``` **CRITICAL:** Do not proceed until the new user can SSH in and sudo without password. ### Stage 4: Configure Firewall (UFW) ```bash ssh -i ~/.ssh/id_ed25519 -p 22 admin@203.0.113.42 << 'EOF' sudo apt-get update sudo apt-get install -y ufw # Default policies sudo ufw default deny incoming sudo ufw default allow outgoing # Allow new SSH port BEFORE enabling firewall sudo ufw allow 2222/tcp comment 'SSH' # Allow other services as needed sudo ufw allow 80/tcp comment 'HTTP' sudo ufw allow 443/tcp comment 'HTTPS' # Enable firewall (answer yes) sudo ufw --force enable # Verify sudo ufw status numbered EOF ``` **Verify firewall rules:** ```bash ssh -i ~/.ssh/id_ed25519 -p 22 admin@203.0.113.42 'sudo ufw status verbose' ``` Expected output: ``` Status: active Logging: on (low) To Action From -- ------ ---- 2222/tcp ALLOW IN Anywhere # SSH 80/tcp ALLOW IN Anywhere # HTTP 443/tcp ALLOW IN Anywhere # HTTPS ``` ### Stage 5: Change SSH Port **Edit sshd_config:** ```bash ssh -i ~/.ssh/id_ed25519 -p 22 admin@203.0.113.42 << 'EOF' sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup sudo sed -i 's/^#Port 22$/Port 2222/' /etc/ssh/sshd_config sudo sed -i 's/^Port 22$/Port 2222/' /etc/ssh/sshd_config EOF ``` **Check for ssh.socket (Debian 12+):** ```bash ssh -i ~/.ssh/id_ed25519 -p 22 admin@203.0.113.42 << 'EOF' if systemctl is-enabled ssh.socket 2>/dev/null | grep -q enabled; then echo "WARNING: ssh.socket is enabled and may keep SSH on port 22" echo "Disabling ssh.socket and using ssh.service directly..." sudo systemctl disable --now ssh.socket sudo systemctl enable ssh.service fi EOF ``` **Restart SSH service:** ```bash ssh -i ~/.ssh/id_ed25519 -p 22 admin@203.0.113.42 'sudo systemctl restart ssh' ``` **Verify new port is listening:** ```bash ssh -i ~/.ssh/id_ed25519 -p 22 admin@203.0.113.42 'sudo ss -ltnp | grep :2222' ``` Expected output: ``` LISTEN 0 128 0.0.0.0:2222 0.0.0.0:* users:(("sshd",pid=1234,fd=3)) ``` **Test new port:** ```bash ssh -i ~/.ssh/id_ed25519 -p 2222 admin@203.0.113.42 'echo "New port works"' ``` **CRITICAL:** Keep the old SSH session open until new port is verified. ### Stage 6: Harden SSH Configuration ```bash ssh -i ~/.ssh/id_ed25519 -p 2222 admin@203.0.113.42 << 'EOF' sudo sed -i 's/^#PermitRootLogin .*/PermitRootLogin no/' /etc/ssh/sshd_config sudo sed -i 's/^PermitRootLogin .*/PermitRootLogin no/' /etc/ssh/sshd_config sudo sed -i 's/^#PasswordAuthentication .*/PasswordAuthentication no/' /etc/ssh/sshd_config sudo sed -i 's/^PasswordAuthentication .*/PasswordAuthentication no/' /etc/ssh/sshd_config sudo sed -i 's/^#PubkeyAuthentication .*/PubkeyAuthentication yes/' /etc/ssh/sshd_config sudo sed -i 's/^#ChallengeResponseAuthentication .*/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config sudo sed -i 's/^ChallengeResponseAuthentication .*/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config # Test configuration sudo sshd -t # Restart SSH sudo systemctl restart ssh EOF ``` **Verify effective configuration:** ```bash ssh -i ~/.ssh/id_ed25519 -p 2222 admin@203.0.113.42 'sudo sshd -T | grep -E "^(permitrootlogin|passwordauthentication|pubkeyauthentication|port)"' ``` Expected output: ``` port 2222 permitrootlogin no pubkeyauthentication yes passwordauthentication no ``` ### Stage 7: Configure Fail2ban ```bash ssh -i ~/.ssh/id_ed25519 -p 2222 admin@203.0.113.42 << 'EOF' sudo apt-get install -y fail2ban # Create local jail configuration sudo tee /etc/fail2ban/jail.local > /dev/null <<'CONFIG' [DEFAULT] bantime = 3600 findtime = 600 maxretry = 5 ignoreip = 127.0.0.1/8 ::1 198.51.100.5 [sshd] enabled = true port = 2222 logpath = /var/log/auth.log backend = systemd CONFIG sudo systemctl enable fail2ban sudo systemctl restart fail2ban EOF ``` **Verify fail2ban status:** ```bash ssh -i ~/.ssh/id_ed25519 -p 2222 admin@203.0.113.42 'sudo fail2ban-client status sshd' ``` Expected output: ``` Status for the jail: sshd |- Filter | |- Currently failed: 0 | |- Total failed: 0 | `- File list: /var/log/auth.log `- Actions |- Currently banned: 0 |- Total banned: 0 `- Banned IP list: ``` ### Stage 8: Update Local SSH Config Add server entry to local `~/.ssh/config`: ```bash cat >> ~/.ssh/config << 'EOF' Host my-server HostName 203.0.113.42 User admin Port 2222 IdentityFile ~/.ssh/id_ed25519 StrictHostKeyChecking ask UserKnownHostsFile ~/.ssh/known_hosts EOF chmod 600 ~/.ssh/config ``` **Test simplified connection:** ```bash ssh my-server 'echo "SSH config works"' ``` ## Verification Checklist After completing all stages, verify the following server-side: ### SSH Service ```bash ssh my-server << 'EOF' # Check SSH is listening on correct port only sudo ss -ltnp | grep sshd # Check effective sshd configuration sudo sshd -T | grep -E "^(port|permitrootlogin|passwordauthentication|pubkeyauthentication)" # Check ssh.socket is not interfering (Debian 12) systemctl is-enabled ssh.socket systemctl is-active ssh.socket EOF ``` ### Firewall ```bash ssh my-server 'sudo ufw status verbose' ``` Verify: - Status is "active" - Default incoming is "deny" - New SSH port is allowed - No rule allowing port 22 ### Fail2ban ```bash ssh my-server << 'EOF' sudo systemctl is-active fail2ban sudo fail2ban-client status sshd sudo fail2ban-client get sshd ignoreip EOF ``` Verify: - fail2ban service is active - sshd jail is enabled - Your management IP is in ignoreip ### User and Sudo ```bash ssh my-server << 'EOF' whoami sudo -l groups EOF ``` Verify: - Logged in as non-root user - User has NOPASSWD sudo - User is in sudo group ## Common Patterns ### Adding Additional Management IPs ```bash ssh my-server << 'EOF' sudo sed -i 's/^ignoreip = .*/& 203.0.113.100/' /etc/fail2ban/jail.local sudo fail2ban-client reload sudo fail2ban-client get sshd ignoreip EOF ``` ### Opening Additional Firewall Ports ```bash ssh my-server << 'EOF' sudo ufw allow 8080/tcp comment 'Application' sudo ufw status numbered EOF ``` ### Checking for Banned IPs ```bash ssh my-server 'sudo fail2ban-client status sshd' ``` ### Unbanning an IP ```bash ssh my-server 'sudo fail2ban-client set sshd unbanip 198.51.100.10' ``` ## Troubleshooting ### Locked Out After Port Change If new port doesn't work and old session is closed: 1. Use provider console/VNC access 2. Check `sudo ss -ltnp | grep sshd` for actual listening port 3. Check `sudo systemctl status ssh.socket` and `ssh.service` 4. Review `/var/log/auth.log` for SSH errors ### UFW Blocked New SSH Port If you enabled UFW before allowing new SSH port: 1. Use provider console/VNC access 2. `sudo ufw disable` 3. `sudo ufw allow 2222/tcp` 4. `sudo ufw enable` ### Fail2ban Banned Your IP Check ban status: ```bash sudo fail2ban-client status sshd ``` Unban yourself: ```bash sudo fail2ban-client set sshd unbanip YOUR_IP ``` Add to ignoreip: ```bash sudo nano /etc/fail2ban/jail.local # Add IP to ignoreip line sudo fail2ban-client reload ``` ### SSH Port Reverts to 22 (Debian 12) This happens when `ssh.socket` is active: ```bash sudo systemctl disable --now ssh.socket sudo systemctl enable --now ssh.service sudo systemctl restart ssh sudo ss -ltnp | grep sshd ``` ### Root Login Still Works Check effective configuration: ```bash sudo sshd -T | grep permitrootlogin ``` If it shows "yes", ensure:
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る