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.
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."
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...
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.
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