mirror of
https://github.com/iredmail/iRedMail
synced 2026-06-08 14:51:59 +00:00
Able to store banned IP addresses in SQL db.
This commit is contained in:
@@ -6,6 +6,9 @@ iRedMail-1.2:
|
||||
- OpenBSD 6.5. Please use the latest stable release 6.6 instead.
|
||||
|
||||
* Improvements:
|
||||
+ Able to store banned IP addresses in SQL db.
|
||||
iRedAdmin-Pro customers can view banned addresses and unban them on
|
||||
web UI directly.
|
||||
+ Fail2ban now works on OpenBSD.
|
||||
+ Track last login of both POP3/IMAP logins, also when new (last one)
|
||||
email was delivered via LMTP/LDA.
|
||||
|
||||
@@ -60,3 +60,7 @@ elif [ X"${KERNEL_NAME}" == X'FREEBSD' ]; then
|
||||
elif [ X"${KERNEL_NAME}" == X'OPENBSD' ]; then
|
||||
export FAIL2BAN_ACTION='pf'
|
||||
fi
|
||||
|
||||
# SQL db.
|
||||
export FAIL2BAN_DB_NAME='fail2ban'
|
||||
export FAIL2BAN_DB_USER='fail2ban'
|
||||
|
||||
+1
-2
@@ -27,8 +27,6 @@
|
||||
export SYS_USER_PGSQL='postgres'
|
||||
export SYS_GROUP_PGSQL='postgres'
|
||||
|
||||
export PGSQL_USER_HOMEDIR='/var/lib/postgresql'
|
||||
|
||||
export PGSQL_RC_SCRIPT_NAME='postgresql'
|
||||
|
||||
export PGSQL_INIT_SQL_SAMPLE="${RUNTIME_DIR}/pgsql_init.pgsql"
|
||||
@@ -52,6 +50,7 @@ elif [ X"${DISTRO}" == X'DEBIAN' -o X"${DISTRO}" == X'UBUNTU' ]; then
|
||||
export PGSQL_VERSION='11'
|
||||
fi
|
||||
|
||||
export PGSQL_USER_HOMEDIR='/var/lib/postgresql'
|
||||
export PGSQL_DATA_DIR="/var/lib/postgresql/${PGSQL_VERSION}/main"
|
||||
export PGSQL_CONF_DIR="/etc/postgresql/${PGSQL_VERSION}/main"
|
||||
export PGSQL_CONF_POSTGRESQL="${PGSQL_CONF_DIR}/postgresql.conf"
|
||||
|
||||
@@ -116,3 +116,7 @@ echo "export SOGO_SIEVE_MASTER_PASSWD='${SOGO_SIEVE_MASTER_PASSWD}'" >> ${IREDMA
|
||||
export random_pw="$(${RANDOM_STRING})"
|
||||
export IREDAPD_DB_PASSWD="${IREDAPD_DB_PASSWD:=${random_pw}}"
|
||||
echo "export IREDAPD_DB_PASSWD='${IREDAPD_DB_PASSWD}'" >> ${IREDMAIL_CONFIG_FILE}
|
||||
|
||||
export random_pw="$(${RANDOM_STRING})"
|
||||
export FAIL2BAN_DB_PASSWD="${FAIL2BAN_DB_PASSWD:=${random_pw}}"
|
||||
echo "export FAIL2BAN_DB_PASSWD='${FAIL2BAN_DB_PASSWD}'" >> ${IREDMAIL_CONFIG_FILE}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
amavisd_initialize_db()
|
||||
{
|
||||
ECHO_DEBUG "Import Amavisd database and privileges."
|
||||
ECHO_DEBUG "Import Amavisd database and grant privileges."
|
||||
|
||||
if [ X"${BACKEND}" == X'OPENLDAP' -o X"${BACKEND}" == X'MYSQL' ]; then
|
||||
${MYSQL_CLIENT_ROOT} <<EOF
|
||||
@@ -59,7 +59,7 @@ EOF
|
||||
cp -f ${SAMPLE_DIR}/amavisd/default_spam_policy.sql ${PGSQL_USER_HOMEDIR}/default_spam_policy.sql >> ${INSTALL_LOG} 2>&1
|
||||
chmod 0777 ${PGSQL_USER_HOMEDIR}/amavisd.sql >/dev/null
|
||||
|
||||
su - ${SYS_USER_PGSQL} -c "psql -d template1" >> ${INSTALL_LOG} <<EOF
|
||||
su - ${SYS_USER_PGSQL} -c "psql -d template1" >> ${INSTALL_LOG} 2>&1 <<EOF
|
||||
-- Create database
|
||||
CREATE DATABASE ${AMAVISD_DB_NAME} WITH TEMPLATE template0 ENCODING 'UTF8';
|
||||
|
||||
|
||||
+79
-14
@@ -19,11 +19,75 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with iRedMail. If not, see <http://www.gnu.org/licenses/>.
|
||||
#---------------------------------------------------------------------
|
||||
_enable_jail() {
|
||||
_jail_conf="${FAIL2BAN_JAIL_CONF_DIR}/${1}"
|
||||
|
||||
fail2ban_config()
|
||||
{
|
||||
ECHO_INFO "Configure Fail2ban (authentication failure monitor)."
|
||||
if [ -e ${_jail_conf} ]; then
|
||||
perl -pi -e 's#(enabled.*=.*)false#${1}true#' ${_jail_conf}
|
||||
fi
|
||||
}
|
||||
|
||||
fail2ban_initialize_db() {
|
||||
ECHO_DEBUG "Import Fail2ban database and grant privileges."
|
||||
|
||||
if [ X"${BACKEND}" == X'OPENLDAP' -o X"${BACKEND}" == X'MYSQL' ]; then
|
||||
${MYSQL_CLIENT_ROOT} <<EOF
|
||||
-- Create database
|
||||
CREATE DATABASE ${FAIL2BAN_DB_NAME} DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||
|
||||
-- Grant privileges
|
||||
GRANT ALL ON ${FAIL2BAN_DB_NAME}.* TO '${FAIL2BAN_DB_USER}'@'${MYSQL_GRANT_HOST}' IDENTIFIED BY '${FAIL2BAN_DB_PASSWD}';
|
||||
|
||||
-- Import Amavisd SQL template
|
||||
USE ${FAIL2BAN_DB_NAME};
|
||||
SOURCE ${SAMPLE_DIR}/fail2ban/sql/fail2ban.mysql;
|
||||
FLUSH PRIVILEGES;
|
||||
EOF
|
||||
|
||||
cat > /root/.my.cnf-${FAIL2BAN_DB_USER} <<EOF
|
||||
[client]
|
||||
host=${MYSQL_SERVER_ADDRESS}
|
||||
port=${MYSQL_SERVER_PORT}
|
||||
user=${FAIL2BAN_DB_USER}
|
||||
password="${FAIL2BAN_DB_PASSWD}"
|
||||
EOF
|
||||
|
||||
elif [ X"${BACKEND}" == X'PGSQL' ]; then
|
||||
cp -f ${SAMPLE_DIR}/fail2ban/sql/fail2ban.pgsql /tmp/fail2ban.pgsql
|
||||
chmod 0755 /tmp/fail2ban.pgsql
|
||||
|
||||
su - ${SYS_USER_PGSQL} -c "psql -d template1" >> ${INSTALL_LOG} <<EOF
|
||||
-- Create database
|
||||
CREATE DATABASE ${FAIL2BAN_DB_NAME} WITH TEMPLATE template0 ENCODING 'UTF8';
|
||||
|
||||
-- Create user
|
||||
CREATE USER ${FAIL2BAN_DB_USER} WITH ENCRYPTED PASSWORD '${FAIL2BAN_DB_PASSWD}' NOSUPERUSER NOCREATEDB NOCREATEROLE;
|
||||
|
||||
ALTER DATABASE ${FAIL2BAN_DB_NAME} OWNER TO ${FAIL2BAN_DB_USER};
|
||||
EOF
|
||||
|
||||
su - ${SYS_USER_PGSQL} -c "psql -U ${FAIL2BAN_DB_USER} -d ${FAIL2BAN_DB_NAME}" >> ${INSTALL_LOG} <<EOF
|
||||
\i /tmp/fail2ban.pgsql;
|
||||
EOF
|
||||
rm -f /tmp/fail2ban.pgsql
|
||||
|
||||
su - ${SYS_USER_PGSQL} -c "psql -U ${FAIL2BAN_DB_USER} -d ${FAIL2BAN_DB_NAME}" >> ${INSTALL_LOG} 2>&1 <<EOF
|
||||
ALTER DATABASE ${FAIL2BAN_DB_NAME} SET bytea_output TO 'escape';
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Copy action config file.
|
||||
cp -f ${SAMPLE_DIR}/fail2ban/action.d/banned_db.conf ${FAIL2BAN_ACTION_DIR}/
|
||||
chmod 0755 ${FAIL2BAN_ACTION_DIR}/banned_db.conf
|
||||
|
||||
# Copy script used to handle sql data.
|
||||
cp -f ${SAMPLE_DIR}/fail2ban/bin/fail2ban_banned_db /usr/local/bin/
|
||||
chmod 0550 /usr/local/bin/fail2ban_banned_db
|
||||
|
||||
echo 'export status_fail2ban_initialize_db="DONE"' >> ${STATUS_FILE}
|
||||
}
|
||||
|
||||
fail2ban_config() {
|
||||
ECHO_DEBUG "Disable all default filters in ${FAIL2BAN_JAIL_CONF}."
|
||||
perl -pi -e 's#^(enabled).*=.*#${1} = false#' ${FAIL2BAN_JAIL_CONF}
|
||||
|
||||
@@ -66,18 +130,19 @@ fail2ban_config()
|
||||
ECHO_DEBUG "Copy sample Fail2ban filter config files."
|
||||
cp -f ${SAMPLE_DIR}/fail2ban/filter.d/*.conf ${FAIL2BAN_FILTER_DIR}
|
||||
|
||||
# Enable Nginx
|
||||
if [ X"${WEB_SERVER}" == X'NGINX' ]; then
|
||||
perl -pi -e 's#(enabled.*=.*)false#${1}true#' ${FAIL2BAN_JAIL_CONF_DIR}/nginx-http-auth.local
|
||||
fi
|
||||
# Enable jail for optional components.
|
||||
[ X"${WEB_SERVER}" == X'NGINX' ] && _enable_jail nginx-http-auth.local
|
||||
[ X"${USE_ROUNDCUBE}" == X'YES' ] && _enable_jail roundcube.local
|
||||
[ X"${USE_SOGO}" == X'YES' ] && _enable_jail sogo.local
|
||||
|
||||
if [ X"${USE_ROUNDCUBE}" == X'YES' ]; then
|
||||
perl -pi -e 's#(enabled.*=.*)false#${1}true#' ${FAIL2BAN_JAIL_CONF_DIR}/roundcube.local
|
||||
fi
|
||||
|
||||
if [ X"${USE_SOGO}" == X'YES' ]; then
|
||||
perl -pi -e 's#(enabled.*=.*)false#${1}true#' ${FAIL2BAN_JAIL_CONF_DIR}/sogo.local
|
||||
fi
|
||||
[ X"${DISTRO}" == X'OPENBSD' ] && service_control enable fail2ban >> ${INSTALL_LOG} 2>&1
|
||||
|
||||
echo 'export status_fail2ban_config="DONE"' >> ${STATUS_FILE}
|
||||
}
|
||||
|
||||
fail2ban_setup() {
|
||||
ECHO_INFO "Configure Fail2ban (authentication failure monitor)."
|
||||
|
||||
check_status_before_run fail2ban_initialize_db
|
||||
check_status_before_run fail2ban_config
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ netdata_install()
|
||||
|
||||
netdata_config()
|
||||
{
|
||||
ECHO_INFO "Configure netdata."
|
||||
ECHO_INFO "Configure netdata (system and application monitor)."
|
||||
|
||||
# Disable sending anonymouse statistics to netdata cloud.
|
||||
touch ${NETDATA_CONF_DIR}/.opt-out-from-anonymous-statistics
|
||||
|
||||
@@ -11,18 +11,22 @@ optional_components()
|
||||
check_status_before_run iredapd_setup
|
||||
|
||||
# iRedAdmin.
|
||||
[ X"${USE_IREDADMIN}" == X'YES' ] && check_status_before_run iredadmin_setup
|
||||
[ X"${USE_IREDADMIN}" == X'YES' ] && \
|
||||
check_status_before_run iredadmin_setup
|
||||
|
||||
# Roundcubemail.
|
||||
[ X"${USE_ROUNDCUBE}" == X'YES' ] && check_status_before_run rcm_setup
|
||||
[ X"${USE_ROUNDCUBE}" == X'YES' ] && \
|
||||
check_status_before_run rcm_setup
|
||||
|
||||
# SOGo
|
||||
[ X"${USE_SOGO}" == X'YES' ] && check_status_before_run sogo_setup
|
||||
|
||||
# netdata.
|
||||
[ X"${USE_NETDATA}" == X'YES' ] && check_status_before_run netdata_setup
|
||||
[ X"${USE_SOGO}" == X'YES' ] && \
|
||||
check_status_before_run sogo_setup
|
||||
|
||||
# Fail2ban.
|
||||
[ X"${USE_FAIL2BAN}" == X'YES' -a X"${DISTRO}" != X'FREEBSD' ] && \
|
||||
check_status_before_run fail2ban_config
|
||||
check_status_before_run fail2ban_setup
|
||||
|
||||
# netdata.
|
||||
[ X"${USE_NETDATA}" == X'YES' ] && \
|
||||
check_status_before_run netdata_setup
|
||||
}
|
||||
|
||||
+10
-9
@@ -436,20 +436,21 @@ EOF
|
||||
ALL_PKGS="${ALL_PKGS} py-pip py-jinja2 py-webpy py-flup py-bcrypt py-curl py-requests py-netifaces"
|
||||
fi
|
||||
|
||||
# Fail2ban
|
||||
# Fail2ban. Install fail2ban and geoip.
|
||||
if [ X"${USE_FAIL2BAN}" == X'YES' ]; then
|
||||
ENABLED_SERVICES="${ENABLED_SERVICES} fail2ban"
|
||||
|
||||
if [ X"${DISTRO}" == X'OPENBSD' ]; then
|
||||
if [ X"${DISTRO}" == X'RHEL' ]; then
|
||||
[[ X"${DISTRO_VERSION}" == X'7' ]] && ALL_PKGS="${ALL_PKGS} fail2ban GeoIP GeoIP-data"
|
||||
[[ X"${DISTRO_VERSION}" == X'8' ]] && ALL_PKGS="${ALL_PKGS} fail2ban GeoIP GeoIP-GeoLite-data"
|
||||
|
||||
DISABLED_SERVICES="${DISABLED_SERVICES} shorewall gamin gamin-python"
|
||||
elif [ X"${DISTRO}" == X'DEBIAN' -o X"${DISTRO}" == X'UBUNTU' ]; then
|
||||
ALL_PKGS="${ALL_PKGS} fail2ban geoip-bin geoip-database"
|
||||
elif [ X"${DISTRO}" == X'OPENBSD' ]; then
|
||||
# No port for fail2ban. Install from source tarball with pip later.
|
||||
# rc script will be generated from sample file later.
|
||||
ALL_PKGS="${ALL_PKGS} py-pip py3-pip"
|
||||
else
|
||||
ALL_PKGS="${ALL_PKGS} fail2ban"
|
||||
|
||||
if [ X"${DISTRO}" == X'RHEL' ]; then
|
||||
DISABLED_SERVICES="${DISABLED_SERVICES} shorewall gamin gamin-python"
|
||||
fi
|
||||
ALL_PKGS="${ALL_PKGS} py-pip py3-pip GeoIP geolite-country"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -113,6 +113,7 @@ EOF
|
||||
*:*:*:${SOGO_DB_USER}:${SOGO_DB_PASSWD}
|
||||
*:*:*:${RCM_DB_USER}:${RCM_DB_PASSWD}
|
||||
*:*:*:${AMAVISD_DB_USER}:${AMAVISD_DB_PASSWD}
|
||||
*:*:*:${FAIL2BAN_DB_USER}:${FAIL2BAN_DB_PASSWD}
|
||||
EOF
|
||||
|
||||
chown ${SYS_USER_PGSQL}:${SYS_GROUP_PGSQL} ${PGSQL_DOT_PGPASS}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# - Store banned IP in SQL db while it's banned.
|
||||
# - Remove banned IP from SQL db while it's unbanned.
|
||||
|
||||
[Definition]
|
||||
actionstart =
|
||||
actioncheck =
|
||||
|
||||
actionban = /usr/local/bin/fail2ban_banned_db ban <ip> <port> <protocol> <name>
|
||||
actionunban = /usr/local/bin/fail2ban_banned_db unban <ip>
|
||||
|
||||
# Each time Fail2ban is stopped or restarted, `actionstop` will be executed,
|
||||
# so the SQL table will be empty each time it stopped or restarted.
|
||||
actionstop = /usr/local/bin/fail2ban_banned_db cleanup <name>
|
||||
@@ -0,0 +1,199 @@
|
||||
#!/usr/bin/env bash
|
||||
# Author: Zhang Huangbin <zhb@iredmail.org>
|
||||
# Puprpose:
|
||||
# - Store banned IP address in SQL db while it's banned.
|
||||
# - Remove unbanned IP address from SQL db while it's unbanned.
|
||||
# - Unban IP addresses which have column `remove=1`.
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# *) Store a banned IP address:
|
||||
#
|
||||
# banned_db ban <ip> <ports> <protocol> <jail>
|
||||
#
|
||||
# - <ip>: One IP address each time.
|
||||
# - <ports>: Network ports. Multiple ports must be separated by comma.
|
||||
# - <protocol>: `tcp` or `udp`.
|
||||
# - <jail>: Fail2ban jail name.
|
||||
#
|
||||
# *) Remove an one or multiple unbanned IP addresses. Notes:
|
||||
#
|
||||
# - it removes IP from all jails.
|
||||
# - multiple IP addresses must be separated by space.
|
||||
#
|
||||
# banned_db unban <ip> [ip] [ip]
|
||||
#
|
||||
# *) Cleanup a jail. When Fail2ban is stopping or restarting, `cleanup` will
|
||||
# be executed. Cleanup manually is supported too:
|
||||
#
|
||||
# banned_db cleanup <jail>
|
||||
#
|
||||
# *) Query SQL db and remove IP addresses which have `remove=1`.
|
||||
#
|
||||
# banned_db unban_db
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# banned_db ban 192.168.0.1 110,143,993,995 tcp dovecot-iredmail
|
||||
# banned_db unban 192.168.0.1
|
||||
# banned_db cleanup dovecot-iredmail
|
||||
# banned_db unban_db
|
||||
|
||||
#
|
||||
# Sample Fail2ban jail config file (/etc/fail2ban/jail.d/xx.local):
|
||||
#
|
||||
# [jail-name]
|
||||
# ...
|
||||
# action = ...[your other actions here]...
|
||||
# banned_db[name=jail-name, port="80", protocol=tcp]
|
||||
#
|
||||
# WARNING: the name set in `banned_db[name=]` must be same as the jail name.
|
||||
|
||||
export DB_NAME="fail2ban"
|
||||
export DB_TABLE="banned"
|
||||
export DB_USER="fail2ban"
|
||||
|
||||
# GeoIP
|
||||
export CMD_GEOIPLOOKUP="$(which geoiplookup)"
|
||||
export CMD_GEOIPLOOKUP6="$(which geoiplookup6)"
|
||||
|
||||
if [ -f /root/.my.cnf-fail2ban ]; then
|
||||
export CMD_SQL="mysql --defaults-file=/root/.my.cnf-fail2ban ${DB_NAME}"
|
||||
export DB_TYPE="mysql"
|
||||
elif [ -f /root/.my.cnf ]; then
|
||||
export CMD_SQL="mysql --defaults-file=/root/.my.cnf ${DB_NAME}"
|
||||
export DB_TYPE="mysql"
|
||||
else
|
||||
# Absolute path to ~/.pgpass
|
||||
# - RHEL: /var/lib/pgsql/.pgpass
|
||||
# - Debian/Ubuntu: /var/lib/postgresql/.pgpass
|
||||
# - FreeBSD: /var/db/postgres/.pgpass
|
||||
# - OpenBSD: /var/postgresql/.pgpass
|
||||
for dir in \
|
||||
/var/lib/pgsql \
|
||||
/var/lib/postgresql \
|
||||
/var/db/postgres \
|
||||
/var/postgresql; do
|
||||
if [ -f ${dir}/.pgpass ]; then
|
||||
export PGPASSFILE="${dir}/.pgpass"
|
||||
export CMD_SQL="psql -U ${DB_USER} -d ${DB_NAME}"
|
||||
export DB_TYPE="pgsql"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ X"${CMD_SQL}" == X'' ]; then
|
||||
echo "No MySQL or PostgreSQL related config file found. Abort."
|
||||
echo " - MySQL: /root/.my.cnf-fail2ban (or /root/.my.cnf)"
|
||||
echo " - PostgreSQL: ~/.pgpass (under PostgreSQL daemon user's home directory)"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
export _action="$1"
|
||||
|
||||
if [[ X"${_action}" == X"ban" ]]; then
|
||||
_ip="${2}"
|
||||
_ports="${3}"
|
||||
_protocol="${4}"
|
||||
_jail="${5}"
|
||||
|
||||
if [[ X"${_ip}" == X'' ]] || \
|
||||
[[ X"${_ports}" == X'' ]] || \
|
||||
[[ X"${_protocol}" == X'' ]] || \
|
||||
[[ X"${_jail}" == X'' ]]; then
|
||||
echo "IP, ports, protocol, or jail name is empty. Abort."
|
||||
exit 255
|
||||
fi
|
||||
|
||||
_hostname="$(hostname)"
|
||||
|
||||
# Lookup for country name.
|
||||
_country=''
|
||||
if echo ${_ip} | grep ':' &>/dev/null; then
|
||||
if [[ -x ${CMD_GEOIPLOOKUP6} ]]; then
|
||||
_country="$(${CMD_GEOIPLOOKUP6} ${_ip} | grep '^GeoIP Country Edition:' | awk -F': ' '{print $2}')"
|
||||
fi
|
||||
else
|
||||
if [[ -x ${CMD_GEOIPLOOKUP} ]]; then
|
||||
_country="$(${CMD_GEOIPLOOKUP} ${_ip} | grep '^GeoIP Country Edition:' | awk -F': ' '{print $2}')"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ X"${DB_TYPE}" == X'mysql' ]; then
|
||||
${CMD_SQL} <<EOF
|
||||
INSERT IGNORE INTO ${DB_TABLE} (ip, ports, protocol, jail, hostname, country) VALUES ('${_ip}', '${_ports}', '${_protocol}', '${_jail}', '${_hostname}', '${_country}');
|
||||
EOF
|
||||
else
|
||||
# CentOS 7 ships PostgreSQL-9.2 which doesn't support `ON CONFLICT DO NOTHING`,
|
||||
# so we query it first, insert it if not existing.
|
||||
(${CMD_SQL} <<EOF
|
||||
SELECT id FROM ${DB_TABLE} WHERE ip='${_ip}' AND ports='${_ports}' AND protocol='${_protocol}' AND jail='${_jail}' LIMIT 1;
|
||||
EOF
|
||||
) | grep '1 row' &>/dev/null
|
||||
|
||||
if [[ X"$?" == X'0' ]]; then
|
||||
echo "Already banned."
|
||||
else
|
||||
${CMD_SQL} >/dev/null <<EOF
|
||||
INSERT INTO ${DB_TABLE} (ip, ports, protocol, jail, hostname, country) VALUES ('${_ip}', '${_ports}', '${_protocol}', '${_jail}', '${_hostname}', '${_country}');
|
||||
EOF
|
||||
echo "Stored."
|
||||
fi
|
||||
fi
|
||||
|
||||
elif [[ X"${_action}" == X"unban" ]]; then
|
||||
shift 1
|
||||
_ips="$@"
|
||||
|
||||
if [[ X"${_ips}" == X'' ]]; then
|
||||
echo "No IP address(es) specified."
|
||||
else
|
||||
for _ip in ${_ips}; do
|
||||
${CMD_SQL} <<EOF
|
||||
DELETE FROM ${DB_TABLE} WHERE ip='${_ip}';
|
||||
EOF
|
||||
done
|
||||
|
||||
[[ X"$?" == X'0' ]] && echo "Removed."
|
||||
fi
|
||||
|
||||
elif [[ X"${_action}" == X"cleanup" ]]; then
|
||||
_jail="$2"
|
||||
|
||||
if [[ X"${_jail}" != X'' ]]; then
|
||||
${CMD_SQL} <<EOF
|
||||
DELETE FROM ${DB_TABLE} WHERE jail='${_jail}';
|
||||
EOF
|
||||
fi
|
||||
|
||||
[[ X"$?" == X'0' ]] && echo "All IP addresses have been removed."
|
||||
elif [[ X"${_action}" == X"unban_db" ]]; then
|
||||
# Call fail2ban-client to unban given IP address(es).
|
||||
tmp_file="$(mktemp)"
|
||||
|
||||
# Exclude extra info on output, just leave jail/ip.
|
||||
(${CMD_SQL} <<EOF
|
||||
SELECT jail, ip FROM ${DB_TABLE} WHERE remove=1;
|
||||
EOF
|
||||
) | grep -Ev '(jail.*ip|\--|\(|^$)' | tr -d '|' >> ${tmp_file}
|
||||
|
||||
while read jail ip; do
|
||||
# Avoid SQL injection: don't allow whitespace, ';', quotes in
|
||||
# jail name and IP address.
|
||||
if echo ${jail} | grep "[ ;\"\']" &>/dev/null; then
|
||||
echo "[WARNING] Invalid jail name: '${jail}'."
|
||||
continue
|
||||
fi
|
||||
|
||||
if echo ${ip} | grep "[ ;\"\']" &>/dev/null; then
|
||||
echo "[WARNING] Invalid IP address: '${ip}'."
|
||||
continue
|
||||
fi
|
||||
|
||||
# fail2ban-client returns number of processed rows on command line,
|
||||
# let's discard it to avoid noise/confusion.
|
||||
fail2ban-client set ${jail} unbanip ${ip} >/dev/null
|
||||
[[ X"$?" == X'0' ]] && echo "Unbanned ${ip} from jail [${jail}]."
|
||||
done < ${tmp_file}
|
||||
rm -f ${tmp_file} &>/dev/null
|
||||
fi
|
||||
@@ -1,5 +1,6 @@
|
||||
[dovecot-iredmail]
|
||||
enabled = true
|
||||
filter = dovecot.iredmail
|
||||
action = PH_FAIL2BAN_ACTION[name=dovecot, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
logpath = PH_DOVECOT_LOG_FILE
|
||||
action = PH_FAIL2BAN_ACTION[name=dovecot, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
banned_db[name=dovecot, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
[nginx-http-auth]
|
||||
enabled = false
|
||||
filter = nginx-http-auth
|
||||
action = PH_FAIL2BAN_ACTION[name=nginx, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
logpath = PH_NGINX_LOG_ERRORLOG
|
||||
action = PH_FAIL2BAN_ACTION[name=nginx, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
banned_db[name=nginx, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
[postfix-pregreet-iredmail]
|
||||
enabled = true
|
||||
maxretry = 1
|
||||
filter = postfix-pregreet.iredmail
|
||||
logpath = PH_MAILLOG
|
||||
maxretry = 1
|
||||
action = PH_FAIL2BAN_ACTION[name=postfix, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
banned_db[name=postfix, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
[postfix-iredmail]
|
||||
enabled = true
|
||||
filter = postfix.iredmail
|
||||
action = PH_FAIL2BAN_ACTION[name=postfix, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
logpath = PH_MAILLOG
|
||||
action = PH_FAIL2BAN_ACTION[name=postfix, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
banned_db[name=postfix, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
[roundcube-iredmail]
|
||||
enabled = false
|
||||
filter = roundcube.iredmail
|
||||
action = PH_FAIL2BAN_ACTION[name=roundcube, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
logpath = PH_RCM_LOGFILE
|
||||
findtime = 3600
|
||||
filter = roundcube.iredmail
|
||||
logpath = PH_RCM_LOGFILE
|
||||
action = PH_FAIL2BAN_ACTION[name=roundcube, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
banned_db[name=roundcube, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
[sogo-iredmail]
|
||||
enabled = false
|
||||
filter = sogo-auth
|
||||
action = PH_FAIL2BAN_ACTION[name=sogo, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
logpath = PH_SOGO_LOG_FILE
|
||||
action = PH_FAIL2BAN_ACTION[name=sogo, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
banned_db[name=sogo, port="PH_FAIL2BAN_DISABLED_SERVICES", protocol=tcp]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
[sshd]
|
||||
enabled = true
|
||||
filter = sshd
|
||||
action = PH_FAIL2BAN_ACTION[name=sshd, port="PH_SSHD_PORT", protocol=tcp]
|
||||
logpath = PH_SSHD_LOGFILE
|
||||
action = PH_FAIL2BAN_ACTION[name=sshd, port="PH_SSHD_PORT", protocol=tcp]
|
||||
banned_db[name=sshd, port="PH_SSHD_PORT", protocol=tcp]
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
--
|
||||
-- Used to store banned/unbanned clients
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `banned` (
|
||||
`id` BIGINT(20) UNSIGNED AUTO_INCREMENT,
|
||||
-- Banned client IP address
|
||||
`ip` VARCHAR(46) NOT NULL DEFAULT '',
|
||||
-- A list of banned network ports, separated by comma
|
||||
`ports` VARCHAR(50) NOT NULL DEFAULT '',
|
||||
-- protocol: tcp, udp, ...
|
||||
`protocol` VARCHAR(10) NOT NULL DEFAULT 'tcp',
|
||||
-- Fail2ban jail name
|
||||
`jail` VARCHAR(30) NOT NULL DEFAULT 'INPUT',
|
||||
-- The server hostname which the ban/unban happens
|
||||
`hostname` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`country` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
-- When the ban happens
|
||||
`timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
-- if `remove=1`, `ip` will be removed by cron job.
|
||||
`remove` TINYINT(1) DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX (`ip`, `ports`, `protocol`),
|
||||
INDEX (`hostname`),
|
||||
INDEX (`jail`),
|
||||
INDEX (`country`),
|
||||
INDEX (`timestamp`),
|
||||
INDEX (`remove`)
|
||||
) ENGINE=InnoDB;
|
||||
@@ -0,0 +1,28 @@
|
||||
--
|
||||
-- Used to store banned/unbanned clients
|
||||
--
|
||||
CREATE TABLE banned (
|
||||
id SERIAL PRIMARY KEY,
|
||||
-- Banned client IP address
|
||||
ip VARCHAR(46) NOT NULL DEFAULT '',
|
||||
-- A list of banned network ports, separated by comma
|
||||
ports VARCHAR(50) NOT NULL DEFAULT '',
|
||||
-- protocol: tcp, udp, ...
|
||||
protocol VARCHAR(10) NOT NULL DEFAULT 'tcp',
|
||||
-- Fail2ban jail name
|
||||
jail VARCHAR(30) NOT NULL DEFAULT '',
|
||||
-- The server hostname which the ban/unban happens
|
||||
hostname VARCHAR(255) NOT NULL DEFAULT '',
|
||||
country VARCHAR(255) NOT NULL DEFAULT '',
|
||||
-- When the ban happens
|
||||
timestamp TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT (CURRENT_TIMESTAMP(0) AT TIME ZONE 'UTC'),
|
||||
-- if `remove=1`, `ip` will be removed by cron job.
|
||||
remove INT2 DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_banned_ip_ports_protocol ON banned (ip, ports, protocol);
|
||||
CREATE INDEX idx_banned_jail ON banned (jail);
|
||||
CREATE INDEX idx_banned_hostname ON banned (hostname);
|
||||
CREATE INDEX idx_banned_country ON banned (country);
|
||||
CREATE INDEX idx_banned_timestamp ON banned (timestamp);
|
||||
CREATE INDEX idx_banned_remove ON banned (remove);
|
||||
Reference in New Issue
Block a user