Skip to content

Commit

Permalink
Added activity item for fleetd enrollment with host serial and displa…
Browse files Browse the repository at this point in the history
…y name.
  • Loading branch information
getvictor committed Nov 13, 2024
1 parent b25034d commit 3a29177
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 12 deletions.
1 change: 1 addition & 0 deletions changes/22810-fleetd-enroll-activity
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added activity item for fleetd enrollment with host serial and display name.
17 changes: 17 additions & 0 deletions docs/Contributing/Audit-logs.md
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,23 @@ This activity contains the following fields:
}
```

## fleet_enrolled

Generated when a host is enrolled to Fleet (Fleet's agent fleetd is installed).

This activity contains the following fields:
- "host_serial": Serial number of the host.
- "host_display_name": Display name of the host.

#### Example

```json
{
"host_serial": "B04FL3ALPT21",
"host_display_name": "WIN-DESKTOP-JGS78KJ7C"
}
```

## mdm_enrolled

Generated when a host is enrolled in Fleet's MDM.
Expand Down
2 changes: 2 additions & 0 deletions orbit/changes/22810-fleetd-enroll-activity
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Added computer_name and hardware_model for fleetd enrollment.
Added serial number for fleetd enrollment for Windows hosts (already present for macOS and Linux).
26 changes: 18 additions & 8 deletions orbit/cmd/orbit/orbit.go
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,8 @@ func main() {
HardwareUUID: osqueryHostInfo.HardwareUUID,
Hostname: osqueryHostInfo.Hostname,
Platform: osqueryHostInfo.Platform,
ComputerName: osqueryHostInfo.ComputerName,
HardwareModel: osqueryHostInfo.HardwareModel,
}

if runtime.GOOS == "darwin" {
Expand Down Expand Up @@ -737,13 +739,6 @@ func main() {
orbitHostInfo.OsqueryIdentifier = osqueryHostInfo.InstanceID
}

// The hardware serial was not sent when Windows MDM was implemented,
// thus we clear its value here to not break any existing enroll functionality
// on the server.
if runtime.GOOS == "windows" {
orbitHostInfo.HardwareSerial = ""
}

var (
options []osquery.Option
// optionsAfterFlagfile is populated with options that will be set after the '--flagfile' argument
Expand Down Expand Up @@ -1697,6 +1692,10 @@ type osqueryHostInfo struct {
HardwareSerial string `json:"hardware_serial"`
// Hostname is the device's hostname (extracted from `system_info` osquery table).
Hostname string `json:"hostname"`
// ComputerName is the friendly computer name (optional) (extracted from `system_info` osquery table).
ComputerName string `json:"computer_name"`
// HardwareModel is the device's hardware model (extracted from `system_info` osquery table).
HardwareModel string `json:"hardware_model"`
// Platform is the device's platform as defined by osquery (extracted from `os_version` osquery table).
Platform string `json:"platform"`
// InstanceID is the osquery's randomly generated instance ID
Expand All @@ -1714,7 +1713,18 @@ func getHostInfo(osqueryPath string, osqueryDBPath string) (*osqueryHostInfo, er
if err := os.MkdirAll(filepath.Dir(osqueryDBPath), constant.DefaultDirMode); err != nil {
return nil, err
}
const systemQuery = "SELECT si.uuid, si.hardware_serial, si.hostname, os.platform, os.version as os_version, oi.instance_id, oi.version as osquery_version FROM system_info si, os_version os, osquery_info oi"
const systemQuery = `
SELECT
si.uuid,
si.hardware_serial,
si.hostname,
si.computer_name,
si.hardware_model,
os.platform,
os.version as os_version,
oi.instance_id,
oi.version as osquery_version
FROM system_info si, os_version os, osquery_info oi`
args := []string{
"-S",
"--database_path", osqueryDBPath,
Expand Down
17 changes: 14 additions & 3 deletions server/datastore/mysql/hosts.go
Original file line number Diff line number Diff line change
Expand Up @@ -1904,7 +1904,12 @@ func (ds *Datastore) EnrollOrbit(ctx context.Context, isMDMEnabled bool, hostInf
}
// NOTE: allow an empty serial, currently it is empty for Windows.

var host fleet.Host
host := fleet.Host{
ComputerName: hostInfo.ComputerName,
Hostname: hostInfo.Hostname,
HardwareModel: hostInfo.HardwareModel,
HardwareSerial: hostInfo.HardwareSerial,
}
err := ds.withRetryTxx(ctx, func(tx sqlx.ExtContext) error {
enrolledHostInfo, err := matchHostDuringEnrollment(ctx, tx, orbitEnroll, isMDMEnabled, hostInfo.OsqueryIdentifier, hostInfo.HardwareUUID, hostInfo.HardwareSerial)

Expand Down Expand Up @@ -1936,6 +1941,8 @@ func (ds *Datastore) EnrollOrbit(ctx context.Context, isMDMEnabled bool, hostInf
uuid = COALESCE(NULLIF(uuid, ''), ?),
osquery_host_id = COALESCE(NULLIF(osquery_host_id, ''), ?),
hardware_serial = COALESCE(NULLIF(hardware_serial, ''), ?),
computer_name = COALESCE(NULLIF(computer_name, ''), ?),
hardware_model = COALESCE(NULLIF(hardware_model, ''), ?),
team_id = ?
WHERE id = ?`
_, err := tx.ExecContext(ctx, sqlUpdate,
Expand Down Expand Up @@ -1977,6 +1984,8 @@ func (ds *Datastore) EnrollOrbit(ctx context.Context, isMDMEnabled bool, hostInf
orbit_node_key,
hardware_serial,
hostname,
computer_name,
hardware_model,
platform
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?)
`
Expand All @@ -1992,16 +2001,18 @@ func (ds *Datastore) EnrollOrbit(ctx context.Context, isMDMEnabled bool, hostInf
orbitNodeKey,
hostInfo.HardwareSerial,
hostInfo.Hostname,
hostInfo.ComputerName,
hostInfo.HardwareModel,
hostInfo.Platform,
)
if err != nil {
return ctxerr.Wrap(ctx, err, "orbit enroll error inserting host details")
}
hostID, _ := result.LastInsertId()
const sqlHostDisplayName = `
INSERT INTO host_display_names (host_id, display_name) VALUES (?, '')
INSERT INTO host_display_names (host_id, display_name) VALUES (?, ?)
`
_, err = tx.ExecContext(ctx, sqlHostDisplayName, hostID)
_, err = tx.ExecContext(ctx, sqlHostDisplayName, hostID, host.DisplayName())
if err != nil {
return ctxerr.Wrap(ctx, err, "insert host_display_names")
}
Expand Down
20 changes: 20 additions & 0 deletions server/fleet/activities.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ var ActivityDetailsList = []ActivityDetails{
ActivityTypeChangedUserTeamRole{},
ActivityTypeDeletedUserTeamRole{},

ActivityTypeFleetEnrolled{},
ActivityTypeMDMEnrolled{},
ActivityTypeMDMUnenrolled{},

Expand Down Expand Up @@ -795,6 +796,25 @@ func (a ActivityTypeDeletedUserTeamRole) Documentation() (activity string, detai
}`
}

