Keep built-ins and policies out of the busiest rules
The established built-in passes most of the traffic, so it topped the statistics' busiest rules every time and made every rule's bar look empty. The summary now lists rules and NAT objects in rules, and built-ins and policies in builtins; the Statistics page and hc stats show them as two lists. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
507d75829f
commit
ca5ac971e5
7 files changed
+40
-10
No files matched your search
@@ -150,8 +150,10 @@ func (s *Server) statsSummary(w http.ResponseWriter, r *http.Request, p *auth.Pr
|
||||
return err
|
||||
}
|
||||
st := s.eng.State()
|
||||
for i := range sum.Rules {
|
||||
sum.Rules[i].Name = markName(st, sum.Rules[i].Key)
|
||||
for _, es := range [][]stats.Entry{sum.Rules, sum.BuiltIns} {
|
||||
for i := range es {
|
||||
es[i].Name = markName(st, es[i].Key)
|
||||
}
|
||||
}
|
||||
writeJSON(w, http.StatusOK, sum)
|
||||
return nil
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -154,6 +155,14 @@ func TestCollector(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
check("drops", s.Drops, 18)
|
||||
for _, e := range s.Rules {
|
||||
if e.Key[0] == 'b' || e.Key[0] == 'p' {
|
||||
t.Errorf("built-in or policy %s among the busiest rules %+v", e.Key, s.Rules)
|
||||
}
|
||||
}
|
||||
if !slices.ContainsFunc(s.Rules, func(e Entry) bool { return e.Key == "r1" }) || !slices.ContainsFunc(s.BuiltIns, func(e Entry) bool { return e.Key == "p-input" }) {
|
||||
t.Errorf("rules %+v, built-ins %+v", s.Rules, s.BuiltIns)
|
||||
}
|
||||
if len(s.Zones) == 0 || s.Zones[0].Name != "wan" || s.Zones[0].Received != 4000 {
|
||||
t.Errorf("zones %+v", s.Zones)
|
||||
}
|
||||
|
||||
+14
-5
@@ -191,8 +191,11 @@ type Summary struct {
|
||||
// chain.
|
||||
Drops int64 `json:"drops"`
|
||||
DropsByChain []Entry `json:"drops_by_chain"`
|
||||
// Rules are the busiest rules, built-ins and policies, by packets.
|
||||
Rules []Entry `json:"rules"`
|
||||
// Rules are the busiest rules and NAT objects, by packets; BuiltIns
|
||||
// the busiest built-ins and policies, kept apart because the
|
||||
// established built-in counts most of the traffic.
|
||||
Rules []Entry `json:"rules"`
|
||||
BuiltIns []Entry `json:"builtins"`
|
||||
// Connections: the most tracked at once (per-bucket averages), and
|
||||
// the table's size.
|
||||
PeakConnections int64 `json:"peak_connections"`
|
||||
@@ -251,9 +254,15 @@ func (q *Querier) Summary(ctx context.Context, since time.Duration, topLimit int
|
||||
s.Zones, s.Interfaces = traffic("zrx:", "ztx:"), traffic("rx:", "tx:")
|
||||
s.Drops = all["drops"]
|
||||
s.DropsByChain = sorted(all, "drop:")
|
||||
s.Rules = sorted(all, "hits:")
|
||||
if len(s.Rules) > topLimit {
|
||||
s.Rules = s.Rules[:topLimit]
|
||||
s.Rules, s.BuiltIns = []Entry{}, []Entry{}
|
||||
for _, e := range sorted(all, "hits:") {
|
||||
if strings.HasPrefix(e.Key, "b-") || strings.HasPrefix(e.Key, "p-") {
|
||||
if len(s.BuiltIns) < topLimit {
|
||||
s.BuiltIns = append(s.BuiltIns, e)
|
||||
}
|
||||
} else if len(s.Rules) < topLimit {
|
||||
s.Rules = append(s.Rules, e)
|
||||
}
|
||||
}
|
||||
if tl, err := q.Timeline(ctx, since, "auto", []string{"g:" + GaugeConntrack, "g:" + GaugeConntrackMax}); err == nil {
|
||||
for _, v := range tl.Series[0].Values {
|
||||
|
||||
@@ -98,7 +98,8 @@ export async function render(el, params, query) {
|
||||
? "No traffic per device " + rangeLabel + "."
|
||||
: ["Traffic per device is off. Turn it on under ", h("a", { href: "#/settings" }, "Settings"), " (it adds a counter for each inside address)."]);
|
||||
parts.push(h("div", { class: "chart-grid" },
|
||||
listCard("Busiest rules", "packets each counted, " + rangeLabel, barList(s.rules, { label: (k) => k, href: (k) => ruleHref(k) })),
|
||||
listCard("Busiest rules", "packets each counted, " + rangeLabel, barList(s.rules, { label: (k) => k, href: (k) => ruleHref(k), empty: "No rule counted anything " + rangeLabel + "." })),
|
||||
listCard("Built-ins and policies", "packets each counted; 'established' passes the replies and the rest of every allowed connection", barList(s.builtins || [], { label: (k) => k, href: (k) => ruleHref(k) })),
|
||||
listCard("Dropped, by chain", "early: antispoofing · invalid: packets conntrack can't place", barList(s.drops_by_chain, { empty: "Nothing dropped " + rangeLabel + "." })),
|
||||
listCard("Blocked most", "sources of logged drops (the policies' with 'log drops' on, and rules that log)", barList(s.blocked_sources, { empty: "No logged drops " + rangeLabel + ".", href: (k) => "#/trace?address=" + encodeURIComponent(k) })),
|
||||
listCard("What they tried", "the logged drops' protocol and port", barList(s.blocked_ports, { empty: "No logged drops " + rangeLabel + "." })),
|
||||
|
||||
Reference in new issue
Block a user