• We value your experience with Plesk during 2024
    Plesk strives to perform even better in 2025. To help us improve further, please answer a few questions about your experience with Plesk Obsidian 2024.
    Please take this short survey:

    https://pt-research.typeform.com/to/AmZvSXkx
  • The Horde webmail has been deprecated. Its complete removal is scheduled for April 2025. For details and recommended actions, see the Feature and Deprecation Plan.
  • We’re working on enhancing the Monitoring feature in Plesk, and we could really use your expertise! If you’re open to sharing your experiences with server and website monitoring or providing feedback, we’d love to have a one-hour online meeting with you.

Resolved Enhance firewall to block services for certain countries

mr-wolf

Silver Pleskian
Plesk Guru
Our Plesk servers need to be accessed from all over the world, but some services are better of when they are only accessible from selected countries.

I created a script that can be easily configured to block some countries.
It is also able to do the reverse. It can open up a port for a certain country.

The core mechanism is provided by ipset
If installed it can manage sets of subnets which can be referenced from iptables.
These country sets are automatically created using country codes and a website which provides all those subnets.

You can give a list of countries that should be whitelisted and a list that should be blacklisted.
To be reliable I can't just reference these sets from a static iptables firewall. These sets may not yet exist. Therefore one half of the script is creating the sets and the other half is adding them to the firewall.

The script does need an entry for that port already in the firewall.
It uses its position in iptables to add an extra iptables row just before that one.

I would recommend to put this script in an hourly cronjob.
Most of the time this script would do nothing, but after some time it will refresh those country lists.
Why an hourly cronjob?
Well, after a reboot all is gone. No sets will survive and also the firewall will be empty or the default one.
Within the hour these country-lines will be added.

In my example I am whitelisting my own country (nl = Netherlands) and blacklisting China and Seychelles (cn,sc)
The whitelist will seek the port 3306 entry and add a whitelist for the Netherlands in front.
It will search for an entry with either DROP or ACCEPT in it
It's not case sensitive so logdrop and logaccept will work too.

Port 8443 and 22 will then be blacklisted for China and Seychelles.

Of course you need to install ipset (apt install ipset).
ipset doesn't run on virtual network adapters.

If your firewall looks like this
iptables --line-numbers -nL INPUT | grep 'dpt:22'
Code:
18   ownservers  tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22
19   bruteprotect  tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22
20   logaccept  tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22
It will look afterward like this:
iptables --line-numbers -nL INPUT | grep 'dpt:22'
Code:
18   ownservers  tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22
19   bruteprotect  tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22
20   DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22 match-set ipset-country-sc src
21   DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22 match-set ipset-country-cn src
22   logaccept  tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22


You can create a ipset-country.conf to overwrite the variables

cat /usr/local/sbin/ipset-country.conf
Code:
WHITE_COUNTRIES=nl,be
BLACK_COUNTRIES=sc,cn,in,pk

WHITE_TCP=
BLACK_TCP=8443,22
WHITE_UDP=
BLACK_UDP=


ln -s /usr/local/sbin/ipset-country /etc/cron.hourly
cat /usr/local/sbin/ipset-country

Code:
#!/bin/bash

HEADLESS=
tty >/dev/null || HEADLESS=true

entries() {
  ipset list $1 2>/dev/null | grep -c '\..*\..*\.'
}

