Subnetting is not working with most relevant entry

Problem with Beta 5.0:
I have added a subnet entry for a /24 network and assigned it to group id 1.
Also I have added a native Client IP-Address with /32 and assigned it to group id 0 and group id 2.

The client will get the group id 1.

The same behavior when adding the client with the dropdown menu.

As I saw, in the selection from the database the first matching record is taken.
See line 278-279 in get_client_groupids (gravitiy-db.c). The Select is limited to 1.
Maybe there must be evaluated if there are more than 1 matching entry. If there is only one everything works great.

What is expected
In my opinion the most relevant entry should be taken.
So the client will be assigned to group id 0 and 2.

Im placing a log snippet where the client-init is shown.
Log Snippet

[2020-05-03 07:56:32.880 29303] Initializing gravity statements for 10.4.0.189
[2020-05-03 07:56:32.880 29303] Querying gravity database for client 10.4.0.189 (counting)
[2020-05-03 07:56:32.881 29303] SQL: Comparing 10.4.0.189 vs. 10.4.0.0/24 (database) - !! MATCH !!
[2020-05-03 07:56:32.881 29303] SQL: Comparing 10.4.0.189 vs. 10.4.0.189/32 (database) - !! MATCH !!
[2020-05-03 07:56:32.881 29303] SQL: Comparing 10.4.0.189 vs. 10.8.1.0/24 (database) - NO MATCH
[2020-05-03 07:56:32.881 29303] SQL: Comparing 10.4.0.189 vs. 192.168.168.111 (database) - NO MATCH
[2020-05-03 07:56:32.881 29303] SQL: Comparing 10.4.0.189 vs. 192.168.168.139 (database) - NO MATCH
[2020-05-03 07:56:32.881 29303] SQL: Comparing 10.4.0.189 vs. 192.168.168.141 (database) - NO MATCH
[2020-05-03 07:56:32.881 29303] SQL: Comparing 10.4.0.189 vs. 192.168.168.210 (database) - NO MATCH
[2020-05-03 07:56:32.881 29303] Querying gravity database for client 10.4.0.189 (getting groups)
[2020-05-03 07:56:32.882 29303] SQL: Comparing 10.4.0.189 vs. 10.4.0.0/24 (database) - !! MATCH !!
[2020-05-03 07:56:32.882 29303] gravityDB_open(): Preparing vw_whitelist statement for client 10.4.0.189
[2020-05-03 07:56:32.882 29303] get_client_querystr: SELECT EXISTS(SELECT domain from vw_whitelist WHERE domain = ? AND group_id IN (1));

Yes. SQLite is unable to do subnetting at all so we had to teach it how this works ourselves. The current implementation can only decide if two IP addresses are the same under a given bitmask due to certain subnet. Our self-engineered SQL subroutine currently only returns 1 (= true) if the addresses match (under the given bitmask) and 0 if they don't match.

We could change this to return the number of bits that a given bitmask has set and then chose the maximum match (in case there is any). This would implement the desired behavior. Pi-hole v5.0 already entered feature-freeze mode and I wouldn't like to postpone the nearing release any further, but implementing this for v5.1 is surely doable. It will be a certain performance hit, however, it shouldn't be a hefty one.

Thank‘s for the reply.
I fully agree to ship 5.0 with all the great features as soon as possible.

So i‘m looking forward to 5.1

Thanks @mgg for pointing out this behavior.
I'm with you that pihole should select group ids based on the smallest IP range for a given client (meaning it excludes the client from group assignments of wider IP ranges)

But I can think of another possible way how users might interpret /24 and /32 configurations - inclusive. "All clients in /24 should fall in group X and client /32 should additionally fall in group Y".

Therefore I suggest to add a small note to the Group management/client page about this behavior.
"Note: If a client is part of more than one IP range only the most exact group assignment is applicable."

Hi @yubiuser,
yes I think that should be noted in the manual.

At the moment (5.0) a client must only match one IP Range to get the expected group assignment.

Even wen we add this, you can still add multiple CIDR masks which are unique but still the same. For instance,

  • 127.0.0.1/24
  • 127.0.0.123/24

