mirror of
https://github.com/adnanh/webhook.git
synced 2025-05-15 10:04:44 +00:00
Merge pull request #379 from moorereason/feature/drop-privs
Add setuid and setgid options for dropping privileges
This commit is contained in:
commit
66562fdb41
4 changed files with 83 additions and 15 deletions
|
@ -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
12
droppriv_nope.go
Normal 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
21
droppriv_unix.go
Normal 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
|
||||||
|
}
|
55
webhook.go
55
webhook.go
|
@ -8,6 +8,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
@ -47,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
|
||||||
|
@ -95,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
|
||||||
}
|
}
|
||||||
|
@ -168,7 +176,8 @@ func main() {
|
||||||
|
|
||||||
err = watcher.Add(hooksFilePath)
|
err = watcher.Add(hooksFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("error adding hooks file to the watcher\n", err)
|
log.Print("error adding hooks file to the watcher\n", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,25 +205,47 @@ func main() {
|
||||||
|
|
||||||
r.HandleFunc(hooksURL, hookHandler)
|
r.HandleFunc(hooksURL, hookHandler)
|
||||||
|
|
||||||
if !*secure {
|
addr := fmt.Sprintf("%s:%d", *ip, *port)
|
||||||
log.Printf("serving hooks on http://%s:%d%s", *ip, *port, hooksURL)
|
|
||||||
log.Fatal(http.ListenAndServe(fmt.Sprintf("%s:%d", *ip, *port), r))
|
// Create common HTTP server settings
|
||||||
|
svr := &http.Server{
|
||||||
|
Addr: addr,
|
||||||
|
Handler: r,
|
||||||
}
|
}
|
||||||
|
|
||||||
svr := &http.Server{
|
// Open listener
|
||||||
Addr: fmt.Sprintf("%s:%d", *ip, *port),
|
ln, err := net.Listen("tcp", addr)
|
||||||
Handler: r,
|
if err != nil {
|
||||||
TLSConfig: &tls.Config{
|
log.Printf("error listening on port: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if *setUID != 0 {
|
||||||
|
err := dropPrivileges(*setUID, *setGID)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error dropping privileges: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serve HTTP
|
||||||
|
if !*secure {
|
||||||
|
log.Printf("serving hooks on http://%s%s", addr, hooksURL)
|
||||||
|
log.Print(svr.Serve(ln))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Server HTTPS
|
||||||
|
svr.TLSConfig = &tls.Config{
|
||||||
CipherSuites: getTLSCipherSuites(*tlsCipherSuites),
|
CipherSuites: getTLSCipherSuites(*tlsCipherSuites),
|
||||||
CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
|
CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
|
||||||
MinVersion: getTLSMinVersion(*tlsMinVersion),
|
MinVersion: getTLSMinVersion(*tlsMinVersion),
|
||||||
PreferServerCipherSuites: true,
|
PreferServerCipherSuites: true,
|
||||||
},
|
|
||||||
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.Fatal(svr.ListenAndServeTLS(*cert, *key))
|
log.Print(svr.ServeTLS(ln, *cert, *key))
|
||||||
}
|
}
|
||||||
|
|
||||||
func hookHandler(w http.ResponseWriter, r *http.Request) {
|
func hookHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue