logo
Apache Lounge
Webmasters

 

About Forum Index Downloads Search Register Log in  RSS Apache Lounge  


Keep Server Online

If you find the Apache Lounge, the downloads and overall help useful, please express your satisfaction with a donation.

or

Bitcoin

A donation makes a contribution towards the costs, the time and effort that's going in this site and building.

Thank You! Steffen

Your donations will help to keep this site alive and well, and continuing building binaries. Apache Lounge is not sponsored.


Post new topic   Forum Index -> Apache View previous topic :: View next topic
Reply to topic   Topic: [SOLVED] Apache 2.4 - deny access to IP's that are not ban
Author
syscon



Joined: 10 Feb 2021
Posts: 4
Location: Canada

PostPosted: Wed 10 Feb '21 17:11    Post subject: [SOLVED] Apache 2.4 - deny access to IP's that are not ban Reply with quote

Apache-2.4.46 (Linux)

In .htaccess file I have a long list of IP-subnets (over 500-subnets) that I ban (mostly spammers).
But I've notices that my .htaccess prevent access to customers from IP that are not on the ban list.

In the .htaccess the IP's are listed in numerical order, eg.:
Code:
<Files history.txt>
        Require all denied
</Files>

<RequireAll>
Require all granted

# block spammers:
...
Require not ip 152.32.186.0/24
Require not ip 157.230.0.0/16
Require not ip 157.7.160.0/22
Require not ip 158.255.128.0/19
...
</RequireAll>

apache log:
Code:

157.55.39.252 - - [09/Feb/2021:17:04:33 -0700] "GET /product_info.php HTTP/1.1" 403 199

The above user is from Microsoft Network
CIDR: 157.60.0.0/16, 157.54.0.0/15, 157.56.0.0/14
that does not appear on my list.

So why my configuration is blocking that user?

The apache .htaccess just blocked IP: 159.14.184.11
this is "Organization: The Children's Hospital of hiladelphia"
CIDR: 159.14.0.0/16

and that CIDR is not on my list, why apache is locking it?
Do these IP subnets need to be sorted in order for them to work correctly?

I can post them here if somebody wants to test it, if it is OK. They are just subdomains not an individual IP's.


Last edited by syscon on Fri 12 Feb '21 16:44; edited 1 time in total
Back to top
tangent



Joined: 16 Aug 2020
Posts: 69
Location: UK

PostPosted: Fri 12 Feb '21 16:27    Post subject: Reply with quote

Your sample list of entries isn't sorted numerically, so if you've really some 500 entries in the list, and they're not sorted either, the chances of an error in the network IP or CIDR number somewhere must increase.

Once sorted, scan and check the IP ranges for overlap, for those CIDR entries around problem IP areas, e.g. via an online CIDR checker https://www.ipaddressguide.com/cidr

An error in the CIDR number can easily reduce the lower end of an IP range, e.g. 159.14.0.0/11 defines a range 159.0.0.0 => 159.31.255.255
Back to top
syscon



Joined: 10 Feb 2021
Posts: 4
Location: Canada

PostPosted: Fri 12 Feb '21 16:44    Post subject: Reply with quote

Thanks for reply. Yes, it was an error on my part.
One of my CIDR was listed as: 212.129.0.0/1

When coping, I missed the second digit after the "/" so I managed to knock out big part of network :-/

To solve this problem, one has to compare IP (that is being ban) to list of CIDR's. Doing it manually would be a lot of work; but I got help from Travis (very nice fellow) of Apache development forum and he help me with this, how to do it quick and efficient.
If somebody is interested I can provide more input.
Back to top
tangent



Joined: 16 Aug 2020
Posts: 69
Location: UK

PostPosted: Fri 12 Feb '21 17:17    Post subject: Reply with quote

I'm sure Apache Lounge users would appreciate you posting alternative solutions in a new topic.

In the past I have used mod_rewrite with a RewriteMap file containing a full list of denied IP's (expanded from a CIDR list using a Perl script). The map file gets cached at Apache startup, and is reloaded automatically if the timestamp gets updated.
Back to top
syscon



Joined: 10 Feb 2021
Posts: 4
Location: Canada

PostPosted: Fri 12 Feb '21 19:25    Post subject: Reply with quote

