Move TLS check into HandleRuntimeOverlay

Signed-off-by: Jonathon Anderson <janderson@ciq.com>
This commit is contained in:
Jonathon Anderson
2026-03-03 17:38:14 -07:00
parent 91723a258a
commit 6ce3d33f50
3 changed files with 97 additions and 19 deletions

View File

@@ -17,8 +17,9 @@ import (
"github.com/warewulf/warewulf/internal/pkg/wwlog" "github.com/warewulf/warewulf/internal/pkg/wwlog"
) )
// HandleOverlay handles system and runtime overlay requests // HandleOverlayList handles requests for an explicit comma-separated list of
func HandleOverlay(w http.ResponseWriter, req *http.Request) { // named overlays via the ?overlay= query parameter.
func HandleOverlayList(w http.ResponseWriter, req *http.Request) {
ctx, err := initHandleRequest(w, req) ctx, err := initHandleRequest(w, req)
if err != nil { if err != nil {
return // response already written return // response already written
@@ -30,19 +31,96 @@ func HandleOverlay(w http.ResponseWriter, req *http.Request) {
return return
} }
var context string request_overlays := strings.Split(ctx.rinfo.overlay, ",")
var request_overlays []string stageFile, err := getOverlayFile(
ctx.remoteNode,
"",
request_overlays,
ctx.conf.Warewulf.AutobuildOverlays())
if len(ctx.rinfo.overlay) > 0 { if err != nil {
request_overlays = strings.Split(ctx.rinfo.overlay, ",") if errors.Is(err, overlay.ErrDoesNotExist) {
} else { w.WriteHeader(http.StatusNotFound)
context = ctx.rinfo.stage wwlog.ErrorExc(err, "")
return
}
w.WriteHeader(http.StatusInternalServerError)
wwlog.ErrorExc(err, "")
return
}
sendResponse(w, req, stageFile, nil, ctx)
}
// HandleSystemOverlay handles system overlay requests.
// If an explicit ?overlay= list is present, delegates to HandleOverlayList.
func HandleSystemOverlay(w http.ResponseWriter, req *http.Request) {
if len(req.URL.Query()["overlay"]) > 0 {
HandleOverlayList(w, req)
return
}
ctx, err := initHandleRequest(w, req)
if err != nil {
return // response already written
}
if !ctx.remoteNode.Valid() {
wwlog.Error("%s (unknown/unconfigured node)", ctx.rinfo.hwaddr)
sendResponse(w, req, "", nil, ctx)
return
} }
stageFile, err := getOverlayFile( stageFile, err := getOverlayFile(
ctx.remoteNode, ctx.remoteNode,
context, "system",
request_overlays, nil,
ctx.conf.Warewulf.AutobuildOverlays())
if err != nil {
if errors.Is(err, overlay.ErrDoesNotExist) {
w.WriteHeader(http.StatusNotFound)
wwlog.ErrorExc(err, "")
return
}
w.WriteHeader(http.StatusInternalServerError)
wwlog.ErrorExc(err, "")
return
}
sendResponse(w, req, stageFile, nil, ctx)
}
// HandleRuntimeOverlay handles runtime overlay requests.
// If TLS is enabled, returns 403 Forbidden for plain-HTTP requests.
// If an explicit ?overlay= list is present, delegates to HandleOverlayList.
func HandleRuntimeOverlay(w http.ResponseWriter, req *http.Request) {
if config.Get().Warewulf.EnableTLS() && req.TLS == nil {
wwlog.Denied("runtime overlay requested over insecure connection")
w.WriteHeader(http.StatusForbidden)
return
}
if len(req.URL.Query()["overlay"]) > 0 {
HandleOverlayList(w, req)
return
}
ctx, err := initHandleRequest(w, req)
if err != nil {
return // response already written
}
if !ctx.remoteNode.Valid() {
wwlog.Error("%s (unknown/unconfigured node)", ctx.rinfo.hwaddr)
sendResponse(w, req, "", nil, ctx)
return
}
stageFile, err := getOverlayFile(
ctx.remoteNode,
"runtime",
nil,
ctx.conf.Warewulf.AutobuildOverlays()) ctx.conf.Warewulf.AutobuildOverlays())
if err != nil { if err != nil {

View File

@@ -47,8 +47,10 @@ func HandleProvision(w http.ResponseWriter, req *http.Request) {
handler = HandleKernel handler = HandleKernel
case "image": case "image":
handler = HandleImage handler = HandleImage
case "system", "runtime": case "system":
handler = HandleOverlay handler = HandleSystemOverlay
case "runtime":
handler = HandleRuntimeOverlay
case "efiboot": case "efiboot":
handler = HandleEfiBoot handler = HandleEfiBoot
case "shim": case "shim":

View File

@@ -37,7 +37,7 @@ func (h *slashFix) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.mux.ServeHTTP(w, r) h.mux.ServeHTTP(w, r)
} }
func configureRootHandler(apiHandler http.Handler, includeRuntime bool) *slashFix { func configureRootHandler(apiHandler http.Handler) *slashFix {
var wwHandler http.ServeMux var wwHandler http.ServeMux
wwHandler.HandleFunc("/provision/", warewulfd.HandleProvision) wwHandler.HandleFunc("/provision/", warewulfd.HandleProvision)
wwHandler.HandleFunc("/ipxe/", warewulfd.HandleIpxe) wwHandler.HandleFunc("/ipxe/", warewulfd.HandleIpxe)
@@ -45,10 +45,8 @@ func configureRootHandler(apiHandler http.Handler, includeRuntime bool) *slashFi
wwHandler.HandleFunc("/kernel/", warewulfd.HandleKernel) wwHandler.HandleFunc("/kernel/", warewulfd.HandleKernel)
wwHandler.HandleFunc("/image/", warewulfd.HandleImage) wwHandler.HandleFunc("/image/", warewulfd.HandleImage)
wwHandler.HandleFunc("/container/", warewulfd.HandleImage) wwHandler.HandleFunc("/container/", warewulfd.HandleImage)
wwHandler.HandleFunc("/overlay-system/", warewulfd.HandleOverlay) wwHandler.HandleFunc("/overlay-system/", warewulfd.HandleSystemOverlay)
if includeRuntime { wwHandler.HandleFunc("/overlay-runtime/", warewulfd.HandleRuntimeOverlay)
wwHandler.HandleFunc("/overlay-runtime/", warewulfd.HandleOverlay)
}
wwHandler.HandleFunc("/overlay-file/", warewulfd.HandleOverlayFile) wwHandler.HandleFunc("/overlay-file/", warewulfd.HandleOverlayFile)
wwHandler.HandleFunc("/status", warewulfd.HandleStatus) wwHandler.HandleFunc("/status", warewulfd.HandleStatus)
@@ -87,7 +85,7 @@ func RunServer() error {
apiHandler = api.Handler(auth, conf.API.AllowedIPNets()) apiHandler = api.Handler(auth, conf.API.AllowedIPNets())
} }
httpHandler := configureRootHandler(apiHandler, !conf.Warewulf.EnableTLS()) httpHandler := configureRootHandler(apiHandler)
errChan := make(chan error, 2) errChan := make(chan error, 2)
@@ -98,7 +96,7 @@ func RunServer() error {
if !util.IsFile(key) || !util.IsFile(crt) { if !util.IsFile(key) || !util.IsFile(crt) {
return fmt.Errorf("TLS enabled but keys not found in %s, run 'wwctl configure tls --create' to generate keys", path.Join(conf.Paths.Sysconfdir, "warewulf", "tls")) return fmt.Errorf("TLS enabled but keys not found in %s, run 'wwctl configure tls --create' to generate keys", path.Join(conf.Paths.Sysconfdir, "warewulf", "tls"))
} }
httpsHandler := configureRootHandler(apiHandler, true) httpsHandler := configureRootHandler(apiHandler)
go func() { go func() {
wwlog.Info("Starting HTTPS service on port %d", conf.Warewulf.SecurePort) wwlog.Info("Starting HTTPS service on port %d", conf.Warewulf.SecurePort)
if err := http.ListenAndServeTLS(":"+strconv.Itoa(conf.Warewulf.SecurePort), crt, key, httpsHandler); err != nil { if err := http.ListenAndServeTLS(":"+strconv.Itoa(conf.Warewulf.SecurePort), crt, key, httpsHandler); err != nil {