Skip to content

Commit

Permalink
support unsharing PIDNS (--pidns)
Browse files Browse the repository at this point in the history
Fix #65

Signed-off-by: Akihiro Suda <[email protected]>
  • Loading branch information
AkihiroSuda committed May 29, 2019
1 parent ba908f9 commit 7d8230f
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 2 deletions.
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ RootlessKit is a kind of Linux-native "fake root" utility, made for mainly runni
- [Usage](#usage)
- [State directory](#state-directory)
- [Environment variables](#environment-variables)
- [PID Namespace](#pid-namespace)
- [Network Drivers](#network-drivers)
- [`--net=host` (default)](#--nethost-default)
- [`--net=slirp4netns` (recommended)](#--netslirp4netns-recommended)
Expand Down Expand Up @@ -135,15 +136,14 @@ allow
Full CLI options:

```console

NAME:
rootlesskit - the gate to the rootless world

USAGE:
rootlesskit [global options] command [command options] [arguments...]

VERSION:
0.3.0+dev
0.4.1+dev

COMMANDS:
help, h Shows a list of commands or help for one command
Expand All @@ -162,6 +162,7 @@ GLOBAL OPTIONS:
--copy-up value mount a filesystem and copy-up the contents. e.g. "--copy-up=/etc" (typically required for non-host network)
--copy-up-mode value copy-up mode [tmpfs+symlink] (default: "tmpfs+symlink")
--port-driver value port driver for non-host network. [none, socat, slirp4netns, builtin(experimental)] (default: "none")
--pidns create a PID namespace
--help, -h show help
--version, -v print the version
```
Expand All @@ -184,6 +185,14 @@ The following environment variables will be set for the child process:

Undocumented environment variables are subject to change.

## PID Namespace

When `--pidns` (since v0.5.0) is specified, RootlessKit executes the child process in a new PID namespace.
The RootlessKit child process becomes the init (PID=1).
When RootlessKit terminates, all the processes in the namespace are killed with `SIGKILL`.

See also [`pid_namespaces(7)`](http://man7.org/linux/man-pages/man7/pid_namespaces.7.html).

## Network Drivers

RootlessKit provides several drivers for providing network connectivity:
Expand Down
6 changes: 6 additions & 0 deletions cmd/rootlesskit/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ func main() {
Usage: "port driver for non-host network. [none, socat, slirp4netns, builtin(experimental)]",
Value: "none",
},
cli.BoolFlag{
Name: "pidns",
Usage: "create a PID namespace",
},
}
app.Before = func(context *cli.Context) error {
if debug {
Expand Down Expand Up @@ -163,6 +167,7 @@ func createParentOpt(clicontext *cli.Context, pipeFDEnvKey, stateDirEnvKey strin
opt := parent.Opt{
PipeFDEnvKey: pipeFDEnvKey,
StateDirEnvKey: stateDirEnvKey,
CreatePIDNS: clicontext.Bool("pidns"),
}
opt.StateDir = clicontext.String("state-dir")
if opt.StateDir == "" {
Expand Down Expand Up @@ -298,6 +303,7 @@ func createChildOpt(clicontext *cli.Context, pipeFDEnvKey string, targetCmd []st
opt := child.Opt{
PipeFDEnvKey: pipeFDEnvKey,
TargetCmd: targetCmd,
MountProcfs: clicontext.Bool("pidns"),
}
switch s := clicontext.String("net"); s {
case "host":
Expand Down
19 changes: 19 additions & 0 deletions pkg/child/child.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,19 @@ func mountSysfs() error {
return nil
}

func mountProcfs() error {
cmds := [][]string{{"mount", "-t", "proc", "none", "/proc"}}
if err := common.Execs(os.Stderr, os.Environ(), cmds); err != nil {
cmdsRo := [][]string{{"mount", "-t", "proc", "-o", "ro", "none", "/proc"}}
logrus.Warnf("failed to mount procfs (%v), falling back to read-only mount (%v): %v",
cmds, cmdsRo, err)
if err := common.Execs(os.Stderr, os.Environ(), cmdsRo); err != nil {
logrus.Warnf("failed to mount procfs (%v): %v", cmdsRo, err)
}
}
return nil
}

func activateLoopback() error {
cmds := [][]string{
{"ip", "link", "set", "lo", "up"},
Expand Down Expand Up @@ -157,6 +170,7 @@ type Opt struct {
CopyUpDriver copyup.ChildDriver // cannot be nil if len(CopyUpDirs) != 0
CopyUpDirs []string
PortDriver port.ChildDriver
MountProcfs bool // needs to be set if (and only if) parent.Opt.CreatePIDNS is set
}

func Child(opt Opt) error {
Expand Down Expand Up @@ -211,6 +225,11 @@ func Child(opt Opt) error {
if err := setupNet(msg, etcWasCopied, opt.NetworkDriver); err != nil {
return err
}
if opt.MountProcfs {
if err := mountProcfs(); err != nil {
return err
}
}
portQuitCh := make(chan struct{})
portErrCh := make(chan error)
if opt.PortDriver != nil {
Expand Down
5 changes: 5 additions & 0 deletions pkg/parent/parent.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type Opt struct {
StateDirEnvKey string // optional env key to propagate StateDir value
NetworkDriver network.ParentDriver // nil for HostNetwork
PortDriver port.ParentDriver // nil for --port-driver=none
CreatePIDNS bool
}

// Documented state files. Undocumented ones are subject to change.
Expand Down Expand Up @@ -85,6 +86,10 @@ func Parent(opt Opt) error {
if opt.NetworkDriver != nil {
cmd.SysProcAttr.Unshareflags |= syscall.CLONE_NEWNET
}
if opt.CreatePIDNS {
// cannot be Unshareflags (panics)
cmd.SysProcAttr.Cloneflags |= syscall.CLONE_NEWPID
}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
Expand Down

0 comments on commit 7d8230f

Please sign in to comment.