add https in wwclient and wwinit

This commit is contained in:
Christian Goll
2025-12-03 12:36:41 +01:00
committed by Jonathon Anderson
parent a1c11db8cc
commit 2f88b4c3d5
4 changed files with 57 additions and 5 deletions

View File

@@ -43,7 +43,7 @@ info "warewulf: mounting ${wwinit_root_device} at ${NEWROOT}"
fi
) || die "warewulf: failed to mount ${wwinit_root_device} at ${NEWROOT}"
for stage in "image" "system" "runtime"; do
for stage in "image" "system" ; do
get_stage "${stage}"
done

View File

@@ -66,7 +66,9 @@ menuentry "Single-stage boot" --id single-stage {
echo "Downloading images..."
image="${uri}&stage=image&compress=gz"
system="${uri}&stage=system&compress=gz"
{{- if not (eq .Https true) }}
runtime="${uri}&stage=runtime&compress=gz"
{{- end }}
initrd $image $system $runtime
if [ $? != 0 ]
then
@@ -113,7 +115,9 @@ menuentry "Single-stage boot (no compression)" --id single-stage-nocompress {
echo "Downloading images..."
image="${uri}&stage=image"
system="${uri}&stage=system"
{{- if not (eq .Https true) }}
runtime="${uri}&stage=runtime"
{{- end }}
initrd $image $system $runtime
if [ $? != 0 ]
then

View File

@@ -46,8 +46,10 @@ echo Downloading compressed image with imgextract...
imgextract --name image ${uri}&stage=image&compress=gz || goto error_use_initrd
echo Downloading compressed system overlay image with imgextract...
imgextract --name system ${uri}&stage=system&compress=gz || goto error_reboot
{{- if not (eq .Https true) }}
echo Downloading compressed runtime overlay image with imgextract...
imgextract --name runtime ${uri}&stage=runtime&compress=gz && set runtime_initrd initrd=runtime || echo Unable to download runtime overlay. (ignored)
{{- end }}
goto boot_single_stage
:error_use_initrd
@@ -63,8 +65,10 @@ echo Downloading compressed image with initrd...
initrd --name image ${uri}&stage=image&compress=gz || goto error_reboot
echo Downloading compressed system overlay with initrd...
initrd --name system ${uri}&stage=system&compress=gz || goto error_reboot
{{- if not (eq .Https true) }}
echo Downloading compressed runtime overlay with initrd...
initrd --name runtime ${uri}&stage=runtime&compress=gz && set runtime_initrd initrd=runtime || echo Unable to download runtime overlay. (ignored)
{{- end }}
goto boot_single_stage
:initrd_nocompress
@@ -76,8 +80,10 @@ echo Downloading uncompressed image with initrd...
initrd --name image ${uri}&stage=image || goto error_reboot
echo Downloading uncompressed system overlay with initrd...
initrd --name system ${uri}&stage=system || goto error_reboot
{{- if not (eq .Https true) }}
echo Downloading uncompressed runtime overlay with initrd...
initrd --name runtime ${uri}&stage=runtime && set runtime_initrd initrd=runtime || echo Unable to download runtime overlay. (ignored)
{{- end }}
goto boot_single_stage
:dracut

View File

@@ -1,6 +1,10 @@
package wwclient
import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"io"
"net"
@@ -112,9 +116,31 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) {
wwlog.Info("running from trusted port: %d", localTCPAddr.Port)
}
tlsConfig := &tls.Config{}
if conf.Warewulf.EnableHttps() {
caCert, err := os.ReadFile("/warewulf/keys/warewulf.crt")
if err != nil {
wwlog.Error("failed to read ca cert: %s", err)
return err
}
block, _ := pem.Decode(caCert)
if block == nil {
wwlog.Warn("failed to parse certificate PEM")
} else if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
wwlog.Info("using cert: %s", cert.SerialNumber)
} else {
wwlog.Warn("parsing cert failed: %s", err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
tlsConfig.RootCAs = caCertPool
}
Webclient = &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: tlsConfig,
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
LocalAddr: &localTCPAddr,
Timeout: 30 * time.Second,
@@ -232,8 +258,15 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) {
}
}
port := conf.Warewulf.Port
scheme := "http"
if conf.Warewulf.EnableHttps() {
port = conf.Warewulf.SecurePort
scheme = "https"
}
for {
updateSystem(target, ipaddr, conf.Warewulf.Port, wwid, tag, localUUID)
updateSystem(target, ipaddr, port, wwid, tag, localUUID, scheme)
if !finishedInitialSync {
// Notify systemd that the service has started successfully.
//
@@ -274,7 +307,7 @@ func parseWWIDFromCmdline(cmdline string) (string, error) {
return "", fmt.Errorf("wwid parameter not found in kernel command line")
}
func updateSystem(target string, ipaddr string, port int, wwid string, tag string, localUUID uuid.UUID) {
func updateSystem(target string, ipaddr string, port int, wwid string, tag string, localUUID uuid.UUID, scheme string) {
var resp *http.Response
counter := 0
for {
@@ -285,7 +318,7 @@ func updateSystem(target string, ipaddr string, port int, wwid string, tag strin
values.Set("stage", "runtime")
values.Set("compress", "gz")
getURL := &url.URL{
Scheme: "http",
Scheme: scheme,
Host: fmt.Sprintf("%s:%d", ipaddr, port),
Path: fmt.Sprintf("provision/%s", wwid),
RawQuery: values.Encode(),
@@ -296,6 +329,15 @@ func updateSystem(target string, ipaddr string, port int, wwid string, tag strin
defer resp.Body.Close()
break
} else {
var certificateInvalidError x509.CertificateInvalidError
var unknownAuthorityError x509.UnknownAuthorityError
var hostnameError x509.HostnameError
if errors.As(err, &certificateInvalidError) ||
errors.As(err, &unknownAuthorityError) ||
errors.As(err, &hostnameError) {
wwlog.Error("TLS connection failed: %v", err)
os.Exit(1)
}
if counter > 60 {
counter = 0
}