1

Topic: fail2ban with FreeBSD

==== REQUIRED BASIC INFO OF YOUR IREDMAIL SERVER ====
- iRedMail version (check /etc/iredmail-release): 1.2.1
- Deployed with iRedMail Easy or the downloadable installer? upgrades from 1.0
- Linux/BSD distribution name and version: FreeBSD
- Store mail accounts in which backend (LDAP/MySQL/PGSQL): PgSQL
- Web server (Apache or Nginx): Nginx
- Manage mail accounts with iRedAdmin-Pro? No
- [IMPORTANT] Related original log or error message is required if you're experiencing an issue.
====

Fail2ban on FreeBSD
1. Motivation

I have a personal domain for about a decade. Initially, I used some providers to mostly have my emails sorted out and a one-page web profile that not even I care about. Over the years, the providers removed the (hook) discounts, and the total price was too high for my taste. Putting my laziness aside and given that I can have a server for AUD4.00 per month, I decided to take things to own my own hands.

After some research, I came across iRedMail, and I am happy using it since v0.98.

Every now and then I check the servers (I now have some other domains) to check for anomalies or other strange things, so I can improve them.

A few days ago I saw that there were repeating offending attempts on postfix by an IP listed on Barracuda.

Connecting the dots, I then remembered that fail2ban is an option to take care of these things. Still, it was commented out of the iRedMail installation on FreeBSD.

I decided to put my laziness aside once again to install AND configure fail2ban.

2. Disclaimer

Follow or implement the directions below at your own risk. There will be NO support.

3. References

I searched for a few combinations of `FreeBSD`, `ipfw`, `fail2ban`, `iRedMail` and got some pages and articles I used to base my attempt.

4. Remarks
4.1 IPFW

FreeBSD has ipfw as its default package filter, and it is embedded in the system. Some people prefer pf developed by the OpenBSD team but requires a separate install. I am keeping it simple.

NOTE: I use the provider's external firewall for the hard work. I am configuring `ipfw` wide open only to work with fail2ban. The configuration below is NOT intended to protect the server.

4.2 SSHGuard

During my search, I came across SSHGuard, which, despite the name now does other services and protocols. I did not compare fail2ban and SSHGuard besides reading their Wikipedia pages and websites.

One appealing thing about SSHGuard is that it is written in C, where fail2ban is written in Python. The difference implies that SSHGuard would have a better performance. As iRedMail on FreeBSD compiles all the software, that would not be an installation issue.

4.3 Fail2ban on FreeBSD

My high-level understanding is that iRedMail is not familiar with ipfw, so it decided to not implement. No criticism here, just apparently a fact, and to me, a wise decision.

4.4 One more note

I run the process below in one of my less critical servers before I decided to write it down as an email/article. I would not call a reference or tutorial, but I will be glad if it helps someone else.

If you catch any issues, please add to the topic's chain.

If you use FreeBSD and want or need fail2ban, ask iRedMail to support it again.

4.5 Summary
  • I am using `ipfw` as it is the default to FreeBSD.

  • I am using `fail2ban` in case iRedMail is reinstated on FreeBSD (maybe this text can help).

  • I think SSHGuard worth consideration by iRedMail itself, but not doing it myself to keep it aligned.

