add custom user for bin mode

This commit is contained in:
Alexander Baryshnikov 2020-12-01 20:16:41 +08:00
parent a418873901
commit fe43e03daf
5 changed files with 55 additions and 2 deletions

View File

@ -6,6 +6,7 @@
Schema:
* `command` (required, string) - command to execute (will be executed in a shell)
* `user` (optional, string) - custom user as process owner (only `bin` mode and only for linux), usually requires root privileges
* `interval` (optional, interval) - interval between attempts
* `timeout` (optional, interval) - maximum execution timeout (enabled only for bin mode and only if positive)
* `graceful_timeout` (optional, interval) - maximum execution timeout after which SIGINT will be sent (enabled only for bin mode and only if positive).

View File

@ -34,6 +34,7 @@ func (m *markerResponse) WriteHeader(statusCode int) {
}
type binHandler struct {
user string
command string
workDir string
shell string
@ -70,8 +71,13 @@ func (bh *binHandler) ServeHTTP(writer http.ResponseWriter, request *http.Reques
cmd.Stdout = marker
cmd.Env = env
internal.SetBinFlags(cmd)
err := bh.run(ctx, cmd)
err := setUser(cmd, bh.user)
if err != nil {
writer.Header().Set("X-Return-Code", strconv.Itoa(cmd.ProcessState.ExitCode()))
writer.WriteHeader(http.StatusInternalServerError)
return
}
err = bh.run(ctx, cmd)
if codeReset, ok := writer.(interface{ Status(status int) }); ok && err != nil {
codeReset.Status(http.StatusBadGateway)

View File

@ -0,0 +1,9 @@
//+build !linux
package server
import "os/exec"
func setUser(cmd *exec.Cmd, user string) error {
return nil
}

35
server/mode_bin_linux.go Normal file
View File

@ -0,0 +1,35 @@
package server
import (
"os/exec"
"os/user"
"strconv"
"syscall"
)
func setUser(cmd *exec.Cmd, userName string) error {
if userName == "" {
return nil
}
info, err := user.Lookup(userName)
if err != nil {
return err
}
uid, err := strconv.Atoi(info.Uid)
if err != nil {
return err
}
gid, err := strconv.Atoi(info.Gid)
if err != nil {
return err
}
if cmd.SysProcAttr == nil {
cmd.SysProcAttr = &syscall.SysProcAttr{}
}
cmd.SysProcAttr.Credential = &syscall.Credential{
Uid: uint32(uid),
Gid: uint32(gid),
}
return nil
}

View File

@ -34,6 +34,7 @@ type Unit struct {
Mode string `yaml:"mode,omitempty"` // execution mode: bin, cgi or proxy
WorkDir string `yaml:"workdir,omitempty"` // working directory for the worker. if empty - temporary one will generated automatically
Command string `yaml:"command"` // command in a shell to execute
User string `yaml:"user,omitempty"` // user name as process owner (only for bin mode)
Timeout time.Duration `yaml:"timeout,omitempty"` // maximum execution timeout (enabled only for bin mode and only if positive)
GracefulTimeout time.Duration `yaml:"graceful_timeout,omitempty"` // maximum execution timeout after which SIGINT will be sent (enabled only for bin mode and only if positive)
Shell string `yaml:"shell,omitempty"` // shell to execute command in bin mode (default - /bin/sh)
@ -258,6 +259,7 @@ func (cfg Unit) createRunner() (http.Handler, error) {
switch cfg.Mode {
case "bin":
return &binHandler{
user: cfg.User,
command: cfg.Command,
workDir: cfg.WorkDir,
shell: cfg.Shell,