3

I'm looking for a good way to block an entire IP range using htaccess.

The problem I'm having is that the block I need to ban is 100 IP ranges big. From a programmers perspective it should be easily doable, but I'm failing to get it done without adding 100 lines in my htaccess, and other techniques I tried did not work.

The IP Address range I need to block is for HUAWEI Clouds: 159.138.100.* - 159.138.199.*

A keen eye spots that basically 159.138.1 is enough to block.

I tried the following without success:

Order Allow,Deny
Deny from 159.138.1
Allow from all

I also tried:

Order Allow,Deny
Deny from 159.138.1*
Allow from all

How can I block this iprange effectively using .htaccess?

  • You can specify partial IP addresses (whole bytes only) of the form 159.138. Or use CIDR notation that Stephen mentions. What version of Apache are you using? – MrWhite Sep 11 at 14:19
  • Feel free to post an answer on the partial IP addresses match. I think that is what I tried in the first place but did not work. I'm renting shared webhosting. Not sure what version of Apache they are using, but they are a company that keep things up-to-date. So I expect that they have one of the latest versions. Is there a way I can find out what version of Apache is running? – LPChip Sep 11 at 14:45
  • Deny etc. are really Apache 2.2 directives. It is more likely you are on Apache 2.4+ (Apache 2.2 was officially end-of-life on 2018-01-01). To find the Apache version you can perhaps check the Server: HTTP response header. However, some shared hosts restrict this to simply report Apache and not the version. Failing that, you may need to ask the host. Trying an Apache 2.4 directive (as mentioned in my answer) on an Apache 2.2 system would result in a 500 Internal Server Error. – MrWhite Sep 12 at 12:02
  • Any command I can run in shell to get the apache version? I do have shell access. – LPChip Sep 12 at 13:09
  • 1
    Yes, that's OK. I would expect Stephen's answer to work OK for quite some "years". – MrWhite Sep 12 at 16:56
3

IP ranges are specified in .htaccess using CIDR notation. The simplest rule that you could use would be

Deny from 159.138.0.0/16

Which would block slightly too much:

CIDR Range      159.138.0.0/16
Netmask         255.255.0.0
Wildcard Bits   0.0.255.255
First IP        159.138.0.0
Last IP         159.138.255.255
Total Host      65536

To block the exact range of 159.138.100.0 to 159.138.199.255 you would need several rules:

Deny from 159.138.100.0/22
Deny from 159.138.104.0/21
Deny from 159.138.112.0/20
Deny from 159.138.128.0/18
Deny from 159.138.192.0/21

Source: IP Range to CIDR calculator

I'm not sure where you got the IP range you are working with. This site lists 74 CIDR ranges for Huawai cloud service

  • I'm being flooded with bots all from the 159.138.1xx.xxx range. If I grab a random ip from the pool and do a whois against it, it tells me huawei clouds. Maybe they are fake, I dunno, but whatever they are, I want to block them. Your solution seems perfect though. Will implement it, and if the visits stop, you earned your checkmark. :) – LPChip Sep 11 at 12:30
  • Yes, this worked. I used the 5 denies. It is not exactly 100 to 199, but given the massive amount of ip addresses and they all start with the 1, not 2 nor 0, I'm going to ban that entire range. Thank you so much. :) Finally my stats will show proper numbers again. :) – LPChip Sep 11 at 12:32
2
Deny from 159.138.1

You can specify partial IP addresses, but only so far as whole bytes. So, you could write:

Deny from 159.138

Which is the same as 159.138.0.0/16 using CIDR notation - which "would block slightly too much" (as mentioned).

Failing that, using multiple CIDR ranges, as @Stephen mentions in his answer is probably the way to go.


159.138.100.* - 159.138.199.*

However, this does lend it itself to a relatively simple regular expression match on the IP address. For example:

SetEnvIf Remote_Addr ^159\.138\.1\d\d BLOCKIT
Deny from env=BLOCKIT

The SetEnvIf directive sets a BLOCKIT environment variable if the remote IP address matches the stated regex. And the Deny directive is triggered if this env var is set. \d is a shorthand character class that matches any digit 0-9.

basically 159.138.1 is enough to block.

For that you could simplify the regex to ^159\.138\.1 (ie. remove the trailing \d\d). Although this would block 11 additional IP addresses.

Not sure what version of Apache they are using, but they are a company that keep things up-to-date. So I expect that they have one of the latest versions.

In that case you are far more likely to be on Apache 2.4. The "problem" now is that Deny is really an Apache 2.2 directive. It is still available in Apache 2.4 - for backwards compatibility only (and has been moved to a different module) - and is formerly deprecated (so will be removed entirely in future versions).

An added complication is that you should really update all instances of the old Order, Deny, Allow directives to the new Require directive throughout the system otherwise you can get unexpected conflicts (since one does not necessarily override the other).

Reference:
https://httpd.apache.org/docs/2.4/mod/mod_access_compat.html

For example, converting the multiple Deny CIDR directives from @Stephen's answer to use Apache 2.4 Require would give:

<RequireAll>
    Require all granted
    Require not ip 159.138.100.0/22
    Require not ip 159.138.104.0/21
    Require not ip 159.138.112.0/20
    Require not ip 159.138.128.0/18
    Require not ip 159.138.192.0/21
</RequireAll>

(Slightly counter intuitive is that negated directives, eg. Require not ..., cannot themselves allow or deny access, hence why the above needs to be enclosed in a <RequireAll> directive with a Require all granted directive.)

Or, you could use Apache 2.4+ expressions and match the IP address using a regex (similar to above). For example:

<If "%{REMOTE_ADDR} =~ /^159\.138\.1\d\d/">
    Require all denied
</If>

Or, match the "overly general" IP range using CIDR notation:

<If "-R '159.138.0.0/16'">
    Require all denied
</If>

Reference:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.