Skip to content

Fail2Ban Primer

fail2ban

Fail2Ban is a log-parsing application that monitors system logs for symptoms of an automated attack on your server, and it bans offending IPs automatically by updating firewall rules to prevent further breaches. Fail2Ban is configured through jail files located in /etc/fail2ban. It comes with a default configuration file (jail.conf) which should not be edited directly, as it may be overwritten by package upgrades. Instead, create a local copy to override the defaults.

1. Configure Fail2Ban

a. Create a Local Configuration File:

sudo cp /etc/fail2ban/jail.{conf,local}

b. Edit the Local Configuration File:

sudo nano /etc/fail2ban/jail.local

c. Configure Default Settings: Inside jail.local, you can set defaults for all jails. Adjust values according to your needs, such as bantime, findtime, and maxretry:

# "bantime" is the number of seconds that a host is banned.
bantime  = 10m

# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime  = 10m

# "maxretry" is the number of failures before a host get banned.
maxretry = 5

d. Enable and Configure Jails: Fail2Ban uses jails for specific services (e.g., SSH, Apache). To enable a jail, uncomment and set enabled = true under its section. For example, to protect SSH:

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3

Adjust maxretry and other settings as needed for your environment.

2. Create Custom Filters

For custom rules or to block specific types of attacks not covered by the default configuration, create custom filter files in /etc/fail2ban/filter.d/.

a. Create a Custom Filter:

sudo nano /etc/fail2ban/filter.d/mycustomfilter.conf
b. Define Fail Regex: Add rules to match log lines indicating malicious activity. For example:
[Definition] failregex = ^<HOST> -.*"(GET|POST).*  ```  Replace the regex pattern with one matching the attacks you want to block.

3. Monitor Fail2Ban

a. Check Fail2Ban Status:

sudo fail2ban-client status
(shows all active jails)

b. Check Status of a Specific Jail:

sudo fail2ban-client status sshd
Replace sshd with the jail name to see details, including currently banned IPs.

4. Adjusting Rules and Unbanning IPs

a. To Adjust Rules: Edit your jail.local or specific filter files, then restart Fail2Ban to apply changes:

sudo systemctl restart fail2ban
b. To Unban an IP:
sudo fail2ban-client set sshd unbanip IP_ADDRESS
Replace sshd with the relevant jail and IP_ADDRESS with the IP you wish to unban.

Common Jails

1. Apache and Nginx Jails

If you're running a web server, enabling jails for Apache or Nginx can help protect against brute force attacks, DDoS attacks, and unauthorized access attempts. - apache-auth: Targets unauthorized access attempts. - apache-badbots: Blocks known bad bots and scrapers. - nginx-http-auth: Similar to apache-auth but for Nginx servers. - nginx-limit-req: Protects against request rate-limiting breaches in Nginx.

2. Mail Server Jails

For servers handling email services, protecting against unauthorized login attempts is crucial. - postfix: Protects the Postfix mail server from brute force and DDoS attacks. - dovecot: Monitors Dovecot IMAP/POP3 server login attempts. - exim: Watches for unauthorized access attempts on the Exim mail server. - sasl: Targets SASL authentication failures.

3. Database Server Jails

If your server is hosting database services, consider enabling jails to monitor for unauthorized access attempts. - mysqld-auth: Monitors MySQL login attempts. - postgresql: Protects PostgreSQL databases from unauthorized access attempts.

4. FTP Server Jails

For servers providing file transfer services via FTP, securing against brute force login attempts is important. - vsftpd: Monitors VsFTPd server for authentication failures. - proftpd: Protects ProFTPd servers from unauthorized access. - pure-ftpd: Watches for login failures on Pure-FTPd servers.

5. Web Application Jails

Fail2Ban can also protect specific web applications by monitoring their logs for signs of abuse. - roundcube-auth: Protects Roundcube webmail access. - wordpress: Monitors for excessive failed login attempts to a WordPress site. - drupal-login: Protects Drupal sites by watching for failed login attempts.

Automated SetUp Script for After Install

#!/bin/bash

# Define paths and settings
read -p "Enter the full filepath for your honeypot: " HONEYPOT_FILE
read -p "Enter the full filepath where fail2ban is installed: " FAIL2BAN_INSTALL_PATH
LOG_FILE="/var/log/honeypot_access.log"


