AdguardTeam / AdGuardHome

Network-wide ads & trackers blocking DNS server
https://adguard.com/adguard-home.html
GNU General Public License v3.0
25.52k stars 1.83k forks source link

MAC address based client identifier #2383

Closed emlimap closed 3 years ago

emlimap commented 3 years ago

Problem

The current implementation of client modifier works great for per device allow/block of certain domains as long as it is either IPv4 or to some extent for IPv6 as long as you use just DHCP to hand out addresses.

This doesn't work when the network supports SLAAC and operating system has temporary addresses enabled. As a result the OS would pick up a new IP everyday making IP based client identifier useless. Temporary addresses are enabled by default in most operating systems these days.

Unfortunately SLAAC can't be disabled as Android devices don't support DHCP for IPv6.

Also, Some ISPs allocate a new IPv6 range whenever the modem/router or PPPoE session is restarted making use of v6 addresses useless as identifier.

Solution

AGH would lookup the MAC address for each IP it encounters for the first time so that it could be used elsewhere similar to client modifier. Due to the way layer 2 networking works, this would be limited to network range AGH is hosted on. Also, it should periodically refresh the IP to MAC list to ensure it is up to date.

For example, the following filter would block example.com for client with MAC 92:1A:C4:12:9C:0C irrespective of whether the request was coming from an IPv4 or v6 address.

||example.com^$macaddr=92:1A:C4:12:9C:0C

This should cover users who use AGH as their DHCP server as well as those who don't.

Some libraries that I came across that could help with this

https://github.com/mostlygeek/arp (IPv4 only and hasn't been tested in windows but the code is there) https://github.com/mdlayher/ndp (IPv6 only but it isn't quite clear as to what operating systems the library supports. Looks like we need to do a Neighbor Solicitation to get a MAC address associated with IPv6 address as per this article https://mdlayher.com/blog/network-protocol-breakdown-ndp-and-go/)

Looks like Pi-Hole recently added support for something similar

Allow defining clients by their MAC address

It works the following way: If we didn't find an IP address match (either exact or subnet), we lookup the IP address within the Network overview table. If we find a (sufficiently recent) IP address match there, we extract the corresponding MAC address. We use this MAC address for a new lookup in the client database table to see if there is a client configured with this MAC address.

https://github.com/pi-hole/FTL/pull/762

corresponding front end change https://github.com/pi-hole/AdminLTE/pull/1285

Additional notes

In the client details popup in query log UI, we can display the MAC address and corresponding device manufacturer based on vendor prefix lookup. Vendor prefix allocation list seems to be available here for free https://macaddress.io/database-download / https://linuxnet.ca/ieee/oui/

Another suggested improvement is in the dropdown next to unblock/block in query log UI, add an option to block for this client MAC only and change existing block for this client only to block for this client IP only. Wording is up for discussion.

ameshkov commented 3 years ago

Tbh, I don't think we should add a new modifier for this, client seems to be sufficient and can be extended to work with MAC-addresses.

Also, this seems to be similar to https://github.com/AdguardTeam/AdGuardHome/issues/961, merging it there.