From ad990401a56bf0f34a23fd3166d95ec30c478336 Mon Sep 17 00:00:00 2001 From: Junwei Zhao Date: Sun, 5 Oct 2025 10:10:06 +1100 Subject: [PATCH] add fail2ban to terraform --- agents.md | 31 +++++++++- terraform/fail2ban.tf | 141 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 terraform/fail2ban.tf diff --git a/agents.md b/agents.md index 4b40bf3..da247bf 100644 --- a/agents.md +++ b/agents.md @@ -42,13 +42,22 @@ - Web UI: https://argo.junv.cc - Uses external Redis (redis-master.db.svc.cluster.local) -4. **Security**: CrowdSec +4. **Security**: Multi-layered protection + + **CrowdSec** (Community threat intelligence): - Monitors NGINX Ingress logs - SSH monitoring (port 22422) - System log analysis - Enrolled in CrowdSec Console - Storage: /mnt/k8s/crowdsec/ on server-3 + **fail2ban** (Local intrusion prevention): + - SSH brute force protection (port 22422) + - Ban time: 1 hour (3600 seconds) + - Max retries: 5 attempts in 10 minutes + - Recidive jail: 24 hour ban for repeat offenders + - Ignores local network (192.168.1.0/24) + 5. **Monitoring**: Prometheus + Grafana - Metrics collection - Custom dashboards @@ -64,6 +73,7 @@ - `main.tf`: K3s cluster setup, SSH configuration - `argocd.tf`: ArgoCD, cert-manager, NGINX Ingress deployment - `crowdsec.tf`: CrowdSec security engine setup + - `fail2ban.tf`: fail2ban intrusion prevention setup - `postgres.tf`: PostgreSQL installation via SSH - `redis.tf`: Redis installation via SSH @@ -209,6 +219,25 @@ kubectl exec -n crowdsec deployment/crowdsec-lapi -- cscli bouncers list ./terraform/view_crowdsec.sh ``` +### fail2ban Commands + +```bash +# View status +ssh -p 22422 junv@192.168.1.2 "sudo fail2ban-client status" + +# SSH jail status +ssh -p 22422 junv@192.168.1.2 "sudo fail2ban-client status sshd" + +# List banned IPs +ssh -p 22422 junv@192.168.1.2 "sudo fail2ban-client status sshd | grep 'Banned IP'" + +# Unban an IP +ssh -p 22422 junv@192.168.1.2 "sudo fail2ban-client set sshd unbanip " + +# Quick status view +./terraform/view_fail2ban.sh +``` + ### Backup/Restore ```bash diff --git a/terraform/fail2ban.tf b/terraform/fail2ban.tf new file mode 100644 index 0000000..595903d --- /dev/null +++ b/terraform/fail2ban.tf @@ -0,0 +1,141 @@ +# Fail2ban Installation and Configuration +# Protects SSH (port 22422) and other services from brute force attacks + +resource "ssh_resource" "fail2ban_install" { + depends_on = [ssh_resource.k3s_install] + + host = local.ssh_host + user = local.ssh_user + port = local.ssh_port + private_key = local.ssh_private_key + timeout = "10m" + + when = "create" + + commands = [ + "echo 'Installing fail2ban...'", + "sudo apt-get update", + "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y fail2ban", + "echo 'fail2ban installed successfully'" + ] +} + +resource "ssh_resource" "fail2ban_config" { + depends_on = [ssh_resource.fail2ban_install] + + host = local.ssh_host + user = local.ssh_user + port = local.ssh_port + private_key = local.ssh_private_key + timeout = "5m" + + when = "create" + + commands = [ + "echo 'Configuring fail2ban...'", + + # Create local jail configuration for SSH on custom port 22422 + <<-EOT + cat << 'EOF' | sudo tee /etc/fail2ban/jail.local + [DEFAULT] + # Ban hosts for 1 hour (3600 seconds) + bantime = 3600 + + # A host is banned if it has generated "maxretry" during the last "findtime" seconds + findtime = 600 + maxretry = 5 + + # Email notifications (optional - configure if needed) + # destemail = me@junv.cc + # sender = fail2ban@junv.cc + # action = %(action_mwl)s + + # Ignore local network + ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24 + + [sshd] + enabled = true + port = 22422 + filter = sshd + logpath = /var/log/auth.log + maxretry = 5 + bantime = 3600 + findtime = 600 + + [sshd-ddos] + enabled = true + port = 22422 + filter = sshd-ddos + logpath = /var/log/auth.log + maxretry = 10 + bantime = 7200 + findtime = 600 + + [recidive] + enabled = true + logpath = /var/log/fail2ban.log + bantime = 86400 + findtime = 86400 + maxretry = 3 + + EOF + EOT + , + + # Create custom filter for Kubernetes-related attacks (optional) + <<-EOT + cat << 'EOF' | sudo tee /etc/fail2ban/filter.d/k8s-api.conf + [Definition] + failregex = ^.*"remote_addr":"".*"status":(?:401|403).*$ + ignoreregex = + EOF + EOT + , + + # Enable and start fail2ban service + "sudo systemctl enable fail2ban", + "sudo systemctl restart fail2ban", + + # Wait for fail2ban to start + "sleep 5", + + # Verify fail2ban is running + "sudo systemctl is-active fail2ban", + + "echo '✅ fail2ban configured and started successfully!'" + ] +} + +# Output fail2ban status information +output "fail2ban_info" { + depends_on = [ssh_resource.fail2ban_config] + + value = <<-EOT + Fail2ban deployed successfully! + + Configuration: + - ✅ SSH protection on port 22422 + - ✅ Ban time: 1 hour (3600 seconds) + - ✅ Max retries: 5 attempts in 10 minutes + - ✅ Recidive jail: 24 hour ban for repeat offenders + - ✅ Ignored IPs: 192.168.1.0/24 (local network) + + Useful Commands: + - Status: ssh -p 22422 junv@192.168.1.2 "sudo fail2ban-client status" + - SSH jail status: ssh -p 22422 junv@192.168.1.2 "sudo fail2ban-client status sshd" + - List banned IPs: ssh -p 22422 junv@192.168.1.2 "sudo fail2ban-client status sshd | grep 'Banned IP'" + - Unban IP: ssh -p 22422 junv@192.168.1.2 "sudo fail2ban-client set sshd unbanip " + - View logs: ssh -p 22422 junv@192.168.1.2 "sudo tail -f /var/log/fail2ban.log" + + Integration with CrowdSec: + - Both fail2ban and CrowdSec monitor /var/log/auth.log + - fail2ban provides immediate local protection + - CrowdSec provides community intelligence and advanced scenarios + - They work together without conflicts + + Configuration files: + - Main config: /etc/fail2ban/jail.local + - Filters: /etc/fail2ban/filter.d/ + - Actions: /etc/fail2ban/action.d/ + EOT +}