add initial Go implementation of arcline-audit

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>
This commit is contained in:
Blake Ridgway
2026-06-23 05:08:34 -05:00
parent 088bb7e138
commit fce90f458c
13 changed files with 1167 additions and 11 deletions

73
cmd/arcline-audit/main.go Normal file
View File

@@ -0,0 +1,73 @@
package main
import (
"flag"
"fmt"
"net"
"os"
"time"
"arcline-audit/internal/dns"
httpcheck "arcline-audit/internal/http"
"arcline-audit/internal/infra"
"arcline-audit/internal/report"
"arcline-audit/internal/ssl"
"arcline-audit/internal/types"
)
func main() {
checksFlag := flag.String("checks", "all", "comma-separated list of checks: ssl,http,dns,infra")
jsonFlag := flag.Bool("json", false, "output as JSON")
outFlag := flag.String("out", "", "write report to file")
flag.Parse()
if flag.NArg() < 1 {
fmt.Fprintf(os.Stderr, "Usage: arcline-audit [flags] <domain>\n")
fmt.Fprintf(os.Stderr, "\nFlags:\n")
flag.PrintDefaults()
os.Exit(1)
}
domain := flag.Arg(0)
checkSet := types.ParseChecks(*checksFlag)
// Resolve the domain once so all checkers share the same IPs.
resolvedIPs, _ := net.LookupHost(domain)
result := types.AuditResult{
Domain: domain,
Time: time.Now(),
}
if checkSet&types.CheckSSL != 0 {
result.SSL = ssl.Run(domain)
}
if checkSet&types.CheckHTTP != 0 {
result.HTTP = httpcheck.Run(domain)
}
if checkSet&types.CheckDNS != 0 {
result.DNS = dns.Run(domain)
}
if checkSet&types.CheckInfra != 0 {
result.Infra = infra.Run(domain, resolvedIPs)
}
// Determine output writer
var w = os.Stdout
if *outFlag != "" {
f, err := os.Create(*outFlag)
if err != nil {
fmt.Fprintf(os.Stderr, "error: cannot create output file: %v\n", err)
os.Exit(1)
}
defer f.Close()
w = f
}
if *jsonFlag {
report.JSON(w, result)
} else {
report.Terminal(w, result)
}
}