Knowledge Base ISC Main Website Ask a Question/Contact ISC
Using Access Control Lists (ACLs) with both addresses and keys
Author: Evan Hunt Reference Number: AA-00723 Views: 3579 Created: 2012-07-18 20:16 Last Updated: 2015-04-29 21:48 100 Rating/ 1 Voters


How can I configure allow-update to permit updates, only if BOTH of the following are true:

  • They hold the secret key (TSIG)
  • They're in the 'permitted' subnet


Here's the long version:
acl address_allow { 10/8; };
acl address_reject { !address_allow; any; };
allow-update { !address_reject; key "...."; };

And now in shorthand:

allow-update { !{!10/8;any;}; key update-key; };

Doesn't this permit any clients on the 10/8 network?

Intuitively, following Boolean logic, you might think that it does, but it doesn't.  What it actually says is 'deny anyone who isn't in subnet 10/8', and then 'allow anyone using this key'.

You're probably thinking in boolean algebra (I did too, when I first encountered this).  If it were boolean algebra, you could redistribute the negatives: "!{!10/8; any;}" becomes "{!!10/8; !any;}" and then
simplifies to "{10/8; none;}".

But ACLs aren't boolean, so you can't do that.  Each element has three possible results instead of two:

  • match and accept
  • match and reject
  • no match (which means "continue processing")

When an ordinary ACL element matches and is negated (for example, the element is "!10/8;" and the address is that means "match and reject".  But if the match is inside of a *nested* ACL, then it's treated differently.  A negative result means "the nested ACL didn't match"--and so you continue processing.

So if you're checking address A against an ACL of one of the following
forms, these will be the results:

    {     A;    B; }   == A is allowed, accept immediately
    {  {  A; }; B; }   == A is allowed, accept immediately
    {    !A;    B; }   == A is forbidden, reject immediately
    { !{  A; }; B; }   == A is forbidden, reject immediately
    {  { !A; }; B; }   == A matched but was negated, try element B
    { !{ !A; }; B; }   == A matched but was negated, try element B

Those last two lines there are confusingly similar (and, as written, useless).  The difference is what happens if you're checking an address other than A, and something else in the nested ACL matches it.

    {  { !A; any; }; B; }  == any address other than A is accepted at once,
                              but A is only accepted if B matches too.
                              boolean translation: ((not A) or (A and B))

    { !{ !A; any; }; B; }  == any address other than A is *rejected* at once,
                              but A is accepted as long as B matches too.
                              boolean translation: (A and B)

Hope that's helpful!

© 2001-2017 Internet Systems Consortium

For assistance with problems and questions for which you have not been able to find an answer in our Knowledge Base, we recommend searching our community mailing list archives and/or posting your question there (you will need to register there first for your posts to be accepted). The bind-users and the dhcp-users lists particularly have a long-standing and active membership.

ISC relies on the financial support of the community to fund the development of its open source software products. If you would like to support future product evolution and maintenance as well having peace of mind knowing that our team of experts are poised to provide you with individual technical assistance whenever you call upon them, then please consider our Professional Subscription Support services - details can be found on our main website.

  • There is no feedback for this article
Quick Jump Menu