feat: Vuln debug logs
This commit is contained in:
@@ -51,11 +51,17 @@ func Start(ctx context.Context, deps Deps) {
|
||||
|
||||
dir, err := os.MkdirTemp("", "vantage-vulndb-")
|
||||
if err != nil {
|
||||
log.Printf("vulnsched: temp dir: %v", err)
|
||||
// The classic form of this is "stat /tmp: no such file or directory" on
|
||||
// the scratch runtime image. It is logged once at boot while everything
|
||||
// else runs normally, so the only other symptom is a fleet that never
|
||||
// reports a finding.
|
||||
log.Printf("vulnsched: temp dir: %v (scan loop NOT started)", err)
|
||||
return
|
||||
}
|
||||
|
||||
s := &scheduler{deps: deps, dir: dir}
|
||||
log.Printf("vulnsched: started, ref=%s tick=%s dir=%s debug=%t",
|
||||
vulndb.Ref(), tickInterval, dir, vulndb.DebugEnabled())
|
||||
|
||||
go func() {
|
||||
defer os.RemoveAll(dir)
|
||||
@@ -66,6 +72,7 @@ func Start(ctx context.Context, deps Deps) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
log.Println("vulnsched: leadership lost or shutting down, scan loop stopping")
|
||||
return
|
||||
case <-ticker.C:
|
||||
s.tick(ctx)
|
||||
@@ -75,16 +82,22 @@ func Start(ctx context.Context, deps Deps) {
|
||||
}
|
||||
|
||||
func (s *scheduler) tick(ctx context.Context) {
|
||||
started := time.Now()
|
||||
vulndb.Debugf("vulnsched tick starting (store loaded=%t, db version=%d, pulled %s ago)",
|
||||
s.store != nil, s.version, time.Since(s.pulled).Round(time.Second))
|
||||
|
||||
if err := s.ensureDB(ctx); err != nil {
|
||||
// Keep the last good database and carry on scanning against it. A
|
||||
// network blip must never clear findings or read as "all fixed".
|
||||
log.Printf("vulnsched: database unavailable: %v", err)
|
||||
s.recordDBError(ctx, err)
|
||||
if s.store == nil {
|
||||
log.Println("vulnsched: no database loaded at all, nothing can be scanned this tick")
|
||||
return
|
||||
}
|
||||
}
|
||||
s.scanPending(ctx)
|
||||
vulndb.Debugf("vulnsched tick finished in %s", time.Since(started).Round(time.Millisecond))
|
||||
}
|
||||
|
||||
// ensureDB pulls a fresh database when the local copy is stale, and marks the
|
||||
@@ -93,8 +106,11 @@ func (s *scheduler) tick(ctx context.Context) {
|
||||
// next agent report.
|
||||
func (s *scheduler) ensureDB(ctx context.Context) error {
|
||||
if s.store != nil && time.Since(s.pulled) < dbMaxAge {
|
||||
vulndb.Debugf("database is %s old, under the %s limit; not pulling",
|
||||
time.Since(s.pulled).Round(time.Second), dbMaxAge)
|
||||
return nil
|
||||
}
|
||||
log.Printf("vulnsched: pulling database (age %s, max %s)", time.Since(s.pulled).Round(time.Second), dbMaxAge)
|
||||
|
||||
version, err := vulndb.Pull(ctx, s.dir)
|
||||
if err != nil {
|
||||
@@ -110,6 +126,7 @@ func (s *scheduler) ensureDB(ctx context.Context) error {
|
||||
s.pulled = time.Now()
|
||||
|
||||
changed := version != s.version
|
||||
log.Printf("vulnsched: database ready, schema %d (previous %d, changed=%t)", version, s.version, changed)
|
||||
s.version = version
|
||||
|
||||
_, _ = db.Col("vulndb_meta").UpdateOne(ctx, bson.M{},
|
||||
@@ -152,6 +169,12 @@ func (s *scheduler) scanPending(ctx context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if len(pending) == 0 {
|
||||
vulndb.Debugf("no servers pending scan")
|
||||
return
|
||||
}
|
||||
log.Printf("vulnsched: %d server(s) pending scan", len(pending))
|
||||
|
||||
// Newly opened findings are collected across the whole tick and sent as one
|
||||
// digest per instance. A database refresh can open several hundred findings
|
||||
// at once; one message per finding would rate-limit the webhook or get the
|
||||
@@ -182,6 +205,8 @@ func (s *scheduler) scanPending(ctx context.Context) {
|
||||
|
||||
func (s *scheduler) scanOne(ctx context.Context, sp models.ServerPackages) []models.VulnFinding {
|
||||
now := time.Now()
|
||||
log.Printf("vulnsched: scanning server %s (instance %s, os %s %s, %d packages)",
|
||||
sp.ServerID, sp.InstanceID, sp.OS.Family, sp.OS.VersionID, len(sp.Packages))
|
||||
|
||||
results, err := vulndb.Match(s.store, sp.OS, sp.Packages)
|
||||
if err != nil {
|
||||
@@ -193,6 +218,9 @@ func (s *scheduler) scanOne(ctx context.Context, sp models.ServerPackages) []mod
|
||||
if !errors.Is(err, vulndb.ErrUnsupportedFamily) {
|
||||
log.Printf("vulnsched: scan %s: %v", sp.ServerID, err)
|
||||
status = sp.Status
|
||||
} else {
|
||||
log.Printf("vulnsched: server %s marked unsupported: no feed for %s %s",
|
||||
sp.ServerID, sp.OS.Family, sp.OS.VersionID)
|
||||
}
|
||||
s.clearPending(ctx, sp.ID, status, now)
|
||||
return nil
|
||||
@@ -210,6 +238,10 @@ func (s *scheduler) scanOne(ctx context.Context, sp models.ServerPackages) []mod
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Printf("vulnsched: server %s scanned: %d matches, %d existing, %d upserts, %d newly opened, %d reopened, %d fixed",
|
||||
sp.ServerID, len(results), len(existing), len(diff.Upserts),
|
||||
len(diff.NewlyOpened), len(diff.ReopenIDs), len(diff.FixedIDs))
|
||||
|
||||
s.clearPending(ctx, sp.ID, models.ScanStatusOK, now)
|
||||
|
||||
for i := range diff.NewlyOpened {
|
||||
|
||||
Reference in New Issue
Block a user