type ActivityTypeFleetEnrolled struct {
HostSerial string `json:"host_serial"`
HostDisplayName string `json:"host_display_name"`
}

func (a ActivityTypeFleetEnrolled) ActivityName() string {
return "fleet_enrolled"
}

func (a ActivityTypeFleetEnrolled) Documentation() (activity string, details string, detailsExample string) {
return `Generated when a host is enrolled to Fleet (Fleet's agent fleetd is installed).`,
`This activity contains the following fields:
- "host_serial": Serial number of the host.
- "host_display_name": Display name of the host.`, `{
"host_serial": "B04FL3ALPT21",
"host_display_name": "WIN-DESKTOP-JGS78KJ7C"
}`
}

type ActivityTypeMDMEnrolled struct {
HostSerial string `json:"host_serial"`
HostDisplayName string `json:"host_display_name"`
Expand Down
4 changes: 4 additions & 0 deletions server/fleet/orbit.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ type OrbitHostInfo struct {
//
// If not set, then the HardwareUUID is used/set as the osquery identifier.
OsqueryIdentifier string
// ComputerName is the device's friendly name (optional).
ComputerName string
// HardwareModel is the device's hardware model. For example: Standard PC (Q35 + ICH9, 2009)
HardwareModel string
}

// ExtensionInfo holds the data of a osquery extension to apply to an Orbit client.
Expand Down
21 changes: 20 additions & 1 deletion server/service/orbit.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ type EnrollOrbitRequest struct {
// OsqueryIdentifier holds the identifier used by osquery.
// If not set, then the hardware UUID is used to match orbit and osquery.
OsqueryIdentifier string `json:"osquery_identifier"`
// ComputerName is the device's friendly name (optional).
ComputerName string `json:"computer_name"`
// HardwareModel is the device's hardware model.
HardwareModel string `json:"hardware_model"`
}

type EnrollOrbitResponse struct {
Expand Down Expand Up @@ -90,6 +94,8 @@ func enrollOrbitEndpoint(ctx context.Context, request interface{}, svc fleet.Ser
Hostname: req.Hostname,
Platform: req.Platform,
OsqueryIdentifier: req.OsqueryIdentifier,
ComputerName: req.ComputerName,
HardwareModel: req.HardwareModel,
}, req.EnrollSecret)
if err != nil {
return EnrollOrbitResponse{Err: err}, nil
Expand Down Expand Up @@ -129,6 +135,8 @@ func (svc *Service) EnrollOrbit(ctx context.Context, hostInfo fleet.OrbitHostInf
"hostname", hostInfo.Hostname,
"platform", hostInfo.Platform,
"osquery_identifier", hostInfo.OsqueryIdentifier,
"computer_name", hostInfo.ComputerName,
"hardware_model", hostInfo.HardwareModel,
),
level.Info,
)
Expand All @@ -155,11 +163,22 @@ func (svc *Service) EnrollOrbit(ctx context.Context, hostInfo fleet.OrbitHostInf
return "", fleet.OrbitError{Message: "app config load failed: " + err.Error()}
}

_, err = svc.ds.EnrollOrbit(ctx, appConfig.MDM.EnabledAndConfigured, hostInfo, orbitNodeKey, secret.TeamID)
host, err := svc.ds.EnrollOrbit(ctx, appConfig.MDM.EnabledAndConfigured, hostInfo, orbitNodeKey, secret.TeamID)
if err != nil {
return "", fleet.OrbitError{Message: "failed to enroll " + err.Error()}
}

if err := svc.NewActivity(
ctx,
nil,
fleet.ActivityTypeFleetEnrolled{
HostSerial: hostInfo.HardwareSerial,
HostDisplayName: host.DisplayName(),
},
); err != nil {
level.Error(svc.logger).Log("msg", "record fleet enroll activity", "err", err)
}

return orbitNodeKey, nil
}

Expand Down

0 comments on commit 3a29177

Please sign in to comment.