Skip to content

Commit

Permalink
Configure the network namespace before executing jailer
Browse files Browse the repository at this point in the history
Right now there is a bug when trying to start a Firecracker VM with
jailer using a CNI where the VM is never joined to the correct network
namespace. This is because in its current form, the CNI execution occurs
when `fcinit.SetupNetwork` runs, which occurs _after_ the jailer has
already created a chroot and dropped privleges.

This fixes the problem by executing the `fcinit.SetupNetwork` call
_before_ running jailer and removing that hook from the `FcInit`
functions later on. It also passes through the UID and GID options to
the `tc-redirect-tap` plugin and includes the `IgnoreUnknown` directive
so that chained CNI plugins work.

Signed-off-by: Dan Norris <[email protected]>
  • Loading branch information
protochron committed Mar 28, 2023
1 parent aa97886 commit 4c36613
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
24 changes: 22 additions & 2 deletions machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,26 @@ func NewMachine(ctx context.Context, cfg Config, opts ...Opt) (*Machine, error)

if cfg.JailerCfg != nil {
m.Handlers.Validation = m.Handlers.Validation.Append(JailerConfigValidationHandler)

if cfg.NetNS == "" && cfg.NetworkInterfaces.cniInterface() != nil {
cfg.NetNS = filepath.Join(defaultNetNSDir, cfg.VMID)

// If the network namespace is set, we need to setup the network prior to running the jailer.
err := cfg.ValidateNetwork()
if err != nil {
return nil, fmt.Errorf("failed to validate network configuration: %w", err)
}
m.Handlers.Validation = m.Handlers.Validation.Remove(ValidateNetworkCfgHandlerName)
m.Handlers.FcInit = m.Handlers.FcInit.Remove(SetupNetworkHandlerName)

jailLog := log.New()
err, cleanupFuncs := cfg.NetworkInterfaces.setupNetwork(ctx, cfg.VMID, cfg.NetNS, log.NewEntry(jailLog), cfg.JailerCfg.UID, cfg.JailerCfg.GID)
m.cleanupFuncs = append(m.cleanupFuncs, cleanupFuncs...)
if err != nil {
return nil, fmt.Errorf("failed to setup network prior to jailing: %w", err)
}
}

if err := jail(ctx, m, &cfg); err != nil {
return nil, err
}
Expand Down Expand Up @@ -492,7 +512,7 @@ func (m *Machine) GetFirecrackerVersion(ctx context.Context) (string, error) {
}

func (m *Machine) setupNetwork(ctx context.Context) error {
err, cleanupFuncs := m.Cfg.NetworkInterfaces.setupNetwork(ctx, m.Cfg.VMID, m.Cfg.NetNS, m.logger)
err, cleanupFuncs := m.Cfg.NetworkInterfaces.setupNetwork(ctx, m.Cfg.VMID, m.Cfg.NetNS, m.logger, nil, nil)
m.cleanupFuncs = append(m.cleanupFuncs, cleanupFuncs...)
return err
}
Expand Down Expand Up @@ -649,7 +669,7 @@ func (m *Machine) startVMM(ctx context.Context) error {
return nil
}

//StopVMM stops the current VMM.
// StopVMM stops the current VMM.
func (m *Machine) StopVMM() error {
return m.stopVMM()
}
Expand Down
18 changes: 18 additions & 0 deletions network.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ func (networkInterfaces NetworkInterfaces) setupNetwork(
vmID string,
netNSPath string,
logger *log.Entry,
uid *int,
gid *int,
) (error, []func() error) {
var cleanupFuncs []func() error

Expand All @@ -111,6 +113,22 @@ func (networkInterfaces NetworkInterfaces) setupNetwork(
cniNetworkInterface.CNIConfiguration.containerID = vmID
cniNetworkInterface.CNIConfiguration.netNSPath = netNSPath
cniNetworkInterface.CNIConfiguration.setDefaults()
if uid != nil && gid != nil {
cniNetworkInterface.CNIConfiguration.Args = [][2]string{
{
"IgnoreUnknown",
"true",
},
{
"TC_REDIRECT_TAP_UID",
fmt.Sprintf("%d", *uid),
},
{
"TC_REDIRECT_TAP_GID",
fmt.Sprintf("%d", *gid),
},
}
}

// Make sure the netns is setup. If the path doesn't yet exist, it will be
// initialized with a new empty netns.
Expand Down

0 comments on commit 4c36613

Please sign in to comment.