Updated osquery perf for #45550 (#48935)

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45550 

# Checklist for submitter

- [x] QA'd all new/changed functionality manually



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Enhanced Windows MDM SCEP certificate simulation to track issued
certificate specs per host during check-ins.

* **Bug Fixes**
* Certificate data generation is now stably ordered and consistent
across refreshes.
* SCEP certificate processing now ignores failed installs (no
certificate) and records only valid issued cert details.

* **Testing**
* A small subset of simulated agents may withhold one SCEP certificate
to exercise verification edge cases.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Victor Lyuboslavsky
2026-07-08 21:55:13 +01:00
committed by GitHub
parent 087e67644d
commit 0a3d73a732
2 changed files with 71 additions and 3 deletions
+21 -2
View File
@@ -547,8 +547,15 @@ type agent struct {
// cache of this host's per-host certificates (the certs unique to this host, excluding the shared certs every host
// reports). Note that this requires a mutex even though only used in a.processQuery, that's because both the runLoop
// and the live query goroutines may call DistributedWrite (which calls processQuery).
certificatesMutex sync.RWMutex
hostCertSpecs []simulatedCert
certificatesMutex sync.RWMutex
hostCertSpecs []simulatedCert
// scepCertSpecs holds the certs issued to this host during Windows MDM SCEP exchanges, keyed by the SCEP CSP
// unique ID so a re-issued cert replaces its predecessor.
scepCertSpecs map[string]simulatedCert
// withholdSCEPCert marks ~5% of hosts that never report their issued SCEP certs, exercising the server's SCEP
// verification backstop (test-only failure).
withholdSCEPCert bool
commonSoftwareNameSuffix string
entraIDDeviceID string
@@ -727,6 +734,8 @@ func newAgent(
cachedLastOpenedAt: make(map[string]*time.Time),
commonSoftwareNameSuffix: commonSoftwareNameSuffix,
mdmProfileFailureProb: mdmProfileFailureProb,
// Every 20th host (5%) withholds its issued SCEP certs to exercise the server's verification backstop (test-only failure).
withholdSCEPCert: agentIndex%20 == 0,
entraIDDeviceID: uuid.NewString(),
entraIDUserPrincipalName: fmt.Sprintf("fake-%s@example.com", randomString(5)),
@@ -1624,6 +1633,16 @@ func (a *agent) doWindowsMDMCheckIn(onDemand bool) (newPollInterval time.Duratio
continue
}
a.stats.IncrementMDMSCEPSuccess()
if res.Cert == nil {
continue
}
// Report the issued cert via the certificates detail query so the server observes the
// fleet-<profileUUID> renewal-ID marker and marks the SCEP profile verified. The withheld ~5% never
// report theirs, so the server's verification backstop fails those profiles.
if a.withholdSCEPCert {
continue
}
a.storeSCEPCertSpec(res.UniqueID, res.Cert)
}
}()
} else {
+50 -1
View File
@@ -2,11 +2,13 @@ package main
import (
"crypto/sha1" //nolint:gosec
"crypto/x509"
"encoding/hex"
"fmt"
"maps"
// osquery-perf shares one global math/rand RNG seeded from the --seed flag so load-test runs are reproducible
"math/rand" //nolint:depguard
"slices"
"strings"
"time"
@@ -151,12 +153,59 @@ func (a *agent) generateCertSpecs() []simulatedCert {
a.churnPerHostCertSpecs()
}
specs := make([]simulatedCert, 0, len(sharedCerts)+len(a.hostCertSpecs))
specs := make([]simulatedCert, 0, len(sharedCerts)+len(a.hostCertSpecs)+len(a.scepCertSpecs))
specs = append(specs, sharedCerts...)
specs = append(specs, a.hostCertSpecs...)
// Include the certs issued via Windows MDM SCEP exchanges (never churned; replaced only on re-issuance). Sorted
// by CSP unique ID so the report order is stable across refreshes.
for _, id := range slices.Sorted(maps.Keys(a.scepCertSpecs)) {
specs = append(specs, a.scepCertSpecs[id])
}
return specs
}
// storeSCEPCertSpec records a certificate issued during a Windows MDM SCEP exchange
func (a *agent) storeSCEPCertSpec(uniqueID string, cert *x509.Certificate) {
a.certificatesMutex.Lock()
defer a.certificatesMutex.Unlock()
if a.scepCertSpecs == nil {
a.scepCertSpecs = make(map[string]simulatedCert)
}
a.scepCertSpecs[uniqueID] = scepIssuedCertSpec(cert)
}
// scepIssuedCertSpec converts a certificate issued during a Windows MDM SCEP exchange into a simulatedCert. The
// cert's subject carries the fleet-<profileUUID> renewal-ID marker (expanded from the profile's
// $FLEET_VAR_SCEP_RENEWAL_ID), which the server matches on ingestion to flip the SCEP profile to verified. Reported
// machine-scoped: osquery-perf drives SCEP CSPs on the device channel, so the cert lands in the LocalMachine store.
func scepIssuedCertSpec(cert *x509.Certificate) simulatedCert {
return simulatedCert{
commonName: cert.Subject.CommonName,
subjectCommonName: cert.Subject.CommonName,
subjectOrg: firstOrEmpty(cert.Subject.Organization),
// Join multiple OUs with "+OU=", mirroring how osquery reports multi-OU certs
subjectOrgUnit: strings.Join(cert.Subject.OrganizationalUnit, "+OU="),
subjectCountry: firstOrEmpty(cert.Subject.Country),
issuerCommonName: cert.Issuer.CommonName,
issuerOrg: firstOrEmpty(cert.Issuer.Organization),
issuerCountry: firstOrEmpty(cert.Issuer.Country),
keyAlgorithm: "rsaEncryption",
keyStrength: "2048",
keyUsage: "Key Encipherment, Digital Signature",
signingAlgorithm: cert.SignatureAlgorithm.String(),
serial: cert.SerialNumber.String(),
notValidAfterUnix: fmt.Sprint(cert.NotAfter.Unix()),
notValidBeforeUnix: fmt.Sprint(cert.NotBefore.Unix()),
}
}
func firstOrEmpty(vals []string) string {
if len(vals) == 0 {
return ""
}
return vals[0]
}
// newPerHostCertSpecs generates 0-10 certificates unique to this host
func (a *agent) newPerHostCertSpecs() []simulatedCert {
count := rand.Intn(11) // 0..10