diff --git a/ansible/group_vars/all b/ansible/group_vars/all
index 7055312d9b05399ad03af400131849912e764840..357ce7bf7e37f26729f61179864abbf62ec5ed44 100644
--- a/ansible/group_vars/all
+++ b/ansible/group_vars/all
@@ -75,3 +75,9 @@
 
 # account app
   account_app_port: 8000
+
+# fail2ban
+  enable_fail2ban: true
+  maxretry: 1
+  findtime: 600
+  bantime: 1200
diff --git a/ansible/roles/fail2ban/templates/jail.local.j2 b/ansible/roles/fail2ban/templates/jail.local.j2
new file mode 100644
index 0000000000000000000000000000000000000000..af6ae6654f0a46487bf6a10863297cbb45d30aa3
--- /dev/null
+++ b/ansible/roles/fail2ban/templates/jail.local.j2
@@ -0,0 +1,7 @@
+[DEFAULT]
+banaction = firewalld
+bantime  = {{ bantime }}
+ignoreip = {{ fail2ban_cidr_list }}
+
+[sshd]
+enabled = true
diff --git a/ansible/roles/fail2ban/templates/sshpiperd_filter.local.j2 b/ansible/roles/fail2ban/templates/sshpiperd_filter.local.j2
new file mode 100644
index 0000000000000000000000000000000000000000..f5a6081ec28c490ab24ff3f4c96c3b08bb86b9da
--- /dev/null
+++ b/ansible/roles/fail2ban/templates/sshpiperd_filter.local.j2
@@ -0,0 +1,22 @@
+# Refer to https://github.com/fail2ban/fail2ban/wiki/Developing-Regex-in-Fail2ban for developing regex using fail2ban
+#
+[INCLUDES]
+before = common.conf
+
+[DEFAULT]
+_daemon = sshpiperd
+__iso_datetime = "\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:[+-]\d{2}:\d{2}|Z)"
+__pref = time=%(__iso_datetime)s level=(?:debug|error)
+
+[Definition]
+# Define the prefix regex for the log lines
+prefregex = ^<F-MLFID>%(__prefix_line)s%(__pref)s</F-MLFID>\s+<F-CONTENT>.+</F-CONTENT>$
+
+# Failregex to match the specific failure log lines (prefregex is automatically included)
+failregex = ^msg="connection from .*failtoban: ip <HOST> too auth many failures"$
+
+ignoreregex =
+
+mode = normal
+
+maxlines = 1
diff --git a/ansible/roles/fail2ban/templates/sshpiperd_jail.local.j2 b/ansible/roles/fail2ban/templates/sshpiperd_jail.local.j2
new file mode 100644
index 0000000000000000000000000000000000000000..681212ccaf59595c5dd6097e188286db85225dbd
--- /dev/null
+++ b/ansible/roles/fail2ban/templates/sshpiperd_jail.local.j2
@@ -0,0 +1,9 @@
+# This configuration will block the remote host after {{maxretry}} failed SSH login attempts.
+[sshpiperd]
+enabled  = true
+filter   = sshpiperd
+logpath  = /var/log/messages
+port     = 22
+maxretry = {{ maxretry }}
+backend  = auto
+findtime = {{ findtime }}