Skip to content

sigwood v0.6.0

Latest

Choose a tag to compare

@github-actions github-actions released this 29 Aug 04:37
· 6 commits to main since this release

Added

  • The dense-cluster tunnel scan now runs on Pi-hole data, not only Zeek. A family of
    generated-looking names used to stop being identifiable in a Pi-hole report once it grew
    large enough to form its own cluster: below that size its domains surfaced individually,
    above it no finding named them and only a counts-only row remained, reporting how many
    domains had formed how many clusters. Such a family is now recovered when its names concentrate under a single
    registrable domain. Recovery is bounded and the bounds are measured: a family sprayed
    across many domains is still outside the scan, an encoding whose labels only sometimes
    look generated can still slip the member-fraction bar, and a cluster the scan inspects
    and rejects produces no row. Pi-hole findings stay capped at MEDIUM, because the volume
    evidence is not permitted to corroborate on a source that records no resolution outcome.
    Disabling the scan returns Pi-hole to its previous aggregate disclosure, which now says
    the scan was disabled rather than claiming a source limitation. The calibration record is
    published in the DNS evidence page.

  • An evidence ledger: what has actually been measured, and what has not.
    docs/EVIDENCE.md carries one
    row for every detector, not only the ones with results behind them: what was measured and
    on what population, what that supports and does not, and what is still owed. Five detectors
    now have published calibration conclusions under docs/evidence/; two are measured with the
    write-up still owed; and two have no calibration campaign at all, which the ledger says
    plainly. Nearly all of it rests on one estate, and each record says so itself. If you want to
    help change that, FIELDKIT.md
    is the door.

Changed

  • Reports are written to be read. A first-time reader described sigwood's output as mostly
    cryptic, and the pass below answers that verdict rather than a lint. None of it changes what
    sigwood finds: the detectors and their thresholds are untouched, and the same run produces the
    same findings, with the same evidence, that it did before. What changed is how those findings
    are put on the page. Two qualifications, so the sentence above is not read wider than it
    holds: the wording of some human-facing notes changed, which json carries verbatim in
    run_summary.notes and has always documented as prose rather than contract; and one dns
    display cell was renamed, which is projection and never reached json or csv. The
    individual changes follow.

  • Severity is spelled out, everywhere a person reads it. The text report showed [H],
    [M], [L] and [I]; a novice reader took those for magnitudes, times and sizes in a single
    sitting, while the spelled word decoded unaided. Text now reads high, medium, low and
    info, padded so mixed rows keep their columns; the html report spells and capitalizes the
    same words in its summary cards, its row pills and its group headers. json keeps its
    lowercase token and csv its column, both unchanged.

  • Verbose reports put the prose before the machine facts. At -v and -vv the order is now
    description, then next steps, then evidence, with the data window last. Previously the
    imperative advice sat below the evidence block, and a reader who bounced off the evidence
    never reached the part telling them what to do. Adjacent findings are separated by one blank
    line, which the dense default view still does without.

  • Each detector group says what that detector looks for. A one-line mission renders beneath
    the group header on both reading surfaces, so a reader meeting beacon or dnsblock for the
    first time is told what question it asks before being shown its answers. A report also carries
    one pointer, once, to the tier that explains why each finding surfaced, and it appears only
    when a group actually rendered.

  • Level-zero rows name what they hold. dns counts read as names, queries and clients;
    beacon's composite reads as rhythm. The dns tables now carry their labels once as column
    headers rather than repeating them on every row, which is what the html tables already did.
    The dns lexical score is labelled entropy score, and the word score is doing work: the
    number is a weighted lexical measure with no units, so a bare entropy heading invites a
    reader to take it as a count of bits, which it is not.

  • Evidence timestamps are readable and unambiguous. Instants inside the evidence block used
    to render as raw machine strings in UTC while the report's own window was shown in local time,
    so two lines of one block could describe the same moment and appear to disagree. Accepted
    instants now follow the report's display timezone, carry their local or UTC label, and
    include seconds where a distinction depends on them, such as an authentication failure and the
    success that followed it.

  • ssl and dnsblock findings explain themselves in plain language. An ssl row said which
    internal signals fired; it now says that no server name was offered, or that a certificate did
    not validate, and it keeps the measured validation status that separates an expired
    certificate from a self-signed one. dnsblock descriptions say in words what its counts mean,
    keeping the distinction between complete daily coverage and coverage that cannot be confirmed.
    Both are rendering only: the machine payloads under them are unchanged.

  • The html report carries sigwood's own identity, and dns entities are one click to copy.
    Detector names in group headers wear the wordmark's serif and colour, so the page reads as
    sigwood's document at every section boundary rather than only in the corner. A dns domain cell
    selects whole on one click, with no visual marking, and that convenience is absent from print.

  • [detectors.beacon].bin_seconds is no longer a configuration key. The beacon detector bins a
    flow's connection times before looking for a rhythm, and every other number in that scorer - the
    score threshold, the period band it will consider, the peak-prominence normalization, and the
    reference score quoted in the documentation - was tuned against a 30-second bin. Changing the bin
    therefore did not adjust sensitivity; it produced scores that could not be compared with any of
    those numbers, including the threshold deciding whether a finding appeared at all. The value is
    now fixed in the detector. A configuration file still carrying the key keeps working: sigwood
    reports config: ignoring unknown setting [detectors.beacon].bin_seconds and continues with the
    calibrated value.

