Alternative ways to get past 32 rpz zone limit in BIND? ...without running BIND a thousand times

Using BIND RPZs gives me exactly what I'm looking for to alter queries. However, my recursive DNS server is in use by hundreds of clients and I am looking for a way to allow each client some level of customization. There's possibly a couple hundred zones a client might want to enable making for thousands of different possible combinations.

It appears I am limited to 32 RPZ zones (of seemingly infinite length) but that alone won't work -- each user needs the ability to opt-in to specific zones. Even with massive zones for each client it will still hit the 32 limit.

I've looked briefly at Unbound which appears to have a similar sort of RPZ setup with local-data transparency, but the fun seems to have ended when looking for a way to separate things into views so I can only serve them to specific clients.

Surely there's a way to accomplish this without reinventing the wheel? I see commercial providers offering similar setups, like OpenDNS for example where thousands of customers can toggle various lists. What's the secret sauce?


First, it helps to understand why the limitation exists.

https://kb.isc.org/docs/aa-01121

The RPZ mechanism has not changed in BIND 9.10. The documentation in KB article AA-00525 (Building DNS Firewalls with Response Policy Zones (RPZ)is still almost current. What has changed in BIND 9.10 is that it is now possible to use as many as 32 separate RPZ files in a single instance of BIND, and that BIND is not significantly slowed by such heavy use of RPZ. Each one of those 32 policy zone files can specify policy for as many different domains as necessary. The limit of 32 is on the number of independently-specified policy collections and not the number of zones for which they specify policy.

In earlier versions of BIND in which RPZ was implemented, having more than one RPZ zone file required BIND to perform a separate lookup in each policy zone to see if there was a match. In BIND 9.10, the policy information is stored in a radix tree, in which simultaneous lookups across all policy zones can be performed in sub-linear time that is approximately proportional to the logarithm of the number of policy statements in the largest collection (RPZ zone).

The improved implementation of RPZ for BIND 9.10 was provided by Vernon Schryver and Paul Vixie. It is faster because it is O(log n) in the size of the policy and because it can look up several items of data in parallel. The new limit of 32 results from the use of a 32-bit bitfield to identify the policy zones that affect a query. Previous implementations of RPZ were O(n) rather than O(log n).

I've emphasized the relevant verbiage. The only way to change the limit of 32 is to update the algorithm to use a larger bitfield, or gut the optimization code entirely. Even if you were to double the size of the bitfield to 64 (or re-double to 128, etc.), you're still dealing with a static limitation imposed by the radix tree optimization. Since I'm not familiar with the innards of this algorithm, I also can't say how effective such an attempt would be to begin with.

You can get around this by using views that match your individual customers, which will give you 32 RPZ zones per customer, but that's as far as you're going to get without diving into the source code.