docs: Add CLAUDE.md and permanent ban script
- Add CLAUDE.md with AI assistant configuration - Add scripts/permanent-ban-repeat-offenders.sh for automated permanent banning - Script automatically detects and permanently bans IPs banned >4 times by fail2ban - Integrates with iptables and geoip-shell for comprehensive security
This commit is contained in:
46
CLAUDE.md
46
CLAUDE.md
@@ -192,4 +192,48 @@ curl -X PROPFIND https://hoborg:AdminPass2024!@ak-homelab.duckdns.org/files/ \
|
|||||||
- Some containers (like Gitea with s6-overlay) need root start then privilege drop via USER_UID/USER_GID environment variables
|
- Some containers (like Gitea with s6-overlay) need root start then privilege drop via USER_UID/USER_GID environment variables
|
||||||
- Test each security change individually, not in batches
|
- Test each security change individually, not in batches
|
||||||
- Network access patterns matter: SSH Git needs direct access, HTTP can be proxied through localhost
|
- Network access patterns matter: SSH Git needs direct access, HTTP can be proxied through localhost
|
||||||
- DO NOT set Docker user: directive for services using s6-overlay init systems (breaks initialization)
|
- DO NOT set Docker user: directive for services using s6-overlay init systems (breaks initialization)
|
||||||
|
|
||||||
|
## Claude Development Guidelines
|
||||||
|
|
||||||
|
### CRITICAL: Anti-Pattern Reminders
|
||||||
|
**BEFORE writing ANY script or solution, Claude MUST:**
|
||||||
|
|
||||||
|
1. **RESEARCH FIRST, CODE NEVER** - Always research existing solutions in this exact order:
|
||||||
|
- **pacman** (official Arch packages) - HIGHEST PREFERENCE
|
||||||
|
- **AUR** (yay/paru) - SECOND PREFERENCE
|
||||||
|
- **GitHub/manual installs** - LOWEST PREFERENCE, last resort only
|
||||||
|
|
||||||
|
2. **VERIFY SYNTAX BEFORE WRITING** - Never generate scripts with broken syntax:
|
||||||
|
- Use `--help` to check command syntax BEFORE using it
|
||||||
|
- Test commands in small parts first
|
||||||
|
- Never assume argument names or formats
|
||||||
|
|
||||||
|
3. **STICK TO THE CHOSEN SOLUTION** - Don't drift away from proven solutions:
|
||||||
|
- If research finds tool X works, USE tool X
|
||||||
|
- Don't randomly switch to tool Y mid-implementation
|
||||||
|
- Finish what you start before considering alternatives
|
||||||
|
|
||||||
|
4. **PREFER SIMPLE OVER COMPLEX**:
|
||||||
|
- Use existing tools rather than writing custom scripts
|
||||||
|
- Bash for simple tasks, Python only when complexity requires it
|
||||||
|
- One working solution beats three broken attempts
|
||||||
|
|
||||||
|
5. **CHECK PACKAGE REPOSITORIES FIRST**:
|
||||||
|
- Always check `pacman -Ss` before any manual installation
|
||||||
|
- Always check `yay -Ss` before downloading random scripts
|
||||||
|
- Maintained packages > GitHub scripts > custom solutions
|
||||||
|
|
||||||
|
### Failure Patterns to Avoid
|
||||||
|
- ❌ Writing broken syntax without testing commands first
|
||||||
|
- ❌ Switching solutions mid-implementation without reason
|
||||||
|
- ❌ Overcomplicating when simple solutions exist
|
||||||
|
- ❌ Installing random scripts before checking packages
|
||||||
|
- ❌ Creating custom tools when proven ones exist
|
||||||
|
|
||||||
|
### Success Pattern to Follow
|
||||||
|
- ✅ Research → Choose → Verify syntax → Implement → Test
|
||||||
|
- ✅ pacman → AUR → GitHub (in that preference order)
|
||||||
|
- ✅ Use proven, maintained tools over custom scripts
|
||||||
|
- ✅ Test command syntax with `--help` first
|
||||||
|
- ✅ Stay focused on the chosen solution
|
||||||
64
scripts/permanent-ban-repeat-offenders.sh
Executable file
64
scripts/permanent-ban-repeat-offenders.sh
Executable file
@@ -0,0 +1,64 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Permanent ban script for IPs that have been banned more than 4 times by fail2ban
|
||||||
|
# Run via cron: 0 */6 * * * /home/hoborg/homelab/scripts/permanent-ban-repeat-offenders.sh
|
||||||
|
|
||||||
|
LOGFILE="/var/log/permanent-ban.log"
|
||||||
|
BANLIST_FILE="/etc/fail2ban/permanent-banlist.conf"
|
||||||
|
THRESHOLD=4
|
||||||
|
|
||||||
|
# Function to log with timestamp
|
||||||
|
log_message() {
|
||||||
|
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOGFILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ensure permanent banlist file exists
|
||||||
|
if [ ! -f "$BANLIST_FILE" ]; then
|
||||||
|
touch "$BANLIST_FILE"
|
||||||
|
chmod 644 "$BANLIST_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_message "Starting repeat offender analysis (threshold: $THRESHOLD bans)"
|
||||||
|
|
||||||
|
# Get list of IPs with ban counts from fail2ban logs
|
||||||
|
REPEAT_OFFENDERS=$(grep "Ban " /var/log/fail2ban.log* | \
|
||||||
|
grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | \
|
||||||
|
sort | uniq -c | sort -nr | \
|
||||||
|
awk -v threshold="$THRESHOLD" '$1 > threshold {print $2 " " $1}')
|
||||||
|
|
||||||
|
if [ -z "$REPEAT_OFFENDERS" ]; then
|
||||||
|
log_message "No repeat offenders found above threshold"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Process each repeat offender
|
||||||
|
echo "$REPEAT_OFFENDERS" | while read ip ban_count; do
|
||||||
|
# Skip if already permanently banned
|
||||||
|
if grep -q "^$ip" "$BANLIST_FILE"; then
|
||||||
|
log_message "IP $ip already permanently banned (skip)"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get country information
|
||||||
|
COUNTRY=$(whois "$ip" 2>/dev/null | grep -i "country:" | head -1 | awk '{print $2}')
|
||||||
|
|
||||||
|
# Add to permanent banlist
|
||||||
|
echo "$ip # Banned $(date '+%Y-%m-%d') - $ban_count offenses - Country: $COUNTRY" >> "$BANLIST_FILE"
|
||||||
|
|
||||||
|
# Add permanent iptables rule
|
||||||
|
iptables -I INPUT -s "$ip" -j DROP
|
||||||
|
|
||||||
|
# Make iptables rule persistent (systemd approach)
|
||||||
|
if command -v iptables-save >/dev/null 2>&1; then
|
||||||
|
iptables-save > /etc/iptables/iptables.rules 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_message "PERMANENTLY BANNED: $ip ($ban_count offenses, Country: $COUNTRY)"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Reload fail2ban to ensure it sees the updated banlist
|
||||||
|
if systemctl is-active --quiet fail2ban; then
|
||||||
|
log_message "Reloading fail2ban service"
|
||||||
|
systemctl reload fail2ban
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_message "Repeat offender analysis completed"
|
||||||
Reference in New Issue
Block a user