# checker-blacklist happyDomain checker that flags whether a domain is currently listed on widely-used reputation systems. ## Sources | Source | Type | API key needed | Configurable | |-----------------------|-----------------|----------------|--------------| | Spamhaus DBL | DNS-based DBL | no | admin (default on) | | SURBL multi | DNS-based DBL | no | admin (default on) | | URIBL multi | DNS-based DBL | no | admin (default on) | | Extra DNSBL zones | DNS-based DBL | no | admin | | Google Safe Browsing | HTTPS lookup | yes (admin) | admin | | OpenPhish public feed | downloaded list | no | user (default on) | | abuse.ch URLhaus | HTTPS lookup | optional Auth-Key (admin) | user (default on) | | VirusTotal v3 | HTTPS lookup | yes (admin) | admin | DNS-based blocklists are queried in parallel. The OpenPhish feed is downloaded once per hour by the provider and cached in memory. ## Common failure scenarios surfaced in the HTML report The report opens with a diagnosis-first "Action required" section that lists the most common, high-impact problems with a one-shot remediation: 1. **Listed on Spamhaus DBL / SURBL / URIBL**: direct lookup link and removal procedure URL per operator. 2. **Flagged by Google Safe Browsing**: link to Google Search Console's security-issues review request. 3. **Listed in the OpenPhish feed**: instructions to treat the host as compromised (audit recently-added files, rotate credentials), plus a link to OpenPhish feedback. 4. **Listed in URLhaus (active malware distribution)**: direct link to the abuse.ch reference page and per-URL takedown notification flow. 5. **VirusTotal multi-vendor flag**: Critical when at least one vendor reports `malicious`, Warning when only `suspicious`. Lists the flagging engines and links to the VT GUI page for re-scan / vendor contact. 6. **DNSBL query refused / API quota exhausted**: most public resolvers are blocked by DBL/URIBL operators; surfaced as a warning so it does not pollute the OK status. A per-source detail table follows for full context (return codes, TXT records, threat types, sample phishing URLs). ## Adding a new source Every reputation backend implements the `Source` interface in its own file and registers itself from `init()`. Skeleton: ```go package checker import ( "context" sdk "git.happydns.org/checker-sdk-go/checker" ) func init() { Register(&mySource{}) } type mySource struct{} func (*mySource) ID() string { return "mybl" } func (*mySource) Name() string { return "My Blocklist" } func (*mySource) Options() SourceOptions { return SourceOptions{ Admin: []sdk.CheckerOptionField{ /* … */ }, } } func (*mySource) Query(ctx context.Context, domain, registered string, opts sdk.CheckerOptions) []SourceResult { res := SourceResult{SourceID: "mybl", SourceName: "My Blocklist", Enabled: true} // …populate Listed / Severity / Reasons / Evidence / Reference / Error return []SourceResult{res} } func (*mySource) Diagnose(res SourceResult) Diagnosis { return Diagnosis{Severity: SeverityCrit, Title: "Listed", Detail: "…"} } ``` That's it: rules, the report, metrics, the standalone `/check` form and the definition pick the new source up automatically. Sources that need richer rendering (a per-vendor table, etc.) additionally implement `RenderDetail(SourceResult) (template.HTML, error)`. ## Build ```bash make # standalone binary (HTTP server + /check form) make plugin # checker-blacklist.so for happyDomain dynamic load make docker # container image ``` ## Running standalone ```bash ./checker-blacklist -listen :8080 # then GET /check, /definition, /health, … ``` The standalone binary embeds an `interactive` form on `GET /check` so a human can paste a domain and run the full pipeline without happyDomain. ## License MIT (checker code); Apache 2.0 SDK dependency.