# Initialize an empty string to keep track of enabled jails
ENABLED_JAILS=""

# Move scripts and install Fail2Ban
sudo python3 $HOME/scripts/fail2ban/setup.py install

# Step 1: Create Fail2Ban Systemd Service Unit File
echo "Creating Fail2Ban systemd service unit file..."
cat <<'EOF' | sudo tee /etc/systemd/system/fail2ban.service > /dev/null
[Unit]
Description=Fail2Ban Service
After=network.target
After=syslog.target

[Service]
Type=simple
ExecStart=/usr/local/bin/fail2ban-client -x start
ExecStop=/usr/local/bin/fail2ban-client stop
ExecReload=/usr/local/bin/fail2ban-client reload
Restart=always
RestartSec=30

[Install]
WantedBy=multi-user.target
EOF

# Ensuring the service file has correct paths
if [ ! -f /usr/local/bin/fail2ban-client ]; then
    echo "Fail2Ban client executable not found at /usr/local/bin/fail2ban-client. Please check the path."
    exit 1
fi

echo "Fail2Ban systemd service unit file has been created."

# Step 2: Reload Systemd and Start Fail2Ban
echo "Reloading systemd daemon and starting Fail2Ban service..."
sudo systemctl daemon-reload
sudo systemctl start fail2ban
echo "Fail2Ban service started."

# Step 3: Enable Fail2Ban to Start on Boot
echo "Enabling Fail2Ban service to start on boot..."
sudo systemctl enable fail2ban
echo "Fail2Ban service has been enabled to start on boot."

# Step 4: Verify the Service is Running
echo "Verifying that Fail2Ban is active and running..."
sudo systemctl status fail2ban | grep "active (running)"

# Configure Fail2Ban
sudo cp /etc/fail2ban/jail.{conf,local}
sudo touch $LOG_FILE

# Append custom settings to jail.local
sudo tee -a /etc/fail2ban/jail.local << EOF

# Custom settings
bantime = 600
findtime = 600
maxretry = 1

[honeypot]
enabled = true
filter = honeypot
logpath = $LOG_FILE
maxretry = 1
bantime = 600
EOF

# Create a custom filter for Fail2Ban
sudo tee /etc/fail2ban/filter.d/honeypot.conf << 'EOF'
[INCLUDES]
before = common.conf

[Definition]
failregex = \[<HOST>\] - Honeypot file was accessed
ignoreregex =

EOF

# Honeypot monitoring script
cat > $HOME/honeypot_monitor.sh << 'EOT'
#!/bin/bash

LOG_FILE="/var/log/honeypot_access.log"
HONEYPOT_FILE="$HOME/scripts/flagScript"

while true; do
  if [ -f "$HONEYPOT_FILE" ]; then
    echo "$(date +"%Y-%m-%d %H:%M:%S") - Honeypot file was accessed" >> $LOG_FILE
  fi
  sleep 10
done
EOT

chmod +x $HOME/honeypot_monitor.sh
sudo systemctl restart fail2ban
(crontab -l 2>/dev/null; echo "* * * * * $HOME/honeypot_monitor.sh") | crontab -

echo "Setup is complete. Fail2Ban is configured, and the honeypot monitor is scheduled to run every minute."


