Repository navigation
feat(freshness): weekly candidate PR from crt.sh, liveness and a graveyard - #88
Merged
Merged
Conversation
…eyard The list stopped being fed when the hunter crawler was retired, and it froze for 105 days before anyone noticed. This is the pipeline that keeps it fed without turning the repo into an auto-merging bot. Three sources, one reviewable PR, no automatic merge: - **crt.sh** — brand tokens are derived from the gambling list itself (no hard-coded list of brands), queried as `%brand%` since the numeric mirrors are separate registrable domains; internal `qa.`/`test.`/`api.` hosts are rejected (a probe of `bets10.com` returned 138 hostnames, all of them QA subdomains), and every candidate has to resolve before it is proposed. crt.sh answers 502 under load, so each query retries with backoff and a failed source does not stop the others. - **liveness** — plain `||domain^` rules are probed with the bounded prober. A rule is only proposed for removal after two rounds (≈2 weeks) *and* a second resolver via DoH, because one resolver's NXDOMAIN is not proof: parked domains, resolver-level filtering and CDN behaviour all look identical. If the second opinion cannot be obtained, nothing is removed. - **graveyard** — a removed domain is not forgotten: it stays tracked for 90 days and is proposed for re-addition if it answers again, which is exactly how rotating gambling mirrors behave. New rules younger than 30 days are never pruned. Output: `data/liveness.json` (auditable state), an additions block marked `! ══ OTOMATİK ADAYLAR (crt.sh) ══`, and a PR body that lists every candidate with its source. The job also warns when a new brand is missing from `GAMBLING_PATTERNS`, since such a domain would silently land in the *lite* list instead of the gambling one. Workflow runs weekly (Mon 04:00 UTC) and on demand; it shares the `main-writes` concurrency group so it cannot race the version bump, and a run with no list change commits only the state with `[skip ci]`. Tests: 20 network-free unit tests for the state machine, the mirror filter, the auto-block rewrite (idempotent) and the category-gap warning; wired into `make test-unit` and the PR gate. Demonstrated: a live run found `casibom--747.com` (resolving, not in the list), and the prune path removed two rules that two resolvers agreed were dead, then kept them in the graveyard.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The list stopped being fed when the hunter crawler was retired, and it froze for 105 days before anyone noticed. This is the pipeline that keeps it fed — one PR a week, never auto-merged.
Sources
crt.sh — new numeric mirrors. Brand tokens are derived from the gambling list itself, so a new brand needs no code change. Queries use
%brand%because the mirrors are separate registrable domains, not subdomains. Internal hosts are rejected: a probe ofbets10.comreturned 138 hostnames and every one was a QA subdomain (api.qa.,casinoblack.test.). Each query retries with backoff — crt.sh answered 502 on the first attempt and 200 on the second while I was measuring — and a dead source never stops the others. Candidates must resolve before they are proposed.liveness — dead-rule pruning. Plain
||domain^rules are probed with the bounded prober (the one that fixed the release hang). A rule is proposed for removal only after two rounds (≈2 weeks) and a second resolver via DoH, because one resolver's NXDOMAIN is not proof: parked domains, resolver-level filtering and CDN behaviour all look the same. If the second opinion cannot be obtained, nothing is removed.graveyard — resurrection. A removed domain stays tracked for 90 days and is proposed for re-addition if it answers again. That is exactly how gambling mirrors behave, and it was the flaw in my first design: once deleted, nothing looked again.
New rules younger than 30 days are never pruned.
Output
data/liveness.json— auditable state (first_seen,last_alive,dead_streak, graveyard withremoved_at)! ══ OTOMATİK ADAYLAR (crt.sh) ══, sorted, rewritten in place so a second run cannot duplicate themGAMBLING_PATTERNS— otherwise that domain silently lands in the lite list instead of the gambling oneWiring
workflow_dispatch(withtokens/skip_crtinputs)main-writesconcurrency group, so it cannot race the version bump[skip ci]make test-unitand in the PR gateDemonstrated, not just written
casibom--747.com— resolves, not in the listdolarkurum.com,r.yabancidizi.in) proposed after 2 rounds + DoH agreement, then removed and kept in the graveyardbetcupquery returned HTTPError → retried, logged, other sources continuedWorth knowing before merging
casibom--747.comcandidate (and possiblycasibommissing from the gambling patterns). That data PR is deliberately not part of this one.data/liveness.jsonstarts from today's probe: 1 426 domains, 2 marked dead once.