Implements the full site health auditor with four check groups: - SSL/TLS (certificate validity, expiry, chain, TLS version, ciphers) - HTTP (redirect chain, security headers, response time) - DNS (A/AAAA, MX, SPF, DKIM, DMARC, DNSSEC) - Infrastructure (CDN detection, common port probes) Includes CLI with --checks filter, --json and --out flags, cross-compile Makefile, and GitLab CI pipeline. Signed-off-by: Blake Ridgway <blake@blakeridgway.com>
112 lines
2.5 KiB
Go
112 lines
2.5 KiB
Go
package types
|
|
|
|
import "time"
|
|
|
|
// Status represents the result status of a single check.
|
|
type Status string
|
|
|
|
const (
|
|
StatusOK Status = "OK"
|
|
StatusWarn Status = "WARN"
|
|
StatusFail Status = "FAIL"
|
|
StatusInfo Status = "INFO"
|
|
)
|
|
|
|
// CheckResult represents the outcome of a single audit check.
|
|
type CheckResult struct {
|
|
Status Status `json:"status"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
// SSLResult holds all SSL/TLS check results.
|
|
type SSLResult struct {
|
|
Checks []CheckResult `json:"checks"`
|
|
Issuer string `json:"issuer,omitempty"`
|
|
Expiry time.Time `json:"expiry,omitempty"`
|
|
DaysLeft int `json:"days_left,omitempty"`
|
|
TLSVersion string `json:"tls_version,omitempty"`
|
|
}
|
|
|
|
// HTTPResult holds all HTTP check results.
|
|
type HTTPResult struct {
|
|
Checks []CheckResult `json:"checks"`
|
|
ResponseTime time.Duration `json:"response_time_ms"`
|
|
FinalURL string `json:"final_url,omitempty"`
|
|
RedirectHops int `json:"redirect_hops,omitempty"`
|
|
}
|
|
|
|
// DNSResult holds all DNS check results.
|
|
type DNSResult struct {
|
|
Checks []CheckResult `json:"checks"`
|
|
}
|
|
|
|
// InfraResult holds all infrastructure check results.
|
|
type InfraResult struct {
|
|
Checks []CheckResult `json:"checks"`
|
|
ASN string `json:"asn,omitempty"`
|
|
Org string `json:"org,omitempty"`
|
|
CDN string `json:"cdn,omitempty"`
|
|
}
|
|
|
|
// AuditResult is the top-level result containing all check sections.
|
|
type AuditResult struct {
|
|
Domain string `json:"domain"`
|
|
Time time.Time `json:"time"`
|
|
SSL SSLResult `json:"ssl"`
|
|
HTTP HTTPResult `json:"http"`
|
|
DNS DNSResult `json:"dns"`
|
|
Infra InfraResult `json:"infra"`
|
|
}
|
|
|
|
// CheckSet is a bitmask of check categories for filtering.
|
|
type CheckSet int
|
|
|
|
const (
|
|
CheckSSL CheckSet = 1 << iota
|
|
CheckHTTP
|
|
CheckDNS
|
|
CheckInfra
|
|
CheckAll = CheckSSL | CheckHTTP | CheckDNS | CheckInfra
|
|
)
|
|
|
|
// ParseChecks parses a comma-separated list of check names into a CheckSet.
|
|
func ParseChecks(s string) CheckSet {
|
|
if s == "" || s == "all" {
|
|
return CheckAll
|
|
}
|
|
var cs CheckSet
|
|
m := map[string]CheckSet{
|
|
"ssl": CheckSSL,
|
|
"http": CheckHTTP,
|
|
"dns": CheckDNS,
|
|
"infra": CheckInfra,
|
|
}
|
|
for _, name := range splitCSV(s) {
|
|
if v, ok := m[name]; ok {
|
|
cs |= v
|
|
}
|
|
}
|
|
if cs == 0 {
|
|
return CheckAll
|
|
}
|
|
return cs
|
|
}
|
|
|
|
func splitCSV(s string) []string {
|
|
var parts []string
|
|
start := 0
|
|
for i := 0; i < len(s); i++ {
|
|
if s[i] == ',' {
|
|
if i > start {
|
|
parts = append(parts, s[start:i])
|
|
}
|
|
start = i + 1
|
|
}
|
|
}
|
|
if start < len(s) {
|
|
parts = append(parts, s[start:])
|
|
}
|
|
return parts
|
|
}
|
|
|