diff --git a/cmd/package/package.go b/cmd/package/package.go index 0ba6ef05bb..fa2c7af43a 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -38,6 +38,11 @@ func main() { Usage: "URL (host:port) of Fleet server", Destination: &opt.FleetURL, }, + &cli.StringFlag{ + Name: "fleet-certificate", + Usage: "Path to server cerificate bundle", + Destination: &opt.FleetCertificate, + }, &cli.StringFlag{ Name: "identifier", Usage: "Identifier for package product", diff --git a/pkg/packaging/deb.go b/pkg/packaging/deb.go index 0476348922..98825b9260 100644 --- a/pkg/packaging/deb.go +++ b/pkg/packaging/deb.go @@ -9,7 +9,6 @@ import ( "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/update" - "github.com/fleetdm/orbit/pkg/update/filestore" "github.com/goreleaser/nfpm/v2" "github.com/goreleaser/nfpm/v2/deb" "github.com/goreleaser/nfpm/v2/files" @@ -38,28 +37,17 @@ func BuildDeb(opt Options) error { // Initialize autoupdate metadata - localStore, err := filestore.New(filepath.Join(orbitRoot, "tuf-metadata.json")) - if err != nil { - return errors.Wrap(err, "failed to create local metadata store") - } updateOpt := update.DefaultOptions - updateOpt.RootDirectory = orbitRoot - updateOpt.ServerURL = "https://tuf.fleetctl.com" - updateOpt.LocalStore = localStore updateOpt.Platform = "linux" + updateOpt.RootDirectory = orbitRoot - updater, err := update.New(updateOpt) - if err != nil { - return errors.Wrap(err, "failed to init updater") + // TODO these should be configurable + updateOpt.ServerURL = "https://tuf.fleetctl.com" + osqueryChannel, orbitChannel := "stable", "stable" + + if err := initializeUpdates(updateOpt, osqueryChannel, orbitChannel); err != nil { + return errors.Wrap(err, "initialize updates") } - if err := updater.UpdateMetadata(); err != nil { - return errors.Wrap(err, "failed to update metadata") - } - osquerydPath, err := updater.Get("osqueryd", "stable") - if err != nil { - return errors.Wrap(err, "failed to get osqueryd") - } - log.Debug().Str("path", osquerydPath).Msg("got osqueryd") // Write files @@ -161,7 +149,7 @@ After=network.service syslog.service [Service] TimeoutStartSec=0 EnvironmentFile=/etc/default/orbit -ExecStart=/usr/local/bin/orbit +ExecStart=/var/lib/orbit/orbit Restart=on-failure KillMode=control-group KillSignal=SIGTERM @@ -181,6 +169,7 @@ WantedBy=multi-user.target var envTemplate = template.Must(template.New("env").Parse(` {{- if .Insecure }}ORBIT_INSECURE=true{{ end }} {{ if .FleetURL }}ORBIT_FLEET_URL={{.FleetURL}}{{ end }} +{{ if .FleetCertificate }}ORBIT_FLEET_CERTIFICATE=/var/lib/orbit/fleet.pem{{ end }} {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET={{.EnrollSecret}}{{ end }} `)) diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index 304af9cd2d..26ffb6f215 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -11,7 +11,6 @@ import ( "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/update" - "github.com/fleetdm/orbit/pkg/update/filestore" "github.com/pkg/errors" "github.com/rs/zerolog/log" ) @@ -41,28 +40,17 @@ func BuildPkg(opt Options) error { // Initialize autoupdate metadata - localStore, err := filestore.New(filepath.Join(orbitRoot, "tuf-metadata.json")) - if err != nil { - return errors.Wrap(err, "failed to create local metadata store") - } updateOpt := update.DefaultOptions - updateOpt.RootDirectory = orbitRoot - updateOpt.ServerURL = "https://tuf.fleetctl.com" - updateOpt.LocalStore = localStore updateOpt.Platform = "macos" + updateOpt.RootDirectory = orbitRoot - updater, err := update.New(updateOpt) - if err != nil { - return errors.Wrap(err, "failed to init updater") + // TODO these should be configurable + updateOpt.ServerURL = "https://tuf.fleetctl.com" + osqueryChannel, orbitChannel := "stable", "stable" + + if err := initializeUpdates(updateOpt, osqueryChannel, orbitChannel); err != nil { + return errors.Wrap(err, "initialize updates") } - if err := updater.UpdateMetadata(); err != nil { - return errors.Wrap(err, "failed to update metadata") - } - osquerydPath, err := updater.Get("osqueryd", "stable") - if err != nil { - return errors.Wrap(err, "failed to get osqueryd") - } - log.Debug().Str("path", osquerydPath).Msg("got osqueryd") // Write files @@ -83,6 +71,11 @@ func BuildPkg(opt Options) error { return errors.Wrap(err, "write launchd") } } + if opt.FleetCertificate != "" { + if err := writeCertificate(opt, orbitRoot); err != nil { + return errors.Wrap(err, "write fleet certificate") + } + } if err := copyFile( "./orbit", filepath.Join(orbitRoot, "bin", "orbit", "macos", "current", "orbit"), @@ -210,6 +203,17 @@ func writeDistribution(opt Options, rootPath string) error { return nil } +func writeCertificate(opt Options, orbitRoot string) error { + // Fleet TLS certificate + dstPath := filepath.Join(orbitRoot, "fleet.pem") + + if err := copyFile(opt.FleetCertificate, dstPath, 0644); err != nil { + return errors.Wrap(err, "write orbit") + } + + return nil +} + // xarBom creates the actual .pkg format. It's a xar archive with a BOM (Bill of // materials?). See http://bomutils.dyndns.org/tutorial.html. func xarBom(opt Options, rootPath string) error { diff --git a/pkg/packaging/macos_templates.go b/pkg/packaging/macos_templates.go index ebf451a850..8ecdea473c 100644 --- a/pkg/packaging/macos_templates.go +++ b/pkg/packaging/macos_templates.go @@ -70,6 +70,7 @@ var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=err {{ if .Insecure }}ORBIT_INSECUREtrue{{ end }} {{ if .FleetURL }}ORBIT_FLEET_URL{{.FleetURL}}{{ end }} + {{ if .FleetCertificate }}ORBIT_FLEET_CERTIFICATE/var/lib/orbit/fleet.pem{{ end }} {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET_PATH/var/lib/orbit/secret{{ end }} KeepAlive diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go index 2994a4db9f..7d75bf643d 100644 --- a/pkg/packaging/packaging.go +++ b/pkg/packaging/packaging.go @@ -6,7 +6,10 @@ import ( "os" "path/filepath" + "github.com/fleetdm/orbit/pkg/update" + "github.com/fleetdm/orbit/pkg/update/filestore" "github.com/pkg/errors" + "github.com/rs/zerolog/log" ) // Options are the configurable options provided for the package. @@ -29,6 +32,8 @@ type Options struct { SignIdentity string // Notarize sets whether macOS packages should be Notarized. Notarize bool + // FleetCertificate is a path to a server certificate to include in the package. + FleetCertificate string } func copyFile(srcPath, dstPath string, perm os.FileMode) error { @@ -54,3 +59,32 @@ func copyFile(srcPath, dstPath string, perm os.FileMode) error { return nil } + +func initializeUpdates(updateOpt update.Options, osqueryChannel, orbitChannel string) error { + localStore, err := filestore.New(filepath.Join(updateOpt.RootDirectory, "tuf-metadata.json")) + if err != nil { + return errors.Wrap(err, "failed to create local metadata store") + } + updateOpt.LocalStore = localStore + + updater, err := update.New(updateOpt) + if err != nil { + return errors.Wrap(err, "failed to init updater") + } + if err := updater.UpdateMetadata(); err != nil { + return errors.Wrap(err, "failed to update metadata") + } + osquerydPath, err := updater.Get("osqueryd", osqueryChannel) + if err != nil { + return errors.Wrap(err, "failed to get osqueryd") + } + log.Debug().Str("path", osquerydPath).Msg("got osqueryd") + + orbitPath, err := updater.Get("orbit", orbitChannel) + if err != nil { + return errors.Wrap(err, "failed to get orbit") + } + log.Debug().Str("path", orbitPath).Msg("got orbit") + + return nil +}