Skip to content

Commit

Permalink
Require server private key only when disk encryption enforcement is t…
Browse files Browse the repository at this point in the history
…urned on, skip FileVault config when enabling disk encryption when macOS MDM is off

Also ensures disk encryption on a per-team basis works as expected.

TODO: set up FileVault if Mac MDM gets enabled after encryption enforcement is enabled.
  • Loading branch information
iansltx committed Nov 23, 2024
1 parent 1a716f5 commit 986d069
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 18 deletions.
18 changes: 6 additions & 12 deletions ee/server/service/teams.go
Original file line number Diff line number Diff line change
Expand Up @@ -1516,15 +1516,15 @@ func unmarshalWithGlobalDefaults(b *json.RawMessage) (fleet.Features, error) {
}

func (svc *Service) updateTeamMDMDiskEncryption(ctx context.Context, tm *fleet.Team, enable *bool) error {
var didUpdate, didUpdateMacOSDiskEncryption bool
var didUpdate bool
if enable != nil {
if svc.config.Server.PrivateKey == "" {
return ctxerr.New(ctx, "Missing required private key. Learn how to configure the private key here: https://fleetdm.com/learn-more-about/fleet-server-private-key")
}
if tm.Config.MDM.EnableDiskEncryption != *enable {
if *enable && svc.config.Server.PrivateKey == "" {
return ctxerr.New(ctx, "Missing required private key. Learn how to configure the private key here: https://fleetdm.com/learn-more-about/fleet-server-private-key")
}

tm.Config.MDM.EnableDiskEncryption = *enable
didUpdate = true
didUpdateMacOSDiskEncryption = true
}
}

Expand All @@ -1537,13 +1537,7 @@ func (svc *Service) updateTeamMDMDiskEncryption(ctx context.Context, tm *fleet.T
if err != nil {
return err
}

// macOS-specific stuff. For legacy reasons we check if apple is configured
// via `appCfg.MDM.EnabledAndConfigured`
//
// TODO: is there a missing bitlocker activity feed item? (see same TODO on
// other methods that deal with disk encryption)
if appCfg.MDM.EnabledAndConfigured && didUpdateMacOSDiskEncryption {
if appCfg.MDM.EnabledAndConfigured {
var act fleet.ActivityDetails
if tm.Config.MDM.EnableDiskEncryption {
act = fleet.ActivityTypeEnabledMacosDiskEncryption{TeamID: &tm.ID, TeamName: &tm.Name}
Expand Down
2 changes: 1 addition & 1 deletion server/service/appconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ func (svc *Service) ModifyAppConfig(ctx context.Context, p []byte, applyOpts fle
// 1. To get the JSON value from the database
// 2. To update fields with the incoming values
if newAppConfig.MDM.EnableDiskEncryption.Valid {
if svc.config.Server.PrivateKey == "" {
if newAppConfig.MDM.EnableDiskEncryption.Value && svc.config.Server.PrivateKey == "" {
return nil, ctxerr.New(ctx, "Missing required private key. Learn how to configure the private key here: https://fleetdm.com/learn-more-about/fleet-server-private-key")
}
appConfig.MDM.EnableDiskEncryption = newAppConfig.MDM.EnableDiskEncryption
Expand Down
9 changes: 6 additions & 3 deletions server/service/apple_mdm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2152,20 +2152,23 @@ func (svc *Service) updateAppConfigMDMDiskEncryption(ctx context.Context, enable
return err
}

var didUpdate, didUpdateMacOSDiskEncryption bool
var didUpdate bool
if enabled != nil {
if ac.MDM.EnableDiskEncryption.Value != *enabled {
if *enabled && svc.config.Server.PrivateKey == "" {
return ctxerr.New(ctx, "Missing required private key. Learn how to configure the private key here: https://fleetdm.com/learn-more-about/fleet-server-private-key")
}

ac.MDM.EnableDiskEncryption = optjson.SetBool(*enabled)
didUpdate = true
didUpdateMacOSDiskEncryption = ac.MDM.EnabledAndConfigured
}
}

if didUpdate {
if err := svc.ds.SaveAppConfig(ctx, ac); err != nil {
return err
}
if didUpdateMacOSDiskEncryption {
if ac.MDM.EnabledAndConfigured { // if macOS MDM is configured, set up FileVault escrow
var act fleet.ActivityDetails
if ac.MDM.EnableDiskEncryption.Value {
act = fleet.ActivityTypeEnabledMacosDiskEncryption{}
Expand Down
47 changes: 45 additions & 2 deletions server/service/integration_enterprise_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2885,7 +2885,7 @@ func (s *integrationEnterpriseTestSuite) TestLinuxDiskEncryption() {
t := s.T()

// create a Linux host
hostLin, err := s.ds.NewHost(context.Background(), &fleet.Host{
noTeamHost, err := s.ds.NewHost(context.Background(), &fleet.Host{
DetailUpdatedAt: time.Now(),
LabelUpdatedAt: time.Now(),
PolicyUpdatedAt: time.Now(),
Expand All @@ -2900,14 +2900,35 @@ func (s *integrationEnterpriseTestSuite) TestLinuxDiskEncryption() {
OSVersion: "Ubuntu 22.04",
})
require.NoError(t, err)
team, err := s.ds.NewTeam(context.Background(), &fleet.Team{Name: "A team"})
require.NoError(t, err)
teamID := ptr.Uint(team.ID)
teamHost, err := s.ds.NewHost(context.Background(), &fleet.Host{
DetailUpdatedAt: time.Now(),
LabelUpdatedAt: time.Now(),
PolicyUpdatedAt: time.Now(),
SeenTime: time.Now(),
NodeKey: ptr.String(strings.ReplaceAll(t.Name(), "/", "_") + "2"),
OsqueryHostID: ptr.String(strings.ReplaceAll(t.Name(), "/", "_") + "2"),
UUID: t.Name() + "2",
Hostname: t.Name() + "foo2.local",
PrimaryIP: "192.168.1.2",
PrimaryMac: "30-65-EC-6F-C4-59",
Platform: "rhel",
OSVersion: "Fedora 38.0",
TeamID: teamID,
})
require.NoError(t, err)

// NO TEAM //

// config profiles endpoint should work but show all zeroes
var profileSummary getMDMProfilesSummaryResponse
s.DoJSON("GET", "/api/latest/fleet/configuration_profiles/summary", getMDMProfilesSummaryRequest{}, http.StatusOK, &profileSummary)
require.Equal(t, fleet.MDMProfilesSummary{}, profileSummary.MDMProfilesSummary)

// set encrypted for host
require.NoError(t, s.ds.SetOrUpdateHostDisksEncryption(context.Background(), hostLin.ID, true))
require.NoError(t, s.ds.SetOrUpdateHostDisksEncryption(context.Background(), noTeamHost.ID, true))

// should still show zeroes
s.DoJSON("GET", "/api/latest/fleet/configuration_profiles/summary", getMDMProfilesSummaryRequest{}, http.StatusOK, &profileSummary)
Expand All @@ -2926,6 +2947,28 @@ func (s *integrationEnterpriseTestSuite) TestLinuxDiskEncryption() {
s.DoJSON("GET", "/api/latest/fleet/disk_encryption", getMDMDiskEncryptionSummaryRequest{}, http.StatusOK, &summary)
// disk is encrypted but key hasn't been escrowed yet
require.Equal(t, fleet.MDMDiskEncryptionSummary{ActionRequired: fleet.MDMPlatformsCounts{Linux: 1}}, *summary.MDMDiskEncryptionSummary)

// TEAM //
s.DoJSON("GET", "/api/latest/fleet/configuration_profiles/summary", getMDMProfilesSummaryRequest{TeamID: teamID}, http.StatusOK, &profileSummary)
require.Equal(t, fleet.MDMProfilesSummary{}, profileSummary.MDMProfilesSummary)

// set encrypted for host
require.NoError(t, s.ds.SetOrUpdateHostDisksEncryption(context.Background(), teamHost.ID, true))

// should still show zeroes
s.DoJSON("GET", "/api/latest/fleet/configuration_profiles/summary", getMDMProfilesSummaryRequest{TeamID: teamID}, http.StatusOK, &profileSummary)
require.Equal(t, fleet.MDMProfilesSummary{}, profileSummary.MDMProfilesSummary)

// turn on disk encryption enforcement for team
s.Do("POST", "/api/latest/fleet/disk_encryption", updateDiskEncryptionRequest{TeamID: teamID, EnableDiskEncryption: true}, http.StatusNoContent)

// should show the Linux host as pending
s.DoJSON("GET", "/api/latest/fleet/configuration_profiles/summary", getMDMProfilesSummaryRequest{TeamID: teamID}, http.StatusOK, &profileSummary)
require.Equal(t, fleet.MDMProfilesSummary{Pending: 1}, profileSummary.MDMProfilesSummary)

// encryption summary should show host as action required
s.DoJSON("GET", "/api/latest/fleet/disk_encryption", getMDMDiskEncryptionSummaryRequest{TeamID: teamID}, http.StatusOK, &summary)
require.Equal(t, fleet.MDMDiskEncryptionSummary{ActionRequired: fleet.MDMPlatformsCounts{Linux: 1}}, *summary.MDMDiskEncryptionSummary)
}

func (s *integrationEnterpriseTestSuite) TestListDevicePolicies() {
Expand Down
1 change: 1 addition & 0 deletions server/service/mdm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2613,6 +2613,7 @@ func (svc *Service) UploadMDMAppleAPNSCert(ctx context.Context, cert io.ReadSeek
}

appCfg.MDM.EnabledAndConfigured = true
// TODO for each team (or no-team) set up for disk encryption, enable FileVault

return svc.ds.SaveAppConfig(ctx, appCfg)
}
Expand Down

0 comments on commit 986d069

Please sign in to comment.