mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 17:08:53 +00:00
Update osquery-perf with DDM functionality (#18273)
This commit is contained in:
parent
8b9099717d
commit
9897649696
2 changed files with 210 additions and 20 deletions
|
|
@ -29,6 +29,7 @@ import (
|
|||
"github.com/fleetdm/fleet/v4/server/fleet"
|
||||
apple_mdm "github.com/fleetdm/fleet/v4/server/mdm/apple"
|
||||
"github.com/fleetdm/fleet/v4/server/mdm/microsoft/syncml"
|
||||
"github.com/fleetdm/fleet/v4/server/mdm/nanomdm/mdm"
|
||||
"github.com/fleetdm/fleet/v4/server/ptr"
|
||||
"github.com/fleetdm/fleet/v4/server/service"
|
||||
"github.com/google/uuid"
|
||||
|
|
@ -135,25 +136,33 @@ func init() {
|
|||
}
|
||||
|
||||
type Stats struct {
|
||||
startTime time.Time
|
||||
errors int
|
||||
osqueryEnrollments int
|
||||
orbitEnrollments int
|
||||
mdmEnrollments int
|
||||
mdmSessions int
|
||||
distributedWrites int
|
||||
mdmCommandsReceived int
|
||||
distributedReads int
|
||||
configRequests int
|
||||
configErrors int
|
||||
resultLogRequests int
|
||||
orbitErrors int
|
||||
mdmErrors int
|
||||
desktopErrors int
|
||||
distributedReadErrors int
|
||||
distributedWriteErrors int
|
||||
resultLogErrors int
|
||||
bufferedLogs int
|
||||
startTime time.Time
|
||||
errors int
|
||||
osqueryEnrollments int
|
||||
orbitEnrollments int
|
||||
mdmEnrollments int
|
||||
mdmSessions int
|
||||
distributedWrites int
|
||||
mdmCommandsReceived int
|
||||
distributedReads int
|
||||
configRequests int
|
||||
configErrors int
|
||||
resultLogRequests int
|
||||
orbitErrors int
|
||||
mdmErrors int
|
||||
ddmDeclarationItemsErrors int
|
||||
ddmConfigurationErrors int
|
||||
ddmActivationErrors int
|
||||
ddmStatusErrors int
|
||||
ddmDeclarationItemsSuccess int
|
||||
ddmConfigurationSuccess int
|
||||
ddmActivationSuccess int
|
||||
ddmStatusSuccess int
|
||||
desktopErrors int
|
||||
distributedReadErrors int
|
||||
distributedWriteErrors int
|
||||
resultLogErrors int
|
||||
bufferedLogs int
|
||||
|
||||
l sync.Mutex
|
||||
}
|
||||
|
|
@ -236,6 +245,54 @@ func (s *Stats) IncrementMDMErrors() {
|
|||
s.mdmErrors++
|
||||
}
|
||||
|
||||
func (s *Stats) IncrementDDMDeclarationItemsErrors() {
|
||||
s.l.Lock()
|
||||
defer s.l.Unlock()
|
||||
s.ddmDeclarationItemsErrors++
|
||||
}
|
||||
|
||||
func (s *Stats) IncrementDDMConfigurationErrors() {
|
||||
s.l.Lock()
|
||||
defer s.l.Unlock()
|
||||
s.ddmConfigurationErrors++
|
||||
}
|
||||
|
||||
func (s *Stats) IncrementDDMActivationErrors() {
|
||||
s.l.Lock()
|
||||
defer s.l.Unlock()
|
||||
s.ddmActivationErrors++
|
||||
}
|
||||
|
||||
func (s *Stats) IncrementDDMStatusErrors() {
|
||||
s.l.Lock()
|
||||
defer s.l.Unlock()
|
||||
s.ddmStatusErrors++
|
||||
}
|
||||
|
||||
func (s *Stats) IncrementDDMDeclarationItemsSuccess() {
|
||||
s.l.Lock()
|
||||
defer s.l.Unlock()
|
||||
s.ddmDeclarationItemsSuccess++
|
||||
}
|
||||
|
||||
func (s *Stats) IncrementDDMConfigurationSuccess() {
|
||||
s.l.Lock()
|
||||
defer s.l.Unlock()
|
||||
s.ddmConfigurationSuccess++
|
||||
}
|
||||
|
||||
func (s *Stats) IncrementDDMActivationSuccess() {
|
||||
s.l.Lock()
|
||||
defer s.l.Unlock()
|
||||
s.ddmActivationSuccess++
|
||||
}
|
||||
|
||||
func (s *Stats) IncrementDDMStatusSuccess() {
|
||||
s.l.Lock()
|
||||
defer s.l.Unlock()
|
||||
s.ddmStatusSuccess++
|
||||
}
|
||||
|
||||
func (s *Stats) IncrementDesktopErrors() {
|
||||
s.l.Lock()
|
||||
defer s.l.Unlock()
|
||||
|
|
@ -274,7 +331,7 @@ func (s *Stats) Log() {
|
|||
defer s.l.Unlock()
|
||||
|
||||
log.Printf(
|
||||
"uptime: %s, error rate: %.2f, osquery enrolls: %d, orbit enrolls: %d, mdm enrolls: %d, distributed/reads: %d, distributed/writes: %d, config requests: %d, result log requests: %d, mdm sessions initiated: %d, mdm commands received: %d, config errors: %d, distributed/read errors: %d, distributed/write errors: %d, log result errors: %d, orbit errors: %d, desktop errors: %d, mdm errors: %d, buffered logs: %d",
|
||||
"uptime: %s, error rate: %.2f, osquery enrolls: %d, orbit enrolls: %d, mdm enrolls: %d, distributed/reads: %d, distributed/writes: %d, config requests: %d, result log requests: %d, mdm sessions initiated: %d, mdm commands received: %d, config errors: %d, distributed/read errors: %d, distributed/write errors: %d, log result errors: %d, orbit errors: %d, desktop errors: %d, mdm errors: %d, ddm declaration items success: %d, ddm declaration items errors: %d, ddm activation success: %d, ddm activation errors: %d, ddm configuration success: %d, ddm configuration errors: %d, ddm status success: %d, ddm status errors: %d, buffered logs: %d",
|
||||
time.Since(s.startTime).Round(time.Second),
|
||||
float64(s.errors)/float64(s.osqueryEnrollments),
|
||||
s.osqueryEnrollments,
|
||||
|
|
@ -293,6 +350,14 @@ func (s *Stats) Log() {
|
|||
s.orbitErrors,
|
||||
s.desktopErrors,
|
||||
s.mdmErrors,
|
||||
s.ddmDeclarationItemsSuccess,
|
||||
s.ddmDeclarationItemsErrors,
|
||||
s.ddmActivationSuccess,
|
||||
s.ddmActivationErrors,
|
||||
s.ddmConfigurationSuccess,
|
||||
s.ddmConfigurationErrors,
|
||||
s.ddmStatusSuccess,
|
||||
s.ddmStatusErrors,
|
||||
s.bufferedLogs,
|
||||
)
|
||||
}
|
||||
|
|
@ -943,10 +1008,115 @@ func (a *agent) runMacosMDMLoop() {
|
|||
a.stats.IncrementMDMErrors()
|
||||
break INNER_FOR_LOOP
|
||||
}
|
||||
if mdmCommandPayload != nil && mdmCommandPayload.Command.RequestType == "DeclarativeManagement" {
|
||||
a.doDeclarativeManagement(mdmCommandPayload)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *agent) doDeclarativeManagement(cmd *mdm.Command) {
|
||||
// defer log.Printf("Exiting DeclarativeManagement for command %s", cmd.CommandUUID)
|
||||
|
||||
// get declaration-items endpoint
|
||||
r, err := a.macMDMClient.DeclarativeManagement("declaration-items")
|
||||
if err != nil {
|
||||
log.Printf("DDM %s declaration-items request failed: %s", cmd.CommandUUID, err)
|
||||
a.stats.IncrementDDMDeclarationItemsErrors()
|
||||
return
|
||||
}
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
log.Printf("DDM %s declaration-items read body failed: %s", cmd.CommandUUID, err)
|
||||
a.stats.IncrementDDMDeclarationItemsErrors()
|
||||
return
|
||||
}
|
||||
var items fleet.MDMAppleDDMDeclarationItemsResponse
|
||||
err = json.Unmarshal(body, &items)
|
||||
if err != nil {
|
||||
log.Printf("DDM %s declaration-items unmarshal failed: %s", cmd.CommandUUID, err)
|
||||
a.stats.IncrementDDMDeclarationItemsErrors()
|
||||
return
|
||||
}
|
||||
a.stats.IncrementDDMDeclarationItemsSuccess()
|
||||
|
||||
// get declaration/configuration/:identifer endpoint
|
||||
for _, d := range items.Declarations.Configurations {
|
||||
path := fmt.Sprintf("declaration/%s/%s", "configuration", d.Identifier)
|
||||
r, err := a.macMDMClient.DeclarativeManagement(path)
|
||||
if err != nil {
|
||||
log.Printf("DDM %s request failed: %s", path, err)
|
||||
a.stats.IncrementDDMConfigurationErrors()
|
||||
return
|
||||
}
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
log.Printf("DDM %s read body failed: %s", path, err)
|
||||
a.stats.IncrementDDMConfigurationErrors()
|
||||
return
|
||||
}
|
||||
var decl fleet.MDMAppleDeclaration
|
||||
err = json.Unmarshal(body, &decl)
|
||||
if err != nil {
|
||||
log.Printf("DDM %s unmarshal failed: %s", path, err)
|
||||
a.stats.IncrementDDMConfigurationErrors()
|
||||
return
|
||||
}
|
||||
}
|
||||
a.stats.IncrementDDMConfigurationSuccess()
|
||||
|
||||
// get declaration/activation/:identifer endpoint
|
||||
for _, d := range items.Declarations.Activations {
|
||||
path := fmt.Sprintf("declaration/%s/%s", "activation", d.Identifier)
|
||||
r, err := a.macMDMClient.DeclarativeManagement(path)
|
||||
if err != nil {
|
||||
log.Printf("DDM %s request failed: %s", path, err)
|
||||
a.stats.IncrementDDMActivationErrors()
|
||||
return
|
||||
}
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
log.Printf("DDM %s read body failed: %s", path, err)
|
||||
a.stats.IncrementDDMActivationErrors()
|
||||
return
|
||||
}
|
||||
var act fleet.MDMAppleDDMActivation
|
||||
err = json.Unmarshal(body, &act)
|
||||
if err != nil {
|
||||
log.Printf("DDM %s unmarshal failed: %s", path, err)
|
||||
a.stats.IncrementDDMActivationErrors()
|
||||
return
|
||||
}
|
||||
}
|
||||
a.stats.IncrementDDMActivationSuccess()
|
||||
|
||||
// sent status report
|
||||
for _, d := range items.Declarations.Configurations {
|
||||
report := fleet.MDMAppleDDMStatusReport{}
|
||||
report.StatusItems.Management.Declarations.Configurations = []fleet.MDMAppleDDMStatusDeclaration{
|
||||
{Active: true, Valid: fleet.MDMAppleDeclarationValid, Identifier: d.Identifier, ServerToken: d.ServerToken},
|
||||
}
|
||||
r, err := a.macMDMClient.DeclarativeManagement("status", report)
|
||||
if err != nil {
|
||||
log.Printf("DDM %s status request failed: %s", d.Identifier, err)
|
||||
a.stats.IncrementDDMStatusErrors()
|
||||
return
|
||||
}
|
||||
|
||||
// Apple's documentation has some conflicting information about the expected status here so we'll
|
||||
// just check for both.
|
||||
//
|
||||
// https://developer.apple.com/documentation/devicemanagement/get_the_device_status#response-codes
|
||||
// https://developer.apple.com/documentation/devicemanagement/statusreport#discussion
|
||||
if r.StatusCode != http.StatusOK && r.StatusCode != http.StatusNoContent {
|
||||
log.Printf("DDM %s status response unexpected: %d", d.Identifier, r.StatusCode)
|
||||
a.stats.IncrementDDMStatusErrors()
|
||||
return
|
||||
}
|
||||
}
|
||||
a.stats.IncrementDDMStatusSuccess()
|
||||
}
|
||||
|
||||
func (a *agent) runWindowsMDMLoop() {
|
||||
mdmCheckInTicker := time.Tick(a.MDMCheckInInterval)
|
||||
|
||||
|
|
|
|||
|
|
@ -819,3 +819,23 @@ type MDMAppleDDMStatusErrorReason struct {
|
|||
// error.
|
||||
Details map[string]any `json:"Details"`
|
||||
}
|
||||
|
||||
// MDMAppleDDMActivationPayload represents the payload of an activation declaration.
|
||||
//
|
||||
// https://developer.apple.com/documentation/devicemanagement/activationsimple
|
||||
type MDMAppleDDMActivationPayload struct {
|
||||
Predicate string `json:"Predicate"`
|
||||
StandardConfigurations []string `json:"StandardConfigurations"`
|
||||
}
|
||||
|
||||
// MDMAppleDDMActivation represents the declaration of an activation. It combines the base
|
||||
// declaation with the activation payload.
|
||||
//
|
||||
// https://developer.apple.com/documentation/devicemanagement/declarationbase
|
||||
// https://developer.apple.com/documentation/devicemanagement/activationsimple
|
||||
type MDMAppleDDMActivation struct {
|
||||
Identifier string `json:"Identifier"`
|
||||
Payload MDMAppleDDMActivationPayload `json:"Payload"`
|
||||
ServerToken string `json:"ServerToken"`
|
||||
Type string `json:"Type"` // "com.apple.activation.simple"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue