-
Print
-
DarkLight
-
PDF
Using Access Control Lists (ACLs) with both addresses and keys
Question:
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
Answer:
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; };
ACLs aren't boolean. The ACL elements are processed in order (from left to right) and each ACL 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 10.0.0.1) 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.
Therefore 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!