# Determine server type and configure relevant jails
# Function to check and configure jail based on detected services
configure_jail_based_on_detection() {
    # Web Server Detection
    if systemctl is-active --quiet apache2 || systemctl is-active --quiet httpd; then
        echo "Apache web server detected."
        configure_jail "apache-auth"
        configure_jail "apache-badbots"
    elif systemctl is-active --quiet nginx; then
        echo "Nginx web server detected."
        configure_jail "nginx-http-auth"
        configure_jail "nginx-limit-req"
    fi

    # Mail Server Detection
    if systemctl is-active --quiet postfix; then
        echo "Postfix mail server detected."
        configure_jail "postfix"
    elif systemctl is-active --quiet dovecot; then
        echo "Dovecot mail server detected."
        configure_jail "dovecot"
    elif systemctl is-active --quiet exim4; then
        echo "Exim mail server detected."
        configure_jail "exim"
    fi

    # Database Server Detection
    if systemctl is-active --quiet mysql || systemctl is-active --quiet mariadb; then
        echo "MySQL/MariaDB database server detected."
        configure_jail "mysqld-auth"
    elif systemctl is-active --quiet postgresql; then
        echo "PostgreSQL database server detected."
        configure_jail "postgresql"
    fi

    # FTP Server Detection
    if systemctl is-active --quiet vsftpd; then
        echo "VsFTPd server detected."
        configure_jail "vsftpd"
    elif systemctl is-active --quiet proftpd; then
        echo "ProFTPd server detected."
        configure_jail "proftpd"
    elif systemctl is-active --quiet pure-ftpd; then
        echo "Pure-FTPd server detected."
        configure_jail "pure-ftpd"
    fi

    # Web Application Detection
    # Note: This is more complex and often requires custom logic based on log files or installed directories
    # WordPress Detection
    if [ -d "/var/www/html/wp-admin" ]; then
        echo "WordPress installation detected."
        configure_jail "wordpress"
    fi
    # Web Application Detection
    # Assuming a standard installation directory, adjust paths as necessary

    # Drupal Detection
    if [ -f "/var/www/html/sites/default/settings.php" ]; then
        echo "Drupal installation detected."
        configure_jail "drupal-login"
    fi

    # Roundcube Detection
    if [ -f "/var/www/html/roundcube/config/config.inc.php" ]; then
        echo "Roundcube webmail detected."
        configure_jail "roundcube-auth"
    fi

}

# Updated configure_jail function to append jail names to ENABLED_JAILS
configure_jail() {
    echo "Enabling $1 jail..."
    # Append the jail name to the ENABLED_JAILS variable
    ENABLED_JAILS="$ENABLED_JAILS $1"
    sudo tee -a /etc/fail2ban/jail.local << EOF

[$1]
enabled = true
EOF
}

# After detecting and enabling jails based on server type
echo "Detecting server type and configuring Fail2Ban..."
configure_jail_based_on_detection

# List out the jails that have just been detected and enabled, in columns
list_enabled_jails

echo "$server_category configuration complete."

# Function to list currently enabled jails in columns
list_enabled_jails() {
    echo "Currently enabled jails:"
    ENABLED_JAILS_LIST=$(grep -Po '^\[.*\]$' /etc/fail2ban/jail.local | while read -r line ; do
        JAIL_NAME=$(echo $line | tr -d '[]')
        if grep -A 3 "\[$JAIL_NAME\]" /etc/fail2ban/jail.local | grep -q "enabled = true"; then
            echo "$JAIL_NAME"
        fi
    done)
    echo "$ENABLED_JAILS_LIST" | column
}

# Then, list all available jails and prompt for additional ones, formatted in columns
echo "Detecting available jails in /etc/fail2ban/jail.local..."

# Extract and list available jails from jail.local, formatting in columns
AVAILABLE_JAILS=$(grep -oP '^\[\K[^]]+' /etc/fail2ban/jail.local | column)
echo "The following jails are available in your configuration:"
echo "$AVAILABLE_JAILS"
echo "You have just seen which jails were automatically enabled. If you wish to enable any additional jails, please enter their names, separated by spaces (e.g., sshd nginx-http-auth)."
read -ra USER_JAILS

# Enable user-selected jails
for JAIL in "${USER_JAILS[@]}"; do
    if grep -q "^\[$JAIL\]" /etc/fail2ban/jail.local; then
        echo "Enabling $JAIL jail..."
        # Check if 'enabled' line exists for the jail
        if grep -A 10 "^\[$JAIL\]" /etc/fail2ban/jail.local | grep -q "^enabled"; then
            # 'enabled' line exists, ensure it's set to true
            sudo sed -i "/^\[$JAIL\]/,/^\[/s/^enabled[ ]*=.*/enabled = true/" /etc/fail2ban/jail.local
        else
            # 'enabled' line doesn't exist, insert it right after the jail block start
            sudo sed -i "/^\[$JAIL\]/a enabled = true" /etc/fail2ban/jail.local
        fi
    else
        echo "Jail $JAIL is not recognized."
    fi
done


# Final summary, with enabled jails listed in columns
echo "The following jails have been detected and enabled: $(echo $ENABLED_JAILS | column)"
echo "Setup is complete. Fail2Ban is configured, and the honeypot monitor is scheduled to run every minute. Please review /etc/fail2ban/jail.local for the enabled jails."