Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAC-based client grouping #245

Closed
davidedellagiustina opened this issue Aug 21, 2021 · 11 comments
Closed

MAC-based client grouping #245

davidedellagiustina opened this issue Aug 21, 2021 · 11 comments
Labels
🤷 wontfix This will not be worked on

Comments

@davidedellagiustina
Copy link

Would it be possible to implement client groups (and therefore specific DNS filtering) basing on the clients' MAC addresses, as an alternative to the rDNS lookup? Moreover, it would be nice if there was a way to group different clients in order to apply the same filtering rules.

@0xERR0R
Copy link
Owner

0xERR0R commented Aug 21, 2021

Hey,

Regarding the grouping of clients: you can use wildcards. For example: 2 devices with hostnames "alex-laptop" and "alex-mobile" can be defined as "alex-*"

Regarding the MAC address: yes, it would be (theoretically) possible. The problem is: if a client request is received by blocky, there is no possibility to retrieve the MAC address directly (only source IP address is available). The MAC address can be retrieved by using the ARP protocol (or using the ARP table of the operating system). This will work only for IPv4. For IPv6, the NDP protocoll can be used.

So, basically, the challenge is to implement 2 lookups (ipv4 with ARP and ipv6 with NDP) and to test it.

@0xERR0R 0xERR0R added the 🔨 enhancement New feature or request label Aug 21, 2021
@davidedellagiustina
Copy link
Author

@0xERR0R Wildcards are not always applicable since devices can have complexely different hostnames (as far as I know, the hostname is controlled by the device itself). At least, it would be great if there was some sort of configuration option (alternative to wildcards) that allows to define a group of client names for which a certain groups of rules apply.

As for the MAC-based filtering, isn't the physical address retrievable by the frame (OSI lv.2) containing the DNS request? Or is it hidden by the operating system? However, I don't actually know that much about IPv6 and I'm not even sure of what NDP is.

Thank you anyway!

@0xERR0R
Copy link
Owner

0xERR0R commented Aug 23, 2021

Some routers (like AVM FritzBox) allow to define custom names for devices. In this case, blocky will retrieve custom name via rDNS from router. But you're right, hostname can be out of control and in this case it would be handy to define different names for one group. I'll create an issue to separate it from the MAC-based grouping request. -> #251

Regarding the MAC-address: yes, this information is available in the layer 2, but not on the DNS request layer (there is no possibility to obtain the MAC address programmatically, only IP address and port is available).

I'll try out, how the ARP tables work for IP4, maybe this would be the first step

@davidedellagiustina
Copy link
Author

@0xERR0R Yeah I am currently using Ubiquiti UniFi hardware on my network - custom names are allowed but rDNS queries get the hostnames, basing on the tests I performed. However, if the MAC-based grouping is too much of a hassle, feel free to just ignore the request - I just switched from PiHole to Blocky and I already love it a lot :)

@kwitsch
Copy link
Collaborator

kwitsch commented Nov 13, 2021

Looked into it and it should be possible if the host arp table is obtained.
I found a golang library which does just that Link.

The drawback would be that the first response time of every client would be slower.
The client potantionally wouldn't be in the arp table cache and a refresh would be neccecary.
I don't think that it would be noticable as it only happens during the first request.

Most users propably are using rDNS therfore the arp refresh should be disabled by default to minimize the performance impact.

@kwitsch
Copy link
Collaborator

kwitsch commented Nov 13, 2021

Upon further investigation it seems quite troublesome getting an ARP based MAC to IP mapping done.
Unless your system supports ARP proxying there would be a direct link to all subnets needed.
This could be done through a VLAN trunk.
Host networking mode would be required if blocky is used inside a docker container.

It seems to be a very complicated aproach.
Splitting up the clients in seperate Subnets and setting up routs between them would be way easiere. Blocking groups could be configured per subnet.

I stop further investigation because this seems way to complicated for the little benefit.

@davidedellagiustina
Copy link
Author

What if Blocky held its own intern kind-of-arp-table and used that instead of the system's one? I guess a table can be built with e.g. arping. Moreover, since IPs can change, I think that such table would need to be updated programmatically, instead of adding new rows only when receiving requests from unknown clients (in fact you could e.g. assign an already known (to Blocky) IP to a new device, and that would break the filtering).
Anyway, thank you so much for your effort and for Blocky in general. I've been using it for some months now and it's rock solid.

@kwitsch
Copy link
Collaborator

kwitsch commented Nov 14, 2021

The library which I first suggested does just that: it creates a cached version of the underlying os ARP table an periodically updates it.
Since the os ARP table is updated automatically through the os as new connections are established a periodical ARP request isn't necessary.
To speed up the first response time the cache could be initialized with a network wide ARP scan during startup.

However this works only for the current subnet.

I use an TP-Link Omada network controller which also lacks an rDNS service.
Therefore I would have loved to find a solution for this.
Every solution I found seems quite complicated if used for multiple subnets.

@0xERR0R
Copy link
Owner

0xERR0R commented Nov 14, 2021

I would agree with @kwitsch: the benefit of apr lookup is low due to limitations:

  • it it necessary to hold the ARP cache in memory and refresh it automatically. This can be done asynchronously, but the first request will be blocked
  • maybe different implementation for windows necessary?
  • it doesn't work in docker with docker network
  • it doesn't work with IPv6 (it must be necessary to implement something similar with NDP)

You can try to workaround:

  • assign static IP addresses to your clients (or use DHCP with sticky IPs) and map each IP to client name in blocky (would work if you have not many clients)
  • use protocols where you can pass the client name: DoT and DoH -> this work also well, but requires additional installation on client side (e.g. Android can DoT natively, Windows not)

@kwitsch
Copy link
Collaborator

kwitsch commented Jan 9, 2022

Got this issue stuck in the head for a while. 😅
The idea to create an one-time MAC->DNS binding seams more elegant than configuring an extensive amount of static IPs to me.

I figured out a way to solve it in an IPv4 environment using additional services inside an docker swarm.
blocky-config.yml.txt
example-stack.yml.txt

Maybe this helps others to.😄

@kwitsch
Copy link
Collaborator

kwitsch commented May 29, 2022

Follow up:
My first approach with TinyMacDns works quite well but required an excessive amount of configuration as every hostname needs an mac address configuration value.
It's a real struggle updating the config every time a new client uses the network.
Furthermore did the config get quite polluted with old entries which had to be removed manually.

Because of the tiny use case and excessive config maintenance I will abandon this approach.

My second approach will be a OmadaSiteDns.

  • Benefit:
    more dynamic and less maintenance intense configuration
  • Drawback:
    network controller has to be Omada

It uses the controller api to read client information and converts these to DNS/rDNS entries.

Thought this might be interesting for people with similar use cases. 😅

Repository owner deleted a comment from github-actions bot Aug 28, 2022
@kwitsch kwitsch added 🤷 wontfix This will not be worked on and removed 🗑️ Stale 🔨 enhancement New feature or request labels Aug 28, 2022
@kwitsch kwitsch closed this as not planned Won't fix, can't repro, duplicate, stale Aug 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤷 wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

3 participants