Fixed

  • sigwood now tells you when a syslog archive's dates look re-dated. RFC 3164 and Pi-hole
    logs carry no year, so sigwood stamps them with the current one. That silently moves an
    archive more than a year old into the last twelve months, and those dates then flow into
    windows, timelines and finding data windows looking entirely confident. Where the file still
    carries its original modification time, sigwood now says so once per file: timestamps parse 730 days newer than the file itself was last written. It explains rather than repairs: the
    dates are still wrong. It is deliberately conservative: the two-day threshold exists
    because a log shipped from a distant timezone legitimately parses up to 26 hours ahead, and a
    copy made without preserving the modification time cannot be flagged at all. See
    RFC 3164 syslog and Pi-hole timestamps carry no year in
    KNOWN-ISSUES.md for
    what it can and cannot see.

  • On a daily-rotating Zeek tree, a default run now includes today's events. sigwood anchored
    its default window on the newest dated log directory and stopped at that day's last second, so
    anything written since midnight - which lives only in the live current/ spool - was read from
    disk and then filtered back out. A plain sigwood /opt/zeek/logs at three in the afternoon
    showed you nothing from that afternoon. The window's lower bound still selects the last N dated
    days; the upper bound is now open, so the live spool is included. Two consequences worth knowing:
    a 7-day default can now span eight calendar dates, because it covers seven archived days plus
    today so far; and a log line stamped in the future - clock skew, a misconfigured sensor - is now
    admitted rather than silently dropped, which is how every other source already behaved.

  • A large group of Pi-hole domains no longer disappears without a word. On Pi-hole data,
    domains that clustered together produced no findings and nothing was said about them, so a burst
    of random lookups that grew large enough to form its own cluster stopped being identifiable - and
    where every domain clustered, the run reported no findings at all. A run now adds one
    informational row saying how many domains formed how many clusters. That row carries counts only,
    and no domain name reaches it. This shipped first as a disclosure over unexamined clusters; the
    Added entry above then extended the scan itself to Pi-hole, so in this release the row appears
    when dense-cluster scanning is switched off.

  • Detectors skipped for the same reason are now reported on one line. Pointing sigwood at a
    single source - sigwood /var/log/pihole/ - previously printed one warning per skipped detector
    and repeated all of them in the report, so a first run could spend ten lines on sources you do
    not have. Detectors sharing an identical reason are now grouped, and the reason text is unchanged:
    a source that is configured but outside the paths you named still says so, rather than being
    described as unconfigured. Machine output is unaffected - the JSON report still carries a
    separate reason for every skipped detector.

  • A malformed [sigwood].home_net now stops the run at startup instead of quietly disabling your
    topology.
    Written as a bare string - home_net = "10.0.0.0/8" rather than
    home_net = ["10.0.0.0/8"] - the value was read as a list of single characters, none of which is
    a network. Depending on which detectors ran, that either silently left sigwood with no internal
    networks at all, so every address was treated as external and direction-aware analysis lost its
    meaning, or surfaced as an unhelpful error from the scan detector. sigwood now checks the value
    when it loads your configuration, names the offending entry, and shows the array form.