mirror of
https://github.com/cirruslabs/orchard.git
synced 2026-10-17 20:25:50 +02:00
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:
@@ -1,3 +1,5 @@
|
||||
//go:build unix
|
||||
|
||||
package dev
|
||||
|
||||
import (
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
//go:build !unix
|
||||
|
||||
package dev
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
func NewCommand() *cobra.Command {
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
//go:build unix
|
||||
|
||||
package localnetworkhelper
|
||||
|
||||
import (
|
||||
"github.com/cirruslabs/chacha/pkg/localnetworkhelper"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: localnetworkhelper.CommandName,
|
||||
Short: "Run the macOS \"Local Network\" permission helper process",
|
||||
Hidden: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
// In localnetworkhelper.New(), a macOS "Local Network"
|
||||
// permission helper process is spawned and receives
|
||||
// its socketpair(2) end via ExtraFiles field of Golang's
|
||||
// exec.Cmd[1].
|
||||
//
|
||||
// This socketpair(2) end becomes FD number 3 here,
|
||||
// according to the ExtraFiles documentation[1]:
|
||||
//
|
||||
// >If non-nil, entry i becomes file descriptor 3+i.
|
||||
//
|
||||
// [1]: https://pkg.go.dev/os/exec#Cmd
|
||||
return localnetworkhelper.Serve(3)
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
//go:build !unix
|
||||
|
||||
package localnetworkhelper
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCommand() *cobra.Command {
|
||||
return nil
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/cirruslabs/orchard/internal/command/dev"
|
||||
"github.com/cirruslabs/orchard/internal/command/get"
|
||||
"github.com/cirruslabs/orchard/internal/command/list"
|
||||
"github.com/cirruslabs/orchard/internal/command/localnetworkhelper"
|
||||
"github.com/cirruslabs/orchard/internal/command/logs"
|
||||
"github.com/cirruslabs/orchard/internal/command/pause"
|
||||
"github.com/cirruslabs/orchard/internal/command/portforward"
|
||||
@@ -37,6 +38,10 @@ func NewRootCmd() *cobra.Command {
|
||||
},
|
||||
}
|
||||
|
||||
if localNetworkHelperCommand := localnetworkhelper.NewCommand(); localNetworkHelperCommand != nil {
|
||||
command.AddCommand(localNetworkHelperCommand)
|
||||
}
|
||||
|
||||
addGroupedCommands(command, "Working With Resources:",
|
||||
create.NewCommand(),
|
||||
deletepkg.NewCommand(),
|
||||
@@ -51,12 +56,20 @@ func NewRootCmd() *cobra.Command {
|
||||
vnc.NewCommand(),
|
||||
)
|
||||
|
||||
addGroupedCommands(command, "Administrative Tasks:",
|
||||
administrativeCommands := []*cobra.Command{
|
||||
context.NewCommand(),
|
||||
controller.NewCommand(),
|
||||
worker.NewCommand(),
|
||||
dev.NewCommand(),
|
||||
)
|
||||
}
|
||||
|
||||
if devCommand := dev.NewCommand(); devCommand != nil {
|
||||
administrativeCommands = append(administrativeCommands, devCommand)
|
||||
}
|
||||
|
||||
if workerCommand := worker.NewCommand(); workerCommand != nil {
|
||||
administrativeCommands = append(administrativeCommands, workerCommand)
|
||||
}
|
||||
|
||||
addGroupedCommands(command, "Administrative Tasks:", administrativeCommands...)
|
||||
|
||||
return command
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user