refactor: moved setuid and setgid flags into platform-specific section

The setuid and setgid flags do not work on Windows, so moved them to platform_unix so they are only added to the flag set on compatible platforms.

Also disallow the use of setuid and setgid in combination with -socket, since a setuid webhook process would not be able to clean up a socket that was created while running as root.  If you _need_ to have the socket owned by root but the webhook process running as a normal user, you can achieve the same effect with systemd socket activation.
This commit is contained in:
Ian Roberts 2024-10-25 14:08:59 +01:00
parent 661a96f3e3
commit ee918ac2ae
2 changed files with 10 additions and 5 deletions

View file

@ -12,6 +12,8 @@ import (
func platformFlags() {
flag.StringVar(&socket, "socket", "", "path to a Unix socket (e.g. /tmp/webhook.sock) to use instead of listening on an ip and port; if specified, the ip and port options are ignored")
flag.IntVar(&setGID, "setgid", 0, "set group ID after opening listening port; must be used with setuid, not permitted with -socket")
flag.IntVar(&setUID, "setuid", 0, "set user ID after opening listening port; must be used with setgid, not permitted with -socket")
}
func trySocketListener() (net.Listener, error) {
@ -35,6 +37,9 @@ func trySocketListener() (net.Listener, error) {
}
// if we get to here, we got no sockets from systemd, so check -socket flag
if socket != "" {
if setGID != 0 || setUID != 0 {
return nil, fmt.Errorf("-setuid and -setgid options are not compatible with -socket. If you need to bind a socket as root but run webhook as a different user, consider using systemd activation")
}
addr = fmt.Sprintf("{unix:%s}", socket)
return net.Listen("unix", socket)
}

View file

@ -48,8 +48,6 @@ var (
useXRequestID = flag.Bool("x-request-id", false, "use X-Request-Id header, if present, as request ID")
xRequestIDLimit = flag.Int("x-request-id-limit", 0, "truncate X-Request-Id header to limit; default no limit")
maxMultipartMem = flag.Int64("max-multipart-mem", 1<<20, "maximum memory in bytes for parsing multipart form data before disk caching")
setGID = flag.Int("setgid", 0, "set group ID after opening listening port; must be used with setuid")
setUID = flag.Int("setuid", 0, "set user ID after opening listening port; must be used with setgid")
httpMethods = flag.String("http-methods", "", `set default allowed HTTP methods (ie. "POST"); separate methods with comma`)
pidPath = flag.String("pidfile", "", "create PID file at the given path")
@ -61,6 +59,8 @@ var (
watcher *fsnotify.Watcher
signals chan os.Signal
pidFile *pidfile.PIDFile
setUID = 0
setGID = 0
socket = ""
addr = ""
)
@ -107,7 +107,7 @@ func main() {
os.Exit(0)
}
if (*setUID != 0 || *setGID != 0) && (*setUID == 0 || *setGID == 0) {
if (setUID != 0 || setGID != 0) && (setUID == 0 || setGID == 0) {
fmt.Println("error: setuid and setgid options must be used together")
os.Exit(1)
}
@ -142,8 +142,8 @@ func main() {
}
}
if *setUID != 0 {
err := dropPrivileges(*setUID, *setGID)
if setUID != 0 {
err := dropPrivileges(setUID, setGID)
if err != nil {
logQueue = append(logQueue, fmt.Sprintf("error dropping privileges: %s", err))
// we'll bail out below