Keep Server Online
If you find the Apache Lounge, the downloads and overall help useful, please express your satisfaction with a donation.
or
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.
| |
|
Topic: [SOLVED] Apache 2.4 - deny access to IP's that are not ban |
|
Author |
|
syscon
Joined: 10 Feb 2021 Posts: 4 Location: Canada
|
Posted: Wed 10 Feb '21 17:11 Post subject: [SOLVED] Apache 2.4 - deny access to IP's that are not ban |
|
|
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 Moderator
Joined: 16 Aug 2020 Posts: 348 Location: UK
|
Posted: Fri 12 Feb '21 16:27 Post subject: |
|
|
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
|
Posted: Fri 12 Feb '21 16:44 Post subject: |
|
|
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 Moderator
Joined: 16 Aug 2020 Posts: 348 Location: UK
|
Posted: Fri 12 Feb '21 17:17 Post subject: |
|
|
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
|
Posted: Fri 12 Feb '21 19:25 Post subject: |
|
|
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 |
|
|
|
|
|
|