You can find the corresponding code in func gokrazy.supervise.
gokrazy’s init process (pid 1) supervises all the binaries the user specified via gokr-packer
flags.
More specifically, gokrazy:
os/exec.Command
API.
stdout
and stderr
file descriptors are hooked up to a ring buffer and can be viewed via gokrazy’s web interface.0
(or 125
), gokrazy will stop
supervision. Exiting immediately with status code 0
when the
GOKRAZY_FIRST_START=1
environment variable is set means “don’t start the
program on boot”gokrazy sets the HOME
environment variable to HOME=/perm/home/<cmd>
, where
<cmd>
is the name of your binary. For example, tailscale.com/cmd/tailscaled
is started with HOME=/perm/home/tailscaled
.
When your binary is first started, gokrazy sets the GOKRAZY_FIRST_START=1
environment variable.
An easy way to implement privilege dropping in Go is to re-execute the process
with syscall.SysProcAttr fields
set. For example, this is how you would drop privileges to user nobody
(uid/gid 65534):
// mustDropPrivileges re-executes the program in a child process,
// dropping root privileges to user nobody.
func mustDropPrivileges() {
if os.Getenv("NTP_PRIVILEGES_DROPPED") == "1" {
return
}
cmd := exec.Command(os.Args[0])
cmd.Env = append(os.Environ(), "NTP_PRIVILEGES_DROPPED=1")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.SysProcAttr = &syscall.SysProcAttr{
Credential: &syscall.Credential{
Uid: 65534,
Gid: 65534,
},
}
log.Fatal(cmd.Run())
}
Examples:
github.com/gokrazy/gokrazy/cmd/ntp
is a rather involved example which retains the CAP_SYS_TIME capability in the
child processgithub.com/gokrazy/rsync
uses Linux
mount namespaces and constructs a file system with read-only bind mounts of
the configured rsync modules