are actually the same thing. Due to algorithm optimization reasons, this will still lead to unpredictable behavior as in you cannot forecast which of the two most exact matches will be the chosen one. Most often, it will be the first added one (as it comes first in the index table), however, it may also be the second one in case you had a lot of groups and clients at some point, deleted them and added new ones. Your database will still be fast, however, it may not be in sequential order any longer.

Mhh.. I think this might be a potential source of user's misconfiguration. Can you add a check if an identical subnet is already defined? (Like it is for entries in general by SQL's unique constrain)

No, for one because SQL had no idea what IP addresses are and how they could be unique under certain conditions and also because users could still add such entries through the CLI/direct database interactions.

I have something more in the pipeline to address such issues...

:smiley:

6 posts were split to a new topic: Client subnet mask incorrect

This will ensure we will use the most recent + make the choice deterministic even in case of duplicates

@yubiuser Check out the web interface screeshot in this PR to see what I meant with "something more in the pipeline".

2 Likes

This is awesome ! :smiley:
If you want some help on testing just give me a ping.

Regards Markus

:heart_eyes:

That's awesome!


One small hint: I've tried this in conjunction with new/diagnostics and it is already great that the icon changes when new messages arrive. But the triangle icon is always present - subconsciously I always think something might be wrong even when it is not. Maybe you could change the default symbol to something else not triggering a brain warning.

Something seems to be broken for you. I don't see the triangle when there are no messages available. Note that there should also be a small orange label with the number of available warnings.

Please ensure you're on the most recent version.

Switched back from tweak/debug_token and the triangle is gone.

The only thing that remains brocken is this HEAD>>>> MASTER seen on API/Web_Interface.


Great feature!

I usually only reserve this for desperate times, but sometimes it's easier just to nuke things:

sudo rm -rf /var/www/html/admin
sudo git clone https://github.com/pi-hole/adminLTE /var/www/html/admin

Works until I switch to pihole checkout web new/diagnostics

from sudo cat /var/log/lighttpd/error.log

2020-05-12 09:47:31: (mod_fastcgi.c.421) FastCGI-stderr: PHP Notice:  Undefined index: PORTFILE in /var/www/html/admin/scripts/pi-hole/php/FTL.php on line 39
2020-05-12 09:47:31: (mod_fastcgi.c.421) FastCGI-stderr: PHP Warning:  file_get_contents(): Filename cannot be empty in /var/www/html/admin/scripts/pi-hole/php/FTL.php on line 39
2020-05-12 09:47:31: (mod_fastcgi.c.421) FastCGI-stderr: PHP Notice:  Undefined index: PORTFILE in /var/www/html/admin/scripts/pi-hole/php/FTL.php on line 39
2020-05-12 09:47:31: (mod_fastcgi.c.421) FastCGI-stderr: PHP Warning:  file_get_contents(): Filename cannot be empty in /var/www/html/admin/scripts/pi-hole/php/FTL.php on line 39
2020-05-12 09:47:31: (mod_fastcgi.c.421) FastCGI-stderr: PHP Notice:  Undefined index: PORTFILE in /var/www/html/admin/scripts/pi-hole/php/FTL.php on line 39
2020-05-12 09:47:31: (mod_fastcgi.c.421) FastCGI-stderr: PHP Warning:  file_get_contents(): Filename cannot be empty in /var/www/html/admin/scripts/pi-hole/php/FTL.php on line 39
2020-05-12 09:47:31: (mod_fastcgi.c.421) FastCGI-stderr: PHP Notice:  Undefined index: PORTFILE in /var/www/html/admin/scripts/pi-hole/php/FTL.php on line 39
2020-05-12 09:47:31: (mod_fastcgi.c.421) FastCGI-stderr: PHP Warning:  file_get_contents(): Filename cannot be empty in /var/www/html/admin/scripts/pi-hole/php/FTL.php on line 39
2020-05-12 09:47:31: (mod_fastcgi.c.421) FastCGI-stderr: PHP Notice:  Undefined index: PORTFILE in /var/www/html/admin/scripts/pi-hole/php/FTL.php on line 39

-rw-rw-r-- 1 pihole root         172 Mai 12 20:02 pihole-FTL.conf

This is not an issue as such, only a warning.

Ok, but still strange that I see this