If I find an offending IP in Apache log, I check the IP with "whois" and if we don't do any business with that part of the world the entire subnet get ban.
Most of the offending IP's are script kiddies, practicing their hacking skills on western networks.

During copying the offending CIDR the last digit was missed so the CIDR after the slash was a single digit (big mistake).
For example:
212.129.0.0/18 = 16,384 Hosts
212.129.0.0/1 = 2,147,483,648 Hosts

That is a huge difference.

One quick solution is to visually check that none of CIDR's after slash have single "digit".

The more precise solution is to run a code (Clojure) (courtesy of Travis R. of Apache dev. community)

Code:
------------code (courtesy of Travis R. of Apache dev. community) ------------------

(ns htaccess.core)

(defn parse-ip [s]
  (let [v (clojure.string/split s #"/")]
    (flatten
      (if (< (count v) 2)
        [(clojure.string/split (get v 0) #"\.") "32"]
        [(clojure.string/split (get v 0) #"\.") (get v 1)]))))

(defn convert-str-to-binary-str [s]
  (clojure.string/replace (format "%0$8s" (java.lang.Integer/toBinaryString (java.lang.Integer/parseUnsignedInt (clojure.string/trim s)))) " " "0"))

(defn convert-mask-to-binary-str [s]
  (let [m (java.lang.Integer/parseUnsignedInt (clojure.string/trim s))
        m (if (< 32 m) 32 m)
        l0 (repeatedly m (fn [] 1))
        l1 (repeatedly (- 32 m) (fn [] 0))
        v  (apply str (flatten [l0 l1]))]
    v))

(defn binary-string-to-int [s] (java.lang.Integer/parseUnsignedInt (clojure.string/trim s) 2))

(defn masked? [p m]
  (let [s0  p
        s1  m
        p0  (parse-ip s0)
        p1  (parse-ip s1)
        v0  (apply str (map convert-str-to-binary-str (take 4 p0)))
        v1  (apply str (map convert-str-to-binary-str (take 4 p1)))
        m   (convert-mask-to-binary-str (last p1))
        im  (binary-string-to-int m)
        iv0 (binary-string-to-int v0)
        iv1 (binary-string-to-int v1)]
    (= (bit-and im iv0) (bit-and im iv1))))

(defn get-mask-data [s]
  (map (fn [s] (clojure.string/replace s "Require not ip " ""))
    (filter (fn [s] (clojure.string/includes? s "Require not ip "))
      (with-open [rdr (clojure.java.io/reader s)]
        (doall (line-seq rdr))))))

(defn return-matching-blocks [p f] (filter (fn [a] (masked? p a)) (get-mask-data f)))

------------end code (courtesy of Travis R. of Apache dev. comunity) ------------------


Somebody who is not a programmer might not know how to run it. So Travis was so kind and provided me with simple instructions.

From bash/zsh (command line on Linux)

1. install leiningen (https://leiningen.org)
On Gentoo emerge: dev-java/leiningen-bin

2. `cd /file/location/you/store/project/sources`
3. As user run `lein new htaccess`
(this will create a folder and project stub)
4. `copy the above code to: ~/htaccess/src/htaccess/core.clj`
(replace/override whatever is in that file "core.clj" with the above code.
5. cd htaccess
6. `lein repl`

on my machine, this gives me a prompt that looks like this:
Code:
nREPL server started on port 37699 on host 127.0.0.1 - nrepl://127.0.0.1:37699
REPL-y 0.4.3, nREPL 0.6.0
Clojure 1.10.0
OpenJDK 64-Bit Server VM 1.8.0_272-b10
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

htaccess.core=>


at "htaccess.core=>" you can paste in:
(return-matching-blocks "ip.of.my.interest" "/path/to/my/htaccess")

eg.
;htaccess.core=> (return-matching-blocks "159.14.184.11" "/home/syscon/htaccess_backup")
;("212.129.0.0/1")

It will return a list of all the matching ip/masks from the lines that contain "Require not ip ".
htaccess_backup - is a copy of .htaccess file

Again, lets give thanks to Travis R. for this handy script and send him your positive thoughts.
Back to top


Reply to topic   Topic: [SOLVED] Apache 2.4 - deny access to IP's that are not ban View previous topic :: View next topic
Post new topic   Forum Index -> Apache