Work around Sequoia's "Local Network" permission with a helper process (#302)

* Work around Sequoia's "Local Network" permission with a helper process

* README.md: macOS 15 (Sequoia) warning

* Make "orchard dev" unix-specific too, otherwise Release fails

* Fix typo in "localNetworkHerlper"

* Slightly improve the macOS 15 (Sequoia) note

* orchard worker run: better documentation for --user

* Make sure privilege dropping is the first step we do in runWorker()
This commit is contained in:
Nikolay Edigaryev
2025-04-10 18:01:19 +04:00
committed by GitHub
parent fa38fe72ed
commit abcfee677d
16 changed files with 201 additions and 32 deletions
+39 -10
View File
@@ -1,8 +1,12 @@
//go:build unix
package worker
import (
"errors"
"fmt"
"github.com/cirruslabs/chacha/pkg/localnetworkhelper"
"github.com/cirruslabs/chacha/pkg/privdrop"
"github.com/cirruslabs/orchard/internal/bootstraptoken"
"github.com/cirruslabs/orchard/internal/netconstants"
"github.com/cirruslabs/orchard/internal/worker"
@@ -32,6 +36,7 @@ var labels map[string]string
var noPKI bool
var defaultCPU uint64
var defaultMemory uint64
var username string
var debug bool
func newRunCommand() *cobra.Command {
@@ -62,17 +67,46 @@ func newRunCommand() *cobra.Command {
"that do not explicitly specify a value")
cmd.PersistentFlags().Uint64Var(&defaultMemory, "default-memory", 8*1024, "megabytes of memory "+
"to use for VMs that do not explicitly specify a value")
cmd.Flags().StringVar(&username, "user", "", "username to drop privileges to "+
"(\"Local Network\" permission workaround: requires starting \"orchard worker run\" as \"root\", "+
"the privileges will be then dropped to the specified user after starting the \"orchard localnetworkhelper\" "+
"helper process)")
cmd.PersistentFlags().BoolVar(&debug, "debug", false, "enable debug logging")
return cmd
}
func runWorker(cmd *cobra.Command, args []string) (err error) {
var clientOpts []client.Option
workerOpts := []worker.Option{
worker.WithName(name),
worker.WithLabels(labels),
worker.WithDefaultCPUAndMemory(defaultCPU, defaultMemory),
}
// Run the macOS "Local Network" permission helper
// when privilege dropping is requested
if username != "" {
localNetworkHelper, err := localnetworkhelper.New(cmd.Context())
if err != nil {
return err
}
clientOpts = append(clientOpts, client.WithDialContext(localNetworkHelper.PrivilegedDialContext))
workerOpts = append(workerOpts, worker.WithLocalNetworkHelper(localNetworkHelper))
if err := privdrop.Drop(username); err != nil {
return err
}
}
// Parse controller URL
controllerURL, err := netconstants.NormalizeAddress(args[0])
if err != nil {
return err
}
clientOpts = append(clientOpts, client.WithAddress(controllerURL.String()))
// Parse bootstrap token
bootstrapTokenRaw, err := readBootstrapToken()
@@ -86,17 +120,15 @@ func runWorker(cmd *cobra.Command, args []string) (err error) {
if err != nil {
return err
}
clientOpts = append(clientOpts, client.WithCredentials(bootstrapToken.ServiceAccountName(),
bootstrapToken.ServiceAccountToken()))
// Convert resources
resources, err := v1.NewResourcesFromStringToString(stringToStringResources)
if err != nil {
return fmt.Errorf("%w: %v", ErrRunFailed, err)
}
clientOpts := []client.Option{
client.WithAddress(controllerURL.String()),
client.WithCredentials(bootstrapToken.ServiceAccountName(), bootstrapToken.ServiceAccountToken()),
}
workerOpts = append(workerOpts, worker.WithResources(resources))
if trustedCertificate := bootstrapToken.Certificate(); trustedCertificate != nil {
clientOpts = append(clientOpts, client.WithTrustedCertificate(trustedCertificate))
@@ -120,14 +152,11 @@ func runWorker(cmd *cobra.Command, args []string) (err error) {
err = syncErr
}
}()
workerOpts = append(workerOpts, worker.WithLogger(logger))
workerInstance, err := worker.New(
controllerClient,
worker.WithName(name),
worker.WithResources(resources),
worker.WithLabels(labels),
worker.WithDefaultCPUAndMemory(defaultCPU, defaultMemory),
worker.WithLogger(logger),
workerOpts...,
)
if err != nil {
return err
+2
View File
@@ -1,3 +1,5 @@
//go:build unix
package worker
import (
@@ -0,0 +1,9 @@
//go:build !unix
package worker
import "github.com/spf13/cobra"
func NewCommand() *cobra.Command {
return nil
}