diff --git a/cmd/rootlesskit/main.go b/cmd/rootlesskit/main.go index e508101e..f63f8c3f 100644 --- a/cmd/rootlesskit/main.go +++ b/cmd/rootlesskit/main.go @@ -21,6 +21,7 @@ import ( "github.com/rootless-containers/rootlesskit/v2/pkg/network/pasta" "github.com/rootless-containers/rootlesskit/v2/pkg/network/slirp4netns" "github.com/rootless-containers/rootlesskit/v2/pkg/network/vpnkit" + "github.com/rootless-containers/rootlesskit/v2/pkg/network/none" "github.com/rootless-containers/rootlesskit/v2/pkg/parent" "github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin" "github.com/rootless-containers/rootlesskit/v2/pkg/port/portutil" @@ -83,7 +84,7 @@ See https://rootlesscontaine.rs/getting-started/common/ . }, CategoryState), Categorize(&cli.StringFlag{ Name: "net", - Usage: "network driver [host, pasta(experimental), slirp4netns, vpnkit, lxc-user-nic(experimental)]", + Usage: "network driver [host, none, pasta(experimental), slirp4netns, vpnkit, lxc-user-nic(experimental)]", Value: "host", }, CategoryNetwork), Categorize(&cli.StringFlag{ @@ -368,7 +369,7 @@ func createParentOpt(clicontext *cli.Context, pipeFDEnvKey, stateDirEnvKey, pare } disableHostLoopback := clicontext.Bool("disable-host-loopback") - if !disableHostLoopback && clicontext.String("net") != "host" { + if !disableHostLoopback && clicontext.String("net") != "host" && clicontext.String("net") != "none" { logrus.Warn("specifying --disable-host-loopback is highly recommended to prohibit connecting to 127.0.0.1:* on the host namespace (requires pasta, slirp4netns, or VPNKit)") } @@ -388,6 +389,26 @@ func createParentOpt(clicontext *cli.Context, pipeFDEnvKey, stateDirEnvKey, pare if ifname != "" { return opt, errors.New("ifname cannot be specified for --net=host") } + case "none": + if mtu != 0 { + logrus.Warnf("unsupported mtu for --net=none: %d", mtu) + } + if ipnet != nil { + return opt, errors.New("custom cidr is not supported for --net=none") + } + if ifname != "" { + return opt, errors.New("ifname cannot be specified for --net=none") + } + switch portDriver := clicontext.String("port-driver"); portDriver { + case "none", "builtin": + // NOP + default: + return opt, errors.New("network \"none\" requires either port driver \"none\" or \"builtin\"") + } + opt.NetworkDriver, err = none.NewParentDriver() + if err != nil { + return opt, err + } case "pasta": logrus.Warn("\"pasta\" network driver is experimental. Needs very recent version of pasta (see docs/network.md).") binary := clicontext.String("pasta-binary") @@ -582,6 +603,8 @@ func createChildOpt(clicontext *cli.Context, pipeFDEnvKey, stateDirEnvKey string switch s := clicontext.String("net"); s { case "host": // NOP + case "none": + // NOP case "pasta": opt.NetworkDriver = pasta.NewChildDriver() case "slirp4netns": diff --git a/pkg/network/none/none.go b/pkg/network/none/none.go new file mode 100644 index 00000000..844fa146 --- /dev/null +++ b/pkg/network/none/none.go @@ -0,0 +1,60 @@ +package none + +import ( + "context" + "os" + "os/exec" + "strconv" + "syscall" + + "github.com/rootless-containers/rootlesskit/v2/pkg/api" + "github.com/rootless-containers/rootlesskit/v2/pkg/common" + "github.com/rootless-containers/rootlesskit/v2/pkg/messages" + "github.com/rootless-containers/rootlesskit/v2/pkg/network" +) + +func NewParentDriver() (network.ParentDriver, error) { + return &parentDriver{}, nil +} + +type parentDriver struct { +} + +const DriverName = "none" + +func (d *parentDriver) MTU() int { + return 0 +} + +func (d *parentDriver) Info(ctx context.Context) (*api.NetworkDriverInfo, error) { + return &api.NetworkDriverInfo{ + Driver: DriverName, + }, nil +} + +func (d *parentDriver) ConfigureNetwork(childPID int, stateDir, detachedNetNSPath string) (*messages.ParentInitNetworkDriverCompleted, func() error, error) { + var cleanups []func() error + + if detachedNetNSPath != "" { + cmd := exec.Command("nsenter", "-t", strconv.Itoa(childPID), "-n"+detachedNetNSPath, "-m", "-U", "--no-fork", "--preserve-credentials", "sleep", "infinity") + cmd.SysProcAttr = &syscall.SysProcAttr{ + Pdeathsig: syscall.SIGKILL, + } + err := cmd.Start() + if err != nil { + return nil, nil, err + } + childPID = cmd.Process.Pid + } + + cmds := [][]string{ + []string{"nsenter", "-t", strconv.Itoa(childPID), "-n", "-m", "-U", "--no-fork", "--preserve-credentials", "ip", "address", "add", "127.0.0.1/8", "dev", "lo"}, + []string{"nsenter", "-t", strconv.Itoa(childPID), "-n", "-m", "-U", "--no-fork", "--preserve-credentials", "ip", "link", "set", "lo", "up"}, + } + if err := common.Execs(os.Stderr, os.Environ(), cmds); err != nil { + return nil, nil, err + } + + netmsg := messages.ParentInitNetworkDriverCompleted{} + return &netmsg, common.Seq(cleanups), nil +}