Simplify and clarify configuration
- changed "secure port" to "tls port" - removed the --create flag for "wwctl configure tls"; made it the default behavior - fixed a TLS creation bug in "wwctl configure --all" - added logging to "wwctl configure tls" and "wwctl configure --all" (for the tls case) Signed-off-by: Jonathon Anderson <janderson@ciq.com>
This commit is contained in:
@@ -61,7 +61,7 @@ if [ "${WWTLS}" = "true" ] && [ -f "$cert_file" ]; then
|
|||||||
# TLS enabled: build HTTPS URI using wwid from kernel cmdline
|
# TLS enabled: build HTTPS URI using wwid from kernel cmdline
|
||||||
# (mirrors wwclient URL construction in internal/app/wwclient/root.go)
|
# (mirrors wwclient URL construction in internal/app/wwclient/root.go)
|
||||||
wwid=$(getarg wwid)
|
wwid=$(getarg wwid)
|
||||||
runtime_uri="https://${WWIPADDR}:${WWSECUREPORT}/provision/${wwid}"
|
runtime_uri="https://${WWIPADDR}:${WWTLSPORT}/provision/${wwid}"
|
||||||
get_stage "runtime" "${runtime_uri}" "${cert_file}" || warn "warewulf: unable to load runtime overlay over HTTPS (ignored)"
|
get_stage "runtime" "${runtime_uri}" "${cert_file}" || warn "warewulf: unable to load runtime overlay over HTTPS (ignored)"
|
||||||
else
|
else
|
||||||
# No TLS: fetch runtime over HTTP
|
# No TLS: fetch runtime over HTTP
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ nodeprofiles:
|
|||||||
system overlay:
|
system overlay:
|
||||||
- wwinit
|
- wwinit
|
||||||
- wwclient
|
- wwclient
|
||||||
|
- hosts
|
||||||
- fstab
|
- fstab
|
||||||
- hostname
|
- hostname
|
||||||
- ssh.host_keys
|
- ssh.host_keys
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) {
|
|||||||
port := conf.Warewulf.Port
|
port := conf.Warewulf.Port
|
||||||
scheme := "http"
|
scheme := "http"
|
||||||
if conf.Warewulf.EnableTLS() {
|
if conf.Warewulf.EnableTLS() {
|
||||||
port = conf.Warewulf.SecurePort
|
port = conf.Warewulf.TlsPort
|
||||||
scheme = "https"
|
scheme = "https"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
package configure
|
package configure
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
|
warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
|
||||||
"github.com/warewulf/warewulf/internal/pkg/configure"
|
"github.com/warewulf/warewulf/internal/pkg/configure"
|
||||||
"github.com/warewulf/warewulf/internal/pkg/util"
|
|
||||||
"github.com/warewulf/warewulf/internal/pkg/wwlog"
|
"github.com/warewulf/warewulf/internal/pkg/wwlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -23,17 +20,8 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if allFunctions {
|
if allFunctions {
|
||||||
keystore := path.Join(conf.Paths.Sysconfdir, "warewulf", "tls")
|
if _, err = configure.TLS(false); err != nil {
|
||||||
keyFile := path.Join(keystore, "warewulf.key")
|
return err
|
||||||
certFile := path.Join(keystore, "warewulf.crt")
|
|
||||||
|
|
||||||
if !util.IsFile(keyFile) || !util.IsFile(certFile) {
|
|
||||||
err = configure.GenTLSKeys()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Printf("Keys already exist in %s\n", keystore)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = configure.WAREWULFD()
|
err = configure.WAREWULFD()
|
||||||
|
|||||||
@@ -19,10 +19,6 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
|||||||
conf := config.Get()
|
conf := config.Get()
|
||||||
keystore := path.Join(conf.Paths.Sysconfdir, "warewulf", "tls")
|
keystore := path.Join(conf.Paths.Sysconfdir, "warewulf", "tls")
|
||||||
|
|
||||||
if err := os.MkdirAll(keystore, 0755); err != nil {
|
|
||||||
return fmt.Errorf("could not create keystore directory: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
keyFile := path.Join(keystore, "warewulf.key")
|
keyFile := path.Join(keystore, "warewulf.key")
|
||||||
certFile := path.Join(keystore, "warewulf.crt")
|
certFile := path.Join(keystore, "warewulf.crt")
|
||||||
|
|
||||||
@@ -75,21 +71,21 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if util.IsFile(keyFile) && util.IsFile(certFile) && !force {
|
if !conf.Warewulf.EnableTLS() {
|
||||||
if create {
|
fmt.Fprintf(cmd.OutOrStdout(), "TLS is not enabled in warewulf.conf\n")
|
||||||
fmt.Fprintf(cmd.OutOrStdout(), "Keys already exist in %s\n", keystore)
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
created, err := configure.TLS(force)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if created {
|
||||||
|
if err := configure.WAREWULFD(); err != nil {
|
||||||
|
return fmt.Errorf("failed to restart warewulfd: %w", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if create {
|
fmt.Fprintf(cmd.OutOrStdout(), "Keys already exist in %s\n", keystore)
|
||||||
if err := configure.GenTLSKeys(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := configure.WAREWULFD(); err != nil {
|
|
||||||
return fmt.Errorf("failed to restart warewulfd: %w", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("keys not found in: %s", keystore)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
w := tabwriter.NewWriter(cmd.OutOrStdout(), 0, 0, 2, ' ', 0)
|
w := tabwriter.NewWriter(cmd.OutOrStdout(), 0, 0, 2, ' ', 0)
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ func Test_Keys(t *testing.T) {
|
|||||||
env := testenv.New(t)
|
env := testenv.New(t)
|
||||||
defer env.RemoveAll()
|
defer env.RemoveAll()
|
||||||
|
|
||||||
|
// Enable TLS in the test config
|
||||||
|
env.WriteFile("etc/warewulf/warewulf.conf", "warewulf:\n tls: true\n")
|
||||||
|
|
||||||
// Define a keystore path within the test environment
|
// Define a keystore path within the test environment
|
||||||
keystoreRelPath := "etc/warewulf/tls"
|
keystoreRelPath := "etc/warewulf/tls"
|
||||||
keystorePath := env.GetPath(keystoreRelPath)
|
keystorePath := env.GetPath(keystoreRelPath)
|
||||||
@@ -24,11 +27,10 @@ func Test_Keys(t *testing.T) {
|
|||||||
t.Run("keys create", func(t *testing.T) {
|
t.Run("keys create", func(t *testing.T) {
|
||||||
baseCmd := GetCommand()
|
baseCmd := GetCommand()
|
||||||
// Reset flags
|
// Reset flags
|
||||||
create = true
|
|
||||||
importPath = ""
|
importPath = ""
|
||||||
exportPath = ""
|
exportPath = ""
|
||||||
|
|
||||||
baseCmd.SetArgs([]string{"--create"})
|
baseCmd.SetArgs([]string{})
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
baseCmd.SetOut(buf)
|
baseCmd.SetOut(buf)
|
||||||
baseCmd.SetErr(buf)
|
baseCmd.SetErr(buf)
|
||||||
@@ -43,11 +45,10 @@ func Test_Keys(t *testing.T) {
|
|||||||
t.Run("keys exist check", func(t *testing.T) {
|
t.Run("keys exist check", func(t *testing.T) {
|
||||||
baseCmd := GetCommand()
|
baseCmd := GetCommand()
|
||||||
// Reset flags
|
// Reset flags
|
||||||
create = true // Even with create, it should say they exist
|
|
||||||
importPath = ""
|
importPath = ""
|
||||||
exportPath = ""
|
exportPath = ""
|
||||||
|
|
||||||
baseCmd.SetArgs([]string{"--create"})
|
baseCmd.SetArgs([]string{})
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
baseCmd.SetOut(buf)
|
baseCmd.SetOut(buf)
|
||||||
baseCmd.SetErr(buf)
|
baseCmd.SetErr(buf)
|
||||||
@@ -61,7 +62,6 @@ func Test_Keys(t *testing.T) {
|
|||||||
t.Run("keys display", func(t *testing.T) {
|
t.Run("keys display", func(t *testing.T) {
|
||||||
baseCmd := GetCommand()
|
baseCmd := GetCommand()
|
||||||
// Reset flags
|
// Reset flags
|
||||||
create = false
|
|
||||||
importPath = ""
|
importPath = ""
|
||||||
exportPath = ""
|
exportPath = ""
|
||||||
|
|
||||||
@@ -88,7 +88,6 @@ func Test_Keys(t *testing.T) {
|
|||||||
|
|
||||||
baseCmd := GetCommand()
|
baseCmd := GetCommand()
|
||||||
// Reset flags
|
// Reset flags
|
||||||
create = false
|
|
||||||
importPath = ""
|
importPath = ""
|
||||||
exportPath = exportFullPath
|
exportPath = exportFullPath
|
||||||
|
|
||||||
|
|||||||
@@ -18,14 +18,12 @@ var (
|
|||||||
}
|
}
|
||||||
importPath string
|
importPath string
|
||||||
exportPath string
|
exportPath string
|
||||||
create bool
|
|
||||||
force bool
|
force bool
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
baseCmd.PersistentFlags().StringVar(&importPath, "import", "", "Import keys from directory")
|
baseCmd.PersistentFlags().StringVar(&importPath, "import", "", "Import keys from directory")
|
||||||
baseCmd.PersistentFlags().StringVar(&exportPath, "export", "", "Export keys to directory")
|
baseCmd.PersistentFlags().StringVar(&exportPath, "export", "", "Export keys to directory")
|
||||||
baseCmd.PersistentFlags().BoolVar(&create, "create", false, "Create keys if they do not exist")
|
|
||||||
baseCmd.PersistentFlags().BoolVarP(&force, "force", "f", false, "Enforce creation of keys even if they exist")
|
baseCmd.PersistentFlags().BoolVarP(&force, "force", "f", false, "Enforce creation of keys even if they exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ func (conf TFTPConf) Enabled() bool {
|
|||||||
// BaseConf.
|
// BaseConf.
|
||||||
type WarewulfConf struct {
|
type WarewulfConf struct {
|
||||||
Port int `yaml:"port,omitempty" default:"9873"`
|
Port int `yaml:"port,omitempty" default:"9873"`
|
||||||
SecurePort int `yaml:"secure port,omitempty" default:"9874"`
|
TlsPort int `yaml:"tls port,omitempty" default:"9874"`
|
||||||
SecureP *bool `yaml:"secure,omitempty" default:"true"`
|
SecureP *bool `yaml:"secure,omitempty" default:"true"`
|
||||||
EnableTLSP *bool `yaml:"tls,omitempty" default:"false"`
|
EnableTLSP *bool `yaml:"tls,omitempty" default:"false"`
|
||||||
UpdateInterval int `yaml:"update interval,omitempty" default:"60"`
|
UpdateInterval int `yaml:"update interval,omitempty" default:"60"`
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ warewulf:
|
|||||||
host overlay: true
|
host overlay: true
|
||||||
port: 9873
|
port: 9873
|
||||||
secure: true
|
secure: true
|
||||||
secure port: 9874
|
tls port: 9874
|
||||||
update interval: 60
|
update interval: 60
|
||||||
nfs:
|
nfs:
|
||||||
enabled: true
|
enabled: true
|
||||||
@@ -70,7 +70,7 @@ warewulf:
|
|||||||
host overlay: true
|
host overlay: true
|
||||||
port: 9873
|
port: 9873
|
||||||
secure: true
|
secure: true
|
||||||
secure port: 9874
|
tls port: 9874
|
||||||
update interval: 60
|
update interval: 60
|
||||||
nfs:
|
nfs:
|
||||||
enabled: true
|
enabled: true
|
||||||
@@ -120,7 +120,7 @@ warewulf:
|
|||||||
host overlay: true
|
host overlay: true
|
||||||
port: 9873
|
port: 9873
|
||||||
secure: true
|
secure: true
|
||||||
secure port: 9874
|
tls port: 9874
|
||||||
update interval: 60
|
update interval: 60
|
||||||
nfs:
|
nfs:
|
||||||
enabled: true
|
enabled: true
|
||||||
@@ -167,7 +167,7 @@ warewulf:
|
|||||||
host overlay: true
|
host overlay: true
|
||||||
port: 9873
|
port: 9873
|
||||||
secure: true
|
secure: true
|
||||||
secure port: 9874
|
tls port: 9874
|
||||||
update interval: 60
|
update interval: 60
|
||||||
nfs:
|
nfs:
|
||||||
enabled: true
|
enabled: true
|
||||||
@@ -243,7 +243,7 @@ warewulf:
|
|||||||
host overlay: true
|
host overlay: true
|
||||||
port: 9873
|
port: 9873
|
||||||
secure: false
|
secure: false
|
||||||
secure port: 9874
|
tls port: 9874
|
||||||
update interval: 60
|
update interval: 60
|
||||||
nfs:
|
nfs:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
@@ -14,16 +14,44 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
|
warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
|
||||||
|
"github.com/warewulf/warewulf/internal/pkg/util"
|
||||||
"github.com/warewulf/warewulf/internal/pkg/wwlog"
|
"github.com/warewulf/warewulf/internal/pkg/wwlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
// TLS ensures TLS keys exist if TLS is enabled.
|
||||||
GenTLSKeys checks for existence of x509 keys and creates them if they don't exist.
|
// If force is true, regenerates even if keys already exist.
|
||||||
*/
|
// Returns true if new keys were generated.
|
||||||
|
func TLS(force bool) (bool, error) {
|
||||||
|
conf := warewulfconf.Get()
|
||||||
|
if !conf.Warewulf.EnableTLS() {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
keystore := path.Join(conf.Paths.Sysconfdir, "warewulf", "tls")
|
||||||
|
keyFile := path.Join(keystore, "warewulf.key")
|
||||||
|
certFile := path.Join(keystore, "warewulf.crt")
|
||||||
|
|
||||||
|
if !force && util.IsFile(keyFile) && util.IsFile(certFile) {
|
||||||
|
wwlog.Info("TLS keys already exist in %s", keystore)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := GenTLSKeys(); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
wwlog.Info("TLS keys generated in %s", keystore)
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenTLSKeys generates new TLS keys and certificate unconditionally.
|
||||||
func GenTLSKeys() error {
|
func GenTLSKeys() error {
|
||||||
conf := warewulfconf.Get()
|
conf := warewulfconf.Get()
|
||||||
keystore := path.Join(conf.Paths.Sysconfdir, "warewulf", "tls")
|
keystore := path.Join(conf.Paths.Sysconfdir, "warewulf", "tls")
|
||||||
|
|
||||||
|
if err := os.MkdirAll(keystore, 0755); err != nil {
|
||||||
|
return fmt.Errorf("could not create keystore directory: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
keyFile := path.Join(keystore, "warewulf.key")
|
keyFile := path.Join(keystore, "warewulf.key")
|
||||||
certFile := path.Join(keystore, "warewulf.crt")
|
certFile := path.Join(keystore, "warewulf.crt")
|
||||||
wwlog.Verbose("Generating new x509 keys in %s", keystore)
|
wwlog.Verbose("Generating new x509 keys in %s", keystore)
|
||||||
|
|||||||
@@ -94,12 +94,12 @@ func RunServer() error {
|
|||||||
crt := path.Join(conf.Paths.Sysconfdir, "warewulf", "tls", "warewulf.crt")
|
crt := path.Join(conf.Paths.Sysconfdir, "warewulf", "tls", "warewulf.crt")
|
||||||
|
|
||||||
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' to generate keys", path.Join(conf.Paths.Sysconfdir, "warewulf", "tls"))
|
||||||
}
|
}
|
||||||
httpsHandler := configureRootHandler(apiHandler)
|
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.TlsPort)
|
||||||
if err := http.ListenAndServeTLS(":"+strconv.Itoa(conf.Warewulf.SecurePort), crt, key, httpsHandler); err != nil {
|
if err := http.ListenAndServeTLS(":"+strconv.Itoa(conf.Warewulf.TlsPort), crt, key, httpsHandler); err != nil {
|
||||||
errChan <- fmt.Errorf("could not start HTTPS service: %w", err)
|
errChan <- fmt.Errorf("could not start HTTPS service: %w", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ WWIPMI_USER="user"
|
|||||||
WWIPMI_PASSWORD="password"
|
WWIPMI_PASSWORD="password"
|
||||||
WWIPMI_WRITE="true"
|
WWIPMI_WRITE="true"
|
||||||
WWTLS=false
|
WWTLS=false
|
||||||
WWSECUREPORT=9874
|
WWTLSPORT=9874
|
||||||
WWIPADDR=192.168.0.1
|
WWIPADDR=192.168.0.1
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ WWIPMI_WRITE="{{$.Ipmi.Write.Bool}}"
|
|||||||
WWIPMI_VLAN="{{$.Ipmi.Tags.vlan}}"
|
WWIPMI_VLAN="{{$.Ipmi.Tags.vlan}}"
|
||||||
{{- end }}
|
{{- end }}
|
||||||
WWTLS={{$.Warewulf.EnableTLS}}
|
WWTLS={{$.Warewulf.EnableTLS}}
|
||||||
WWSECUREPORT={{$.Warewulf.SecurePort}}
|
WWTLSPORT={{$.Warewulf.TlsPort}}
|
||||||
WWIPADDR={{$.Ipaddr}}
|
WWIPADDR={{$.Ipaddr}}
|
||||||
|
|||||||
Reference in New Issue
Block a user