THISSCRIPT="`readlink -f $0`"
BASE=${THISSCRIPT##*/}
[ -z "${BASE}" ] && BASE=${0##*/}

IPDENY_PREFIX=http://ipdeny.com/ipblocks/data/aggregated
IPDENY_POSTFIX=aggregated.zone

WHITE_COUNTRIES=nl,be
BLACK_COUNTRIES=sc,cn

WHITE_TCP=
BLACK_TCP=8443,22
WHITE_UDP=
BLACK_UDP=

# Using a seperate config file makes it easier to distribute the script over more servers
if grep -q "^WHITE_TCP" ${THISSCRIPT}.conf 2>/dev/null ; then
  [ ${HEADLESS} ] || echo "Use the config file ${THISSCRIPT}.conf"
  . ${THISSCRIPT}.conf
fi

# Some sanity checks first

IPTABLES_LENGTH=`iptables-save | grep -c INPUT`
if [ ${IPTABLES_LENGTH} -lt 10 ] ; then
  echo "iptables is less than 10 rows long, there's not much use to go on" >&2
  exit 1
fi

# Check if ipset is installed
if ! ipset -v >/dev/null 2>&1 ; then
  echo "This script relies on ipset, without it this will NOT work!" >&2
  echo "Use sudo apt-get install ipset !!!" >&2
  exit 1
fi

# Check if aggregate is installed
if ! which aggregate 2>&1 >/dev/null ; then
  echo "This script relies on aggregate, without it this will NOT work!" >&2
  echo "Use sudo apt-get install aggregate !!!" >&2
  exit 1
fi

# Now define the 2 core functions

create_set() {
  # remove country IP-list when older than 30 days
  find /tmp -maxdepth 1 -type f -name ${BASE}-${i} -mtime +30 -exec rm {} \;

  if [ ! -f /tmp/${BASE}-${i} ] || [ `entries ${BASE}-${i}` -eq 0 ] ; then
    # Fetch netblocks for this country from the site http://ipdeny.com/ipblocks/data/aggregated
    if wget -qO /tmp/${BASE}-${i}.tmp ${IPDENY_PREFIX}/$i-${IPDENY_POSTFIX} ; then
      # I noticed these aren't always aggregated, so I do this myself
      egrep -o "^[0-9]+\.[0-9]+\.[0-9]+\.[0-9/]+" /tmp/${BASE}-${i}.tmp | aggregate 2>/dev/null >/tmp/${BASE}-${i}
      rm /tmp/${BASE}-${i}.tmp

      # If the file contains CIDR-addresses then continue
      if [ -s /tmp/${BASE}-${i} ] ; then
        [ ${HEADLESS} ] || echo "Create set ${BASE}-${i}"
        # Create the country-set if it does not exist yet
        if ! ipset -exist create ${BASE}-${i} hash:net ; then
          echo -e "\n\nIt seems iptables can't work with ipset, this is probably a virtual machine!!\n\n" >&2
          rm /tmp/${BASE}-${i}
          exit 1
        fi
        # Flush the addresses as we just picked up a fresh list
        ipset flush ${BASE}-${i}
        # Add all the subnets to the set
        while read IPNET ; do
          ipset add ${BASE}-${i} ${IPNET}
        done</tmp/${BASE}-${i}
      fi
    fi
  else
    [ ${HEADLESS} ] || echo "The set ${BASE}-${i} is still current"
  fi
}

add_to_firewall() {

  [ `entries ${BASE}-${i}` -eq 0 ] && return  # only useful if we have a filled set
  # loop through all the ports
  for j in ${PORT//,/ } ; do
    [ ${HEADLESS} ] || echo -e "  ${PROT}:${j} set ${BASE}-${i}"

    # Find the catch-all of this port in the current firewall
    ANCHOR=`iptables --line-numbers -nL INPUT | \
            egrep -i "(ACCEPT|DROP) *${PROT}.*0\.0\.0\.0/0 *0\.0\.0\.0/0 *${PROT} dpt:$j$" | \
            head -n1 | awk '{print $1}'`
    # Did or didn't we find the anchor to attach our iptables lines?
    if [ -z "${ANCHOR}" ] ; then
      echo "Unable to find the anchor for ${PROT} port ${j} in iptables" >&2
    else

      # Find the ipset line for this protocol / port / ipset
      INSERT=`iptables --line-numbers -nL INPUT | \
              grep "${ACTION} *${PROT}.*0\.0\.0\.0/0 *0\.0\.0\.0/0.*${PROT} dpt:$j match-set ${BASE}-${i} src" | \
              head -n1 | awk '{print $1}'`

      if [ -n "${INSERT}" ] ; then
        [ ${HEADLESS} ] || echo -e "\tA line for ${PROT} dpt:$j is already added (${BASE}-${i}) @ ${INSERT}"
      else
        if iptables -I INPUT ${ANCHOR} -p ${PROT} --dport ${j} -m set --match-set ${BASE}-${i} src -j ${ACTION} ; then
          echo -e "\tAdd ${ACTION}-line for port ${j} (set ${BASE}-${i}) @ position ${ANCHOR}"
        else
          echo -e "\n\nIt seems iptables is giving some problem, abort!! " >&2
          exit 1
        fi
      fi
    fi
  done
}

# Let's get to work

[ ${HEADLESS} ] || echo "Create the sets for whitelisting...."
for i in ${WHITE_COUNTRIES//,/ } ; do
  [ ${HEADLESS} ] || echo -n "$i... "
  create_set
done
[ ${HEADLESS} ] || echo -e "\nCreate the sets for blacklisting...."
for i in ${BLACK_COUNTRIES//,/ } ; do
  [ ${HEADLESS} ] || echo -n "$i... "
  create_set
done

[ ${HEADLESS} ] || echo -e "\n\nAdd entries to firewall"
n=1
# Loop 4 times through the firewall script with different parameters
while [ $n -le 4 ] ; do
  [ $n -eq 1 ] && PORT=${WHITE_TCP} && PROT=tcp && COUNTRIES=${WHITE_COUNTRIES} && ACTION=ACCEPT
  [ $n -eq 2 ] && PORT=${WHITE_UDP} && PROT=udp
  [ $n -eq 3 ] && PORT=${BLACK_TCP} && PROT=tcp && COUNTRIES=${BLACK_COUNTRIES} && ACTION=DROP
  [ $n -eq 4 ] && PORT=${BLACK_UDP} && PROT=udp

  for i in ${COUNTRIES//,/ } ; do
    add_to_firewall
  done
  let n+=1
done
 
Last edited:
No, ipset does not work on those...
Code:
ipset v6.29: Kernel error received: Operation not permitted

EDIT ipset does not work on some OpenVZ machines. Support for it needs to be added to the kernel. This can only be done by the hosting provider of the OpenVZ-machines.
 
Last edited:
hi mr-wolf,
I'm tring to implent some country block rules, and I have a question about your example; my iptables look like this :

Code:
13   f2b-SSH    tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22

Can I implement ipset even if I have Fail2Ban to check my ssh ?

Thank you
 
You mean you want to implement ipset-country.
That's the name of my script
ipset is a package that's needed for it.

Yes, but I need to see more as I'm not using fail2ban myself.
I need to see the chain INPUT
The chain f2b-SSH is probably referenced there....

I think I know enough if you show me the output of
Code:
iptables-save | egrep '(f2b-SSH|dport 22)'

My script needs to find a position in the firewall where it can insert itself.
I call this position the "anchor" in my script.
It's the first catch-all it finds in the chain INPUT containing either "DROP" or "ACCEPT" (not case-sensitive)
yours probably doesn't have one


I also need to know if you want to block countries or that you want to accept countries.... (opt-out or opt-in)

I'm noticing a lot of wolves here..... aaauuuuuuuw!!!
 
Last edited:
this is the output

Code:
:f2b-SSH - [0:0]
-A INPUT -p tcp -m tcp --dport 22 -j f2b-SSH
-A f2b-SSH -s 103.89.88.130/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-SSH -j RETURN


..yes...we're wolf...;)
 
Hi OverWolf....

It seems that the default action of your firewall is ACCEPT
I can't see any accept for port 22
Maybe "grep" filtered this line (maybe it uses dports instead of dport)

To be on the safe side you should put this line after "-A INPUT -p tcp -m tcp --dport 22 -j f2b-SSH"

Code:
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT

With this configuration you can block countries, so put the countries you like to block in the script and have port 22 on both whitelist and blacklist
Then run the script....


[EDIT]

If you want to block the world, but open it up for your own country you should first find out the IP's of your own connection.
I mean the connection from which you want to connect to your server (not the server itself)
With "whois <your-ip>" you can find out your ISP's subnet.

I would open up the complete subnet...

Code:
whois 86.90.15.32 | grep ^route
route:          86.88.0.0/13

I don't know if the Plesk server is also connected to a LAN. If so, open that up too.

Open these IP's BEFORE the f2b line
Do not forget to put the script in the hourly cronjob, by creating a symbolic link!!


Code:
-A INPUT -p tcp -m tcp -s 192.168.0.0/16 --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp -s 86.88.0.0/13 --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j f2b-SSH
-A INPUT -p tcp -m tcp --dport 22 -j DROP

After the script has run this will become

cat /usr/local/sbin/ipset-country.conf
Code:
WHITE_COUNTRIES=it
BLACK_COUNTRIES=

WHITE_TCP=22
BLACK_TCP=
WHITE_UDP=
BLACK_UDP=

Code:
-A INPUT -p tcp -m tcp -s 192.168.0.0/16 --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp -s 86.88.0.0/13 --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j f2b-SSH
-A INPUT -p tcp -m tcp --dport 22 -m set --match-set ipset-country-it src -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j DROP

Only Italian IP's can then SSH to your server.
If they try to bruteforce your server they will be blocked by Fail2ban
Only a small subnet has always a connection to your server....

Do not forget that after a reboot your server will NOT have loaded the "country IP's" and SSH access is not possible from an IP outside the manual set.
This could take up to an hour if the symbolic link is in /etc/cron.hourly
 
Last edited:
Hi mr-wolf,
for now I want to set, only black-countries, so I think that the white control I can leave empty...Is it's ok, how can I add "this line after "-A INPUT -p tcp -m tcp --dport 22 -j f2b-SSH" ?
I have create the script and the conf file on /usr/local/sbin, but I cannot understand how can I mod my iptables.. Thank you and excuse for my noob question.
 
I have create the script and the conf file on /usr/local/sbin, but I cannot understand how can I mod my iptables.. Thank you and excuse for my noob question.

Are you using the standard Plesk firewall?
The problem is that I don't....
The first thing I do is remove that firewall after the installation.

My firewall is loaded using an executable script in /etc/network/if-up.d/
This folder exists on a Debian distro (like Ubuntu)

cat /etc/network/if-up.d/iptables
Code:
#!/bin/sh
iptables-restore </etc/iptables.rules

But we need to find out how yours is managed.
On CentOS it's typically this file:

cat /etc/sysconfig/iptables

If you're using the Plesk Firewall you could check this and open up Port 22 explicitly
Adding a rule to the Plesk 12 firewall

Do show me the output of that same iptables-save command
 
When implementing country blocks make sure to be aware of any IP addresses that you need whitelisted (Plesk license checks, the extension directory). For example Plesk license checks need to talk to ka.plesk.com and that server is based out of Russia so if you just block Russia your license checks aren't going to work any more.
 
These are not full blocks, but to certain services.
But you are right. Russia is one of the likely candidates to get blocked and chances are that someone is using out for services that Plesk needs access to.

I believe I once came across a page with Siberian subnets of Plesk.
I will add it to this thread of I have them

AFAIK license checks are pulled not pushed. This firewall extension is about the INPUT chain.
An outgoing connection will be able to communicate because one of the first lines in the INPUT chain is this one:

Code:
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
 
Last edited:
Are you using the standard Plesk firewall?
The problem is that I don't....
The first thing I do is remove that firewall after the installation.

My firewall is loaded using an executable script in /etc/network/if-up.d/
This folder exists on a Debian distro (like Ubuntu)

cat /etc/network/if-up.d/iptables
Code:
#!/bin/sh
iptables-restore </etc/iptables.rules

But we need to find out how yours is managed.
On CentOS it's typically this file:

cat /etc/sysconfig/iptables

If you're using the Plesk Firewall you could check this and open up Port 22 explicitly
Adding a rule to the Plesk 12 firewall

Do show me the output of that same iptables-save command

Hi,
I'm on CentOs 7.3 and there isn't iptables under sysconfig but ip6tables-config and iptables-config.

This is the output of command
Code:
# Generated by iptables-save v1.4.21 on Wed Sep 27 10:10:51 2017
*filter
:INPUT ACCEPT [13:1196]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [6:540]
:f2b-BadBots - [0:0]
:f2b-SSH - [0:0]
:f2b-apache - [0:0]
:f2b-default - [0:0]
:f2b-mySql - [0:0]
:f2b-nginx-bot - [0:0]
:f2b-plesk-dovecot - [0:0]
:f2b-plesk-horde - [0:0]
:f2b-plesk-login - [0:0]
:f2b-plesk-postfix - [0:0]
:f2b-plesk-proftpd - [0:0]
:f2b-plesk-roundcube - [0:0]
:f2b-plesk-wordpress - [0:0]
:f2b-postfix - [0:0]
:f2b-recidive - [0:0]
-A INPUT -p tcp -m multiport --dports 25,465,587 -j f2b-postfix
-A INPUT -p tcp -m multiport --dports 80,443 -j f2b-nginx-bot
-A INPUT -p tcp -m multiport --dports 80,443,7080,7081 -j f2b-plesk-wordpress
-A INPUT -p tcp -m tcp --dport 3306 -j f2b-mySql
-A INPUT -p tcp -j f2b-default
-A INPUT -p tcp -m multiport --dports 8880,8443 -j f2b-plesk-login
-A INPUT -p tcp -m multiport --dports 80,443,7080,7081 -j f2b-BadBots
-A INPUT -p tcp -m multiport --dports 80,443,7080,7081 -j f2b-apache
-A INPUT -p tcp -m multiport --dports 80,443,7080,7081 -j f2b-plesk-roundcube
-A INPUT -p tcp -m multiport --dports 80,443,7080,7081 -j f2b-plesk-horde
-A INPUT -p tcp -m multiport --dports 143,220,993,110,995,4190 -j f2b-plesk-dove                                                       cot
-A INPUT -p tcp -m multiport --dports 25,465,587 -j f2b-plesk-postfix
-A INPUT -p tcp -m multiport --dports 21,20,990,989 -j f2b-plesk-proftpd
-A INPUT -p tcp -j f2b-recidive
-A INPUT -p tcp -m tcp --dport 22 -j f2b-SSH
-A f2b-BadBots -j RETURN
-A f2b-SSH -j RETURN
-A f2b-apache -j RETURN
-A f2b-default -j RETURN
-A f2b-plesk-dovecot -s 82.165.98.27/32 -j REJECT --reject-with icmp-port-unreac                                                       hable
-A f2b-plesk-dovecot -j RETURN
-A f2b-plesk-horde -j RETURN
-A f2b-plesk-login -j RETURN
-A f2b-plesk-postfix -j RETURN
-A f2b-plesk-proftpd -s 220.216.111.35/32 -j REJECT --reject-with icmp-port-unre                                                       achable
-A f2b-plesk-proftpd -j RETURN
-A f2b-plesk-roundcube -j RETURN
-A f2b-plesk-wordpress -j RETURN
-A f2b-postfix -s 185.162.171.131/32 -j REJECT --reject-with icmp-port-unreachab                                                       le
-A f2b-postfix -j RETURN
-A f2b-recidive -s 82.165.98.27/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-recidive -s 58.218.198.169/32 -j REJECT --reject-with icmp-port-unreachab                                                       le
-A f2b-recidive -s 120.132.30.150/32 -j REJECT --reject-with icmp-port-unreachab                                                       le
-A f2b-recidive -j RETURN
COMMIT
# Completed on Wed Sep 27 10:10:51 2017

I'm also trying to implement ipset under f2b, but I have some problem with it (see How can I add a action to fail2ban - iptables-ipset-proto)
 
Your default policy is ACCEPT
So you have in fact not a firewall that's doing much.
Because F2B is handling some special ports you will have those protected by it, but any other port is open.

That's why you don't have a line to open port 22 because all ports are already open
I would suggest for starters to add this line after "-A INPUT -p tcp -m tcp --dport 22 -j f2b-SSH"

Code:
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT

Then run the script and you will see the firewall change

iptables-save | grep 'dport 22 '
Code:
-A INPUT -p tcp -m tcp --dport 22 -j f2b-SSH
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT

ipset-country
iptables-save | grep 'dport 22 '

Code:
-A INPUT -p tcp -m tcp --dport 22 -j f2b-SSH
-A INPUT -p tcp -m tcp --dport 22 -m set --match-set ipset-country-cn src -j DROP
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT

You should consider a firewall where the INPUT chain ends with "-A INPUT -j DROP"
Beware that each port you want your server to listen to has to be explicitly opened.
Now you have NO such line for port 22
 
Hi mr-wolf,
so you suggest to enable plesk firewall or load a firewall like you ?
I would suggest taking small steps.
Be also aware that my script only covers ipv4.
Personally I have disabled ipv6, but this is not a recommendation.

I would, for now, create at least the accept rule for port 22 and run the script.
I would also add an ACCEPT rule for your own IP somewhere before the first f2b rule.
This way you will never be locked out.

Finally add an "all drop rule" at the end of the INPUT chain.
But before you do that you would need to create an ACCEPT rule for each of the F2B rule you have in now...

iptables is very logic and efficient.
It may take some time in the beginning to understand, but working with it it'll come.


[EDIT]
I have no idea how your rules are inserted into your iptables chain
I assume it has something to do with how you implemented F2B.
Is this an extension you have installed?
Maybe others that have this as well can help you with altering its behavior.
As I wrote earlier, I'm managing my firewall with vi and a file that I load with iptables-restore
 
Last edited:
Thank you, mr-wolf.
Fail2Ban is present since 12.5 under security panel from plesk. It's a service that you can activate and configure with a gui. It's a good scanner of log files (Fail2ban) and with 17.5 you have 0.9.6 version. There is a new enhanced version: 0.11.
 
I have installed "fail2ban" in Plesk and I can see it works similar to my own ipset-country script.
It inserts rules into an already existing firewall.

Because you had no firewall installed, it will only have the rules of F2B.

On my firewall it installed itself on ROW 1 of the INPUT chain.

My first rules are:
Code:
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -j REJECT --reject-with tcp-reset
-A INPUT -m state --state INVALID -j loginvalid
-A INPUT -i lo -j ACCEPT

Any insertions of rules should be at least AFTER these 4 lines.
Better yet, it should insert itself before the row of the corresponding port (just like I do in my script).

I will therefore quickly disable this F2B as it's not that smart IMHO.

Back to you....
I would just enable the Plesk firewall as well and restart F2B
 
Last edited:
I have also installed the Plesk firewall and the fail2ban module.
That combination should work together with my ipset-country and these would work together.

The whole thing could be much improved if you take charge yourself of the firewall, but that should be done in a later stage....
 
Hi mr-wolf,
I'm happy that your country script works. I'll install firewall too asap.
I've resolve the problem with f2b and ipset (it works like a charm) and now I'm trying to implement iptables --seconds 1 --hitcount 10 to some port (22, 110, 25....)
 
@mr-wolf and @OverWolf

Nice to read that you are busy with implementing Plesk Firewall extension and Fail2Ban, which can be a good combination.

However, there are some common "good practices" when it concerns Plesk Firewall and Fail2Ban together.

Amongst others:

- Fail2Ban is rather resource hungry: make sure that your Fail2Ban config is proper in the sense that the performance footprint is minimal
- Fail2Ban can allow some hack attempts to go undetected: keep track of your log files to establish whether Fail2Ban misses out on specific hack attempts
- Fail2Ban customization and Fail2Ban usage with Nginx can make the system very strong in terms of security
- Plesk Firewall can be used in combination with Fail2Ban, but there are some pitfalls, which I will explain below

I am focussing on the last point, since the usage of Plesk Firewall extension and Fail2Ban can have some unexpected consequences.

In the light of the above, the following has to be mentioned:

a) Plesk Firewall extension is essentially a GUI for iptables: having Plesk Firewall and Fail2Ban both altering and creatig iptable firewall rules can result in a huge firewall set, which can result in a (relatively) huge performance penalty, even in the case where ipset is being used, (and)

b) Plesk Firewall extension is a GUI that is not showing all iptabels rulesets: as a result, it can be the case that

- manually created firewall rule sets AND rules sets created with Plesk Firewall extension AND firewall rulesets created by Fail2Ban will cause a (lot of) double firewall rules,
- Fail2Ban has to "work harder" if the Plesk Firewall extension is not used to it's full potential and/or to the full extent,

and the overall result is often a significant performance penalty, (and)

c) firewall rulesets have to be persistent (across reboots) and

- Plesk Firewall extension uses a script that results in persistence
- Fail2Ban uses python code to rescan logs at reboot, resulting in persistence
- manual iptables entries are NOT persistent by default

and the overall result is that one has to be careful and take into account that one really has to have persistent iptables rulesets,

and all of the above is non-exhaustive summary of points that have to be taken into consideration.

However, a number of general rules of thumb can be introduced to make life more easy:

1 - use Fail2Ban to detect and temporarily block bad IPs,
2 - use Fail2Ban to detect recurring attempts from bad IPs AND add these bad IPs via the Plesk Firewall extension,
3 - do not OR try to prevent usage of manual iptables entries.

All of the above will result in

- a more efficient Fail2Ban process: most of the recurring attempts from bad IPs are blocked by (persistent!) firewall rules, Fail2Ban does not have to "work hard"
- the probability of double firewall rulesets is decreased significantly
- the chance that important iptables rulesets are non-persistent is almost non-existing

Finally, note that one can use Nginx or ModSec to make the whole system less vulnerable to hack attempts and/or make the entire system more efficient.

Hope the above helps a bit.....

Regards.........
 
Back
Top