first commit

This commit is contained in:
Hermes Agent
2026-05-10 13:52:46 +08:00
commit ccc63d1e70
4583 changed files with 584341 additions and 0 deletions

View File

@@ -0,0 +1,185 @@
---
name: ssh-server-setup
description: "Set up SSH key authentication, configure firewalls, harden SSH, and audit server security. Use when: (1) user needs SSH access to a server, (2) SSH connection fails with permission errors, (3) setting up key-based auth for new users, (4) enabling/configuring UFW firewall, (5) analyzing SSH attacks, (6) hardening SSH config."
---
# SSH Server Setup & Troubleshooting
## Quick Setup (New Key Pair)
### 1. Generate Key Pair
```bash
# On client machine (or use Xshell's key generator)
ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa -C "user@host"
```
### 2. Install Public Key on Server
```bash
# On server
mkdir -p /home/<user>/.ssh
echo '<public-key-content>' >> /home/<user>/.ssh/authorized_keys
chmod 700 /home/<user>/.ssh
chmod 600 /home/<user>/.ssh/authorized_keys
chmod 755 /home/<user> # CRITICAL: must NOT be 777 or group-writable
chown -R <user>:<user> /home/<user>/.ssh
```
### 3. Verify SSH Config Allows Key Auth
```bash
grep -E "^(PubkeyAuthentication|AuthorizedKeysFile)" /etc/ssh/sshd_config
# Should show:
# PubkeyAuthentication yes
# AuthorizedKeysFile .ssh/authorized_keys
```
## ⚠️ Critical Pitfall: Home Directory Permissions
**Symptom**: SSH logs show `Authentication refused: bad ownership or modes for directory /home/<user>`
**Root cause**: SSH (OpenSSH) refuses public key authentication if the user's home directory has group or other write permissions (e.g., 777, 775).
**Fix**:
```bash
chmod 755 /home/<user>
```
**Why**: OpenSSH considers a writable home directory a security risk — other users could manipulate `~/.ssh/authorized_keys`. The directory must be owned by the user and not writable by group/others.
**Debugging**:
```bash
# Check current permissions
ls -la /home/ | grep <user>
# Should show drwxr-xr-x (755), NOT drwxrwxrwx (777) or drwxrwxr-x (775)
# Check SSH logs for the exact error
tail -20 /var/log/auth.log | grep -i "ssh\|publickey"
# Or on systemd systems:
journalctl -u ssh --no-pager -n 20
```
## Permission Checklist
| Path | Owner | Permissions | Why |
|------|-------|-------------|-----|
| `/home/<user>` | `<user>` | `755` | SSH refuses auth if group/other writable |
| `~/.ssh/` | `<user>` | `700` | Only owner should access SSH config |
| `~/.ssh/authorized_keys` | `<user>` | `600` | Only owner should read/write keys |
| `~/.ssh/id_rsa` (private) | `<user>` | `600` | Private key must be restricted |
## Xshell-Specific Notes
1. **Generate key**: 工具 → 用户密钥管理器 → 新建 → RSA 2048
2. **Import key**: 工具 → 用户密钥管理器 → 导入
3. **Connection settings**:
- 协议: SSH
- 用户身份验证: 方法选 **Public Key**(不是 Password
- 用户名: `ubuntu` (or whatever the server user is)
- 用户密钥: select the imported key
## Common Errors
| Error | Cause | Fix |
|-------|-------|-----|
| `bad ownership or modes for directory` | Home dir writable by group/others | `chmod 755 /home/<user>` |
| `bad ownership or modes for file` | authorized_keys wrong perms | `chmod 600 ~/.ssh/authorized_keys` |
| `Permission denied (publickey)` | Key not in authorized_keys | Add public key to file |
| `Connection closed by foreign host` | Auth failed, server disconnects | Check logs for specific reason |
| `所选的用户密钥未在远程主机上注册` | Public key not installed on server | Add public key to authorized_keys |
---
## UFW Firewall Setup
When enabling SSH access, always set up UFW in this order to avoid lockout:
```bash
# 1. Allow SSH FIRST (before enabling firewall)
sudo ufw allow 22/tcp comment "SSH"
# 2. Set default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing
# 3. Enable (use --force for non-interactive)
sudo ufw --force enable
# 4. Verify
sudo ufw status verbose
```
**Opening additional ports later:**
```bash
sudo ufw allow 80/tcp comment "HTTP"
sudo ufw allow 443/tcp comment "HTTPS"
sudo ufw allow from <specific-ip> to any port 22 # Restrict SSH to specific IP
```
---
## SSH Attack Analysis
**Check attack patterns:**
```bash
# Failed/disconnected attempts with IP counts
journalctl -u ssh --no-pager --since "2026-05-01" | \
grep -i "failed\|invalid\|refused\|disconnected.*preauth" | \
grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | sort | uniq -c | sort -rn | head -15
# Successful logins only
journalctl -u ssh --no-pager --since "2026-05-01" | grep "Accepted" | \
grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | sort | uniq -c | sort -rn
```
**IP geolocation lookup:**
```bash
# ip-api.com (free, no key needed, rate limited 45/min)
curl -s "http://ip-api.com/json/<IP>?fields=country,regionName,isp,org"
```
**Typical attack sources:** Cloud provider IPs (Tencent Cloud, Alibaba Cloud, OVH, Hetzner) — these are botnet/scanner nodes, not targeted attacks.
---
## SSH Hardening (sshd_config)
Add to `/etc/ssh/sshd_config`:
```bash
MaxAuthTries 3 # Limit auth attempts per connection
LoginGraceTime 30 # Timeout for auth (seconds)
ClientAliveInterval 300 # Send keepalive every 5 min
ClientAliveCountMax 2 # Disconnect after 2 missed keepalives
MaxSessions 3 # Limit concurrent sessions per connection
AllowAgentForwarding no # Disable unless needed
AllowTcpForwarding no # Disable unless needed
```
Apply: `sudo systemctl restart sshd`
---
## Server Security Audit Checklist
```bash
# 1. SSH config
cat /etc/ssh/sshd_config | grep -v "^#" | grep -v "^$"
# 2. Firewall status
sudo ufw status verbose
# 3. fail2ban status (if installed)
sudo fail2ban-client status sshd
# 4. Auto-updates
cat /etc/apt/apt.conf.d/20auto-upgrades
# 5. Listening ports
ss -tlnp | grep -v "127.0.0.1" | grep -v "::1"
# 6. System resources
free -h && df -h / && uptime
# 7. Swap config
swapon --show
cat /proc/sys/vm/swappiness
```