@OverWolf
I will give you a (in my humble opinion "simple") solution, but I first will provide some explanation about two points with respect to the basics of Plesk:
1) firewall rules should be simple and fast:
iptables rulesets should be efficient
In every firewall, one can opt for blocking specific IPs and this would often result in huge lists of IPs or CIDR ranges of IPs.
Even the usage of CIDR ranges of the kind 42.224.0.0/12 (one for China) would simplify firewall rulesets, but one still has to add an awful lot of CIDR ranges.
In order to keep the firewall performant AND in order to keep the firewall itself protected (!), a simple set of iptables rulesets should be set.
In essence, that would imply
the policy: one should opt for "
deny all, except for good IPs"
The issue with this policy is that one does not always know what "good IPs are" .......... making this policy only useful for:
- SSH and associated ports: deny all, with the exception of the IPs of sysadmins
- MySQL and associated ports: deny all, with the exception of the local IP (127.0.0.1) and trusted remote machines
and so on.
2) an Apache + Nginx setup is
valuable
Most of the malicious traffic is aimed at your web server (Apache) and the applications hosted by the web server.
One can try to block specific IPs with a firewall ruleset and that
should be done for specific bad crawlbots: just add the IPs or IP ranges via the Plesk Firewall extension.
On the other hand, a lot of IPs from "visitors" cannot be deemed "bad" or "good" upfront: one really does not know.
For instance, many Chinese IP addresses are not associated with malicious traffic, it is often some specific set of CIDR ranges.
Now we have to make decisions on what is good or bad: we can leave that up to Fail2Ban (not recommended) OR we will decide for ourselves (a better idea!).
Suppose we want to block a huge amount of IPs and CIDR ranges.
Blocking them with the firewall makes the firewall contain huge lists of IPs and CIDR ranges...........and that is not always a good idea: performance penalties are present AND even some types of hack attempts are aiming to overload the firewall, in order to get in via a backdoor.
However, most services (SSH, MySQL) are not attacked, if
the policy from point 1 is implemented: hack attempts do not get through the firewall.
Now let's focus on the malicious traffic aimed at Apache (the web server).
It is not recommended to let Apache do all the work when defending against malicious traffic, since Apache is very bad at it and very resource hungry.
Just
adding a layer in front of Apache is an excellent idea:
that "layer" can do all the work that Apache should not!
Nginx is the ideal candidate:
it is efficient, fast, reliable and a default component of Plesk, without much need of customization.
In short, using Nginx in front of Apache allows us to
add a layer of protection.
What about that
solution?
Well, let's define the problem and challenge: we want to block certain CIDR ranges belonging to a specific country.
Hmm, Nginx normally has something like a geoip module, but at the current moment, that module is not shipped with the default Nginx binary of Plesk.
That is too bad, since using the geoip module would involve a database with IPs (and the database has to be updated regularly), which is quite convenient and efficient.
But the convenience of a ready-steady database is not outweighing the discomfort of creating a custom Nginx binary, amongst others due to the facts that (on the one hand) Nginx compilation is not that easy as it might seem and (on the other hand) the custom binary is very likely to be or will be erased when Plesk's default binary gets updated.
So, we should work around that issue by using a fool-proof solution, using the default Nginx directives "deny" and "allow".......
...........and we should know which IPs to block.
We can know the IPs to block by having a look at
Index of /ipcountry (note: this is an example of a site that maintains CIDR lists, one of many).
When clicking on CN.cidr, one gets redirected to a page with subnets associated with China.
The list is a bit "rough" and, normally, one has to do some clean-up.......... however, Nginx does handle potential double entries perfectly fine, so no worries about that!
What we have to do now is the following (steps in chronlogical order)
1 - login to SSH
2 - create a directory with the command: mkdir /CIDR (or any other name for the directory)
3 - cd into /CIDR and run the command: curl -O
http://www.iwik.org/ipcountry/CN.cidr
4 - run the command: grep -r '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' CN.cidr | sort -n | uniq -c | awk -F' ' '{print "deny "$2";"}' > /etc/nginx/conf.d/CN.conf
NOTE: the CN.conf contains all the CIDR ranges belonging to China and those ranges are blocked with the deny directive.
5 - run the command: nginx -t && nginx reload
NOTE: "nginx -t" is a test to perform a check that the nginx config is proper, whereas "nginx reload" is the command to reload all config, including the new CN.conf file.
And that is all there is to it!
In general, the above steps can be repeated for every country that you want to block entirely.
However, note the following:
- one can alter the [countrycode].conf files to allow for some specific ip ranges: just delete the entry in question and run the command from step 5,
- one can use other CIDR ranges then those from the site iwik.org,
- one can create and use a bash script to automate steps 1 to 5 for each country and/or to update the [countrycode].conf files regularly.
The
endresult: you will have a
block of bad IPs where you need it the most, at the application level.
Do not forget to use the firewall (read: iptables) or Plesk Firewall extension on all other crucial services and ports, such as SSH and MySQL!!
Hope the above helps a bit....
Kind regards........