Add setuid & setgid options

Only applicable on unix systems, although Go doesn't support Linux at
this time.
This commit is contained in:
Cameron Moore 2019-12-25 23:23:35 -06:00
parent 35d1cedc24
commit 77159d9db6
4 changed files with 58 additions and 4 deletions

View file

@ -25,6 +25,10 @@ Usage of webhook:
port the webhook should serve hooks on (default 9000) port the webhook should serve hooks on (default 9000)
-secure -secure
use HTTPS instead of HTTP use HTTPS instead of HTTP
-setgid int
set group ID after opening listening port; must be used with setuid
-setuid int
set user ID after opening listening port; must be used with setgid
-template -template
parse hooks file as a Go template parse hooks file as a Go template
-tls-min-version string -tls-min-version string

12
droppriv_nope.go Normal file
View file

@ -0,0 +1,12 @@
// +build linux windows
package main
import (
"errors"
"runtime"
)
func dropPrivileges(uid, gid int) error {
return errors.New("setuid and setgid not supported on " + runtime.GOOS)
}

21
droppriv_unix.go Normal file
View file

@ -0,0 +1,21 @@
// +build !windows,!linux
package main
import (
"syscall"
)
func dropPrivileges(uid, gid int) error {
err := syscall.Setgid(gid)
if err != nil {
return err
}
err = syscall.Setuid(uid)
if err != nil {
return err
}
return nil
}

View file

@ -48,6 +48,8 @@ var (
useXRequestID = flag.Bool("x-request-id", false, "use X-Request-Id header, if present, as request ID") 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") 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") 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")
responseHeaders hook.ResponseHeaders responseHeaders hook.ResponseHeaders
hooksFiles hook.HooksFiles hooksFiles hook.HooksFiles
@ -96,6 +98,11 @@ func main() {
os.Exit(0) os.Exit(0)
} }
if (*setUID != 0 || *setGID != 0) && (*setUID == 0 || *setGID == 0) {
fmt.Println("Error: setuid and setgid options must be used together")
os.Exit(1)
}
if *debug { if *debug {
*verbose = true *verbose = true
} }
@ -198,22 +205,32 @@ func main() {
r.HandleFunc(hooksURL, hookHandler) r.HandleFunc(hooksURL, hookHandler)
addr := fmt.Sprintf("%s:%d", *ip, *port)
// Create common HTTP server settings // Create common HTTP server settings
svr := &http.Server{ svr := &http.Server{
Addr: fmt.Sprintf("%s:%d", *ip, *port), Addr: addr,
Handler: r, Handler: r,
} }
// Open listener // Open listener
ln, err := net.Listen("tcp", fmt.Sprintf("%s:%d", *ip, *port)) ln, err := net.Listen("tcp", addr)
if err != nil { if err != nil {
log.Printf("error listening on port: %s", err) log.Printf("error listening on port: %s", err)
return return
} }
if *setUID != 0 {
err := dropPrivileges(*setUID, *setGID)
if err != nil {
log.Printf("error dropping privileges: %s", err)
return
}
}
// Serve HTTP // Serve HTTP
if !*secure { if !*secure {
log.Printf("serving hooks on http://%s:%d%s", *ip, *port, hooksURL) log.Printf("serving hooks on http://%s%s", addr, hooksURL)
log.Print(svr.Serve(ln)) log.Print(svr.Serve(ln))
return return
} }
@ -227,7 +244,7 @@ func main() {
} }
svr.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler)) // disable http/2 svr.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler)) // disable http/2
log.Printf("serving hooks on https://%s:%d%s", *ip, *port, hooksURL) log.Printf("serving hooks on https://%s%s", addr, hooksURL)
log.Print(svr.ServeTLS(ln, *cert, *key)) log.Print(svr.ServeTLS(ln, *cert, *key))
} }