5. My environment
  • A virtual server on a small, self-service host provider.

  • A AUD4.00/month, 1GB memory, 20GB disk, the smallest configuration available.

  • I use the provider's external firewall

  • FreeBSD 12.1.

  • Initial iRedMail 1.0 (updated to 1.1, 1.2, 1.2.1 // 1.3.x are not FreeBSD friendly until we move on to Python 3.x).

  • I intend to reinstall all when FreeBSD 12.2 and iRedMail 1.? are 100% OK with each other.

6. Manual steps

I am quite comfortable with Shell Scripts, and I have dug enough on iRedMail to have a good grasp on what it is doing.

I checked and followed most of what iRedMail does related to `fail2ban`, which is currently commented out on FreeBSD.

NOTE: As I am running these statements `manually` AND as `root`, the syntax is `csh` and not `bash`. The `csh` is the default shell for the `root` on FreeBSD. If you are not familiar with FreeBSD, here is a tip: Best Practice: DO NOT change the shell of the `root`!!

6.1 Enable/Start `ipfw`
6.1.1 Create `/usr/local/etc/ipfw.rules`
cat > /usr/local/etc/ipfw.rules << EOF
# NOTE: This set of rules are intended to allow `ipfw` and `fail2ban` to work with each other only.
#       It is [b]NOT[/b] intended to close or protect the server.

# Call initial firewall setup as per FreeBSD's standards using the "OPEN" profile
/bin/sh /etc/rc.firewall open

# Create a Table to hold the IPs worked by fail2ban
# The number "10" is just an ID for the table

if ! ipfw table 10 info > /dev/null 2>&1; then
  ipfw -q table 10 create
  ipfw -q table 10 flush
fi

# create (an early) rule to deny access to the offender on the table
ipfw -q add 00050 deny ip from "table(10)" to me
EOF
6.1.2 Start `ipfw` on every boot
sysrc -f /etc/rc.conf -c firewall_enable=YES
if ( $? ) then
  sysrc firewall_enable="YES"
  sysrc firewall_quiet="YES"
  sysrc firewall_type="OPEN"
  sysrc firewall_script="/usr/local/etc/ipfw.rules"
endif
6.1.3 Start `ipfw`
service ipfw start
6.2 Install `fail2ban`

Using Python 2.7 as it is still the current default for iRedMail.

cd /usr/ports/security/py-fail2ban
make FLAVOR=py27 config install
6.3 Create `fail2ban` action `ipfw-iredmail.conf`

NOTE: This is pretty much the missing link to make `fail2ban` work with iRedMail on FreeBSD, alongside the `/usr/local/etc/ipfw.rules` script above.

cat > /usr/local/etc/fail2ban/action.d/ipfw-iredmail.conf << EOF
[Definition]

actionstart =
actionstop =
actioncheck =
actionban = ipfw table 10 add <ip>
actionunban = ipfw table 10 delete <ip>
EOF
6.4 Configure `fail2ban`

Mostly following the steps from the `~/iRedMail/functions/fail2ban.sh`.

NOTE: The `fail2ban` documentation expressely says to NOT edit the configuration files `fail2ban.conf` and `jail.conf`. It instead recommends to create/edit `fail2ban.local` and `jail.local`.

set IREDMAIL_DIR="~/iRedMail-1.0"
set F2B_CONF="/usr/local/etc/fail2ban/fail2ban.conf"
set F2B_LOCAL="/usr/local/etc/fail2ban/fail2ban.local"
set JAIL_CONF="/usr/local/etc/fail2ban/jail.conf"
set JAIL_LOCAL="/usr/local/etc/fail2ban/jail.local"

echo "# FREEBSD default : logtarget = /var/log/fail2ban.log" > $F2B_LOCAL
echo "# iRedMail default: logtarget = SYSLOG" >> $F2B_LOCAL
echo "# Using configuration from FreeBSD" >> $F2B_LOCAL
set FAIL2BAN_LOGTARGET="SYSLOG"
echo "[DEFAULT]" >> $F2B_LOCAL
echo "#logtarget = $FAIL2BAN_LOGTARGET" >> $F2B_LOCAL

# Disable all default filters in /usr/local/etc/fail2ban/jail.conf.
# FREEBSD default: enabled = false
grep -E "^enabled *= *false" $JAIL_CONF
if ( $? ) then
  sed -i '' -e 's#^\(enabled *\)= *true#\1= false#' $JAIL_CONF
endif

echo "" >> $F2B_LOCAL
echo "# Set proper socket path: /var/run/fail2ban.sock" >> $F2B_LOCAL
echo "# FREEBSD default : '/var/run/fail2ban/fail2ban.sock'" >> $F2B_LOCAL
echo "# iRedMail default: '/var/run/fail2ban.sock'" >> $F2B_LOCAL
echo "# Using configuration from FreeBSD" >> $F2B_LOCAL
set FAIL2BAN_SOCKET="/var/run/fail2ban/fail2ban.sock"
echo "#socket = $FAIL2BAN_SOCKET" >> $F2B_LOCAL

# Create Fail2ban config file: /usr/local/etc/fail2ban/jail.local.
# backup_file /usr/local/etc/fail2ban/jail.local
cp -f $IREDMAIL_DIR/samples/fail2ban/jail.local $JAIL_LOCAL
# $PH_LOCAL_ADDRESS (127.0.0.1/8) already exist in jail.local
set LOCAL_ADDRESS="127.0.0.1"
sed -i '' -e "s#PH_LOCAL_ADDRESS#$LOCAL_ADDRESS#" $JAIL_LOCAL

# Create Fail2ban directory: /usr/local/etc/fail2ban/jail.d.
# FREEBSD: already exists as per instalation
# mkdir -p /usr/local/etc/fail2ban/jail.d
# Copy modular Fail2ban jail config files to /usr/local/etc/fail2ban/jail.d.
cp -f $IREDMAIL_DIR/samples/fail2ban/jail.d/*.local /usr/local/etc/fail2ban/jail.d
# I do not use sogo, so I deleted the jail
rm /usr/local/etc/fail2ban/jail.d/sogo.local

# Mimic the ./conf/core script
set JAIL_D_LOCAL="/usr/local/etc/fail2ban/jail.d/*.local"
set FAIL2BAN_ACTION="ipfw-iredmail"
set SSHD_LOGFILE="/var/log/auth.log"
set HTTPD_LOG_ERRORLOG="/var/log/nginx/error.log"
set RCM_LOGFILE="/var/log/maillog"
set MAILLOG="/var/log/maillog"
# set SOGO_LOG_FILE="???" # I do not use SoGo
set DOVECOT_LOG_DIR="/var/log/dovecot/dovecot.log"
set FAIL2BAN_DISABLED_SERVICES="80,443,25,587,465,110,995,143,993"
set SSHD_PORT="ssh"

# I am old-school. I like awk, sed, etc. I am not familiar with Perl. Do not care for it.
sed -i '' -e "s#PH_FAIL2BAN_ACTION#$FAIL2BAN_ACTION#" $JAIL_D_LOCAL
sed -i '' -e "s#PH_SSHD_LOGFILE#$SSHD_LOGFILE#" $JAIL_D_LOCAL
sed -i '' -e "s#PH_HTTPD_LOG_ERRORLOG#$HTTPD_LOG_ERRORLOG#" $JAIL_D_LOCAL
sed -i '' -e "s#PH_RCM_LOGFILE#$RCM_LOGFILE#" $JAIL_D_LOCAL
sed -i '' -e "s#PH_MAILLOG#$MAILLOG#" $JAIL_D_LOCAL
#sed -i '' -e "s#PH_SOGO_LOG_FILE#$SOGO_LOG_FILE#" $JAIL_D_LOCAL
sed -i '' -e "s#PH_DOVECOT_LOG_FILE#$DOVECOT_LOG_DIR#" $JAIL_D_LOCAL
sed -i '' -e "s#PH_FAIL2BAN_DISABLED_SERVICES#$FAIL2BAN_DISABLED_SERVICES#" $JAIL_D_LOCAL
sed -i '' -e "s#PH_SSHD_PORT#$SSHD_PORT#" $JAIL_D_LOCAL

# Enable Nginx check
grep -E "^enabled *= *true" /usr/local/etc/fail2ban/jail.d/nginx-http-auth.local
if ( $? ) then
  sed -i '' -e 's#false#true#' /usr/local/etc/fail2ban/jail.d/nginx-http-auth.local
endif

# Copy the sample Fail2ban filter config files.
cp -f $IREDMAIL_DIR/samples/fail2ban/filter.d/*.conf /usr/local/etc/fail2ban/filter.d

unset IREDMAIL_DIR
unset F2B_CONF
unset F2B_LOCAL
unset JAIL_CONF
unset JAIL_LOCAL
unset FAIL2BAN_LOGTARGET
unset FAIL2BAN_SOCKET
unset LOCAL_ADDRESS
unset JAIL_D_LOCAL
unset FAIL2BAN_ACTION
unset SSHD_LOGFILE
unset HTTPD_LOG_ERRORLOG
unset RCM_LOGFILE
unset MAILLOG
unset DOVECOT_LOG_DIR
unset FAIL2BAN_DISABLED_SERVICES
unset SSHD_PORT
6.4.1 Start `fail2ban` on every boot
sysrc -f /etc/rc.conf.local fail2ban_enable=YES
7. FreeBSD AND iRedMail AND Fail2ban

The manual process above was based on the current fail2ban script, so not much more needs to be done.

7.1 Extra steps
  • Add `ipfw.rules` to `$IREDMAIL_DIR/sample/firewall/ipfw/` and then copy it over to `/usr/local/etc/`

  • Add `ipfw-iredmail.conf` to `$IREDMAIL_DIR/sample/fail2ban/action.d/` and then copy it over to `/usr/local/etc/fail2ban/action.d/`

  • Configure `ipfw` to run on boot (/etc/rc.conf)

  • Configure `fail2ban` to run on boot (/etc/rc.conf.local)

----

Spider Email Archiver: On-Premises, lightweight email archiving software developed by iRedMail team. Supports Amazon S3 compatible storage and custom branding.

2

Re: fail2ban with FreeBSD

Thanks for sharing.

I was planned to integrate Fail2ban on FreeBSD, but cannot decide whether it's ipfw or pf. sad

3

Re: fail2ban with FreeBSD

ZhangHuangbin wrote:

Thanks for sharing.

I was planned to integrate Fail2ban on FreeBSD, but cannot decide whether it's ipfw or pf. sad

Welcome.

This is a common dilemma. In the end it is just a preference on syntax and maintenance as the package filtering is done inside the kernel. I prefer ipfw as it is already installed. Also pf is a port from OpenBSD, so not always the very last version, has to be compiled. With ipfw just two statements on rc.conf and you are up.

4

Re: fail2ban with FreeBSD

ZhangHuangbin wrote:

I was planned to integrate Fail2ban on FreeBSD, but cannot decide whether it's ipfw or pf. sad

IMHO, pf would be better. It is more popular, so more people have competence in managing it. Moreover, the same code will work for FreeBSD and OpenBSD installations of iRedMail.

5

Re: fail2ban with FreeBSD

From "Absolute FreeBSD" by Michael W. Lucas:

FreeBSD suffers from a wealth of packet filters: IPFW, IP Filter, and PF.
IPFW is the primordial FreeBSD packet filtering software. It’s tightly
integrated with FreeBSD; in fact, the generically named files /etc/rc.firewall
and /etc/rc.firewall6 are purely for IPFW. While quite powerful and very popu-
lar with more experienced FreeBSD administrators, it’s a little difficult for a
beginner.
The second packet filter, IP Filter, is not a FreeBSD-specific firewall
program but is supported on several Unix-like operating systems. It’s pri-
marily the work of one individual, Darren Reed, who has by heroic effort
developed the overwhelming majority of the code and ported it to all those
operating systems. IP Filter is most useful if you want to share one firewall
configuration among multiple operating systems.
We’ll focus on the imaginatively named PF, or packet filter. PF originated
in OpenBSD and was designed to be featureful, flexible, and easy to use.
The average FreeBSD administrator can use PF to achieve almost any effect
possible with the other two packet filters.

6 (edited by Diamond_Head 2021-02-04 21:49:36)

Re: fail2ban with FreeBSD

BTW: In FreeBSD there also is blacklistd: https://docs.freebsd.org/en/books/handb … blacklistd

Also see: https://cryptomonkeys.com/2018/05/freebsd-blacklistd/