Add blocking: blocklists and block/allow rules with BIND response policy zones
jarld downloads blocklists (Adblock, hosts or plain domains), checks them daily and reloads named only when a list changed; your own block and allow rules take precedence, and the most specific rule wins. Lists and rules apply per view (default: every view that offers recursion). Web UI Blocking page with name checks, jarl blocklist and jarl block, the /blocking API, blocked counts in the statistics. Database schema 6. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
436cd79ec9
commit
9fc23310bd
54 files changed
+4269
-85
No files matched your search
+20
-10
@@ -153,14 +153,19 @@ type Summary struct {
|
||||
Queries int64 `json:"queries"`
|
||||
Per string `json:"per"` // minute, hour or day
|
||||
} `json:"peak,omitempty"`
|
||||
RCodes []Entry `json:"rcodes"`
|
||||
QTypes []Entry `json:"qtypes"`
|
||||
Views []Entry `json:"views"`
|
||||
Zones []Entry `json:"zones"`
|
||||
Answers []Entry `json:"answers"` // authoritative, recursive
|
||||
Transport []Entry `json:"transport"` // udp, tcp
|
||||
CacheHitRatio *float64 `json:"cache_hit_ratio,omitempty"`
|
||||
RCodes []Entry `json:"rcodes"`
|
||||
QTypes []Entry `json:"qtypes"`
|
||||
Views []Entry `json:"views"`
|
||||
Zones []Entry `json:"zones"`
|
||||
Answers []Entry `json:"answers"` // authoritative, recursive
|
||||
Transport []Entry `json:"transport"` // udp, tcp
|
||||
CacheHitRatio *float64 `json:"cache_hit_ratio,omitempty"`
|
||||
// NXDomainRatio leaves out answers blocking gave (which are
|
||||
// NXDOMAIN too); Blocked counts those (docs/blocking.md).
|
||||
NXDomainRatio *float64 `json:"nxdomain_ratio,omitempty"`
|
||||
Blocked int64 `json:"blocked"`
|
||||
BlockedRatio *float64 `json:"blocked_ratio,omitempty"`
|
||||
Blocklists []Entry `json:"blocklists,omitempty"`
|
||||
Tops map[string][]Entry `json:"tops,omitempty"`
|
||||
}
|
||||
|
||||
@@ -181,9 +186,14 @@ func (q *Querier) Summary(ctx context.Context, since time.Duration, topLimit int
|
||||
r := float64(h) / float64(h+m)
|
||||
s.CacheHitRatio = &r
|
||||
}
|
||||
s.Blocked, s.Blocklists = all["blocked"], sorted(all, "blocklist:")
|
||||
if s.Queries > 0 {
|
||||
r := float64(all["rcode:NXDOMAIN"]) / float64(s.Queries)
|
||||
r := float64(max(all["rcode:NXDOMAIN"]-s.Blocked, 0)) / float64(s.Queries)
|
||||
s.NXDomainRatio = &r
|
||||
if s.Blocked > 0 {
|
||||
b := float64(s.Blocked) / float64(s.Queries)
|
||||
s.BlockedRatio = &b
|
||||
}
|
||||
}
|
||||
per, err := q.Store.series(ctx, res, from, to, "queries")
|
||||
if err != nil {
|
||||
@@ -209,7 +219,7 @@ func (q *Querier) Summary(ctx context.Context, since time.Duration, topLimit int
|
||||
}
|
||||
if topLimit > 0 {
|
||||
s.Tops = map[string][]Entry{}
|
||||
for _, k := range []string{KindName, KindClient, KindNXDomain} {
|
||||
for _, k := range []string{KindName, KindClient, KindNXDomain, KindBlocked} {
|
||||
es, err := q.Top(ctx, k, since, topLimit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -246,7 +256,7 @@ func (q *Querier) Breakdown(ctx context.Context, group string, since time.Durati
|
||||
}
|
||||
|
||||
// Groups are the counter groups Breakdown accepts.
|
||||
var Groups = []string{"qtype", "rcode", "view", "zone", "answer", "transport", "rtt", "dnssec", "cache", "ratelimit"}
|
||||
var Groups = []string{"qtype", "rcode", "view", "zone", "answer", "transport", "rtt", "dnssec", "cache", "ratelimit", "blocklist"}
|
||||
|
||||
// Timeline is a set of series over time.
|
||||
type Timeline struct {
|
||||
|
||||
Reference in new issue
Block a user