Merge pull request #1187 from mslacken/SetSSHKeys

allow the user to specify ssh key types
This commit is contained in:
Christian Goll
2024-05-06 11:12:06 +02:00
committed by GitHub
13 changed files with 98 additions and 20 deletions

View File

@@ -36,6 +36,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## v4.5.2, unreleased
### Added
- Allow specification of the ssh-keys to be to be created. #1185
### Fixed
- Fix nightly release build failure issue. #1195

View File

@@ -38,3 +38,9 @@ container mounts:
- source: /etc/resolv.conf
dest: /etc/resolv.conf
readonly: true
ssh:
key types:
- rsa
- dsa
- ecdsa
- ed25519

View File

@@ -28,7 +28,7 @@ func init() {
baseCmd.AddCommand(nfs.GetCommand())
baseCmd.AddCommand(hostfile.GetCommand())
baseCmd.PersistentFlags().BoolVarP(&allFunctions, "all", "a", false, "Configure all services")
baseCmd.Flags().BoolVarP(&allFunctions, "all", "a", false, "Configure all services")
}
// GetRootCommand returns the root cobra.Command for the application.

View File

@@ -2,9 +2,13 @@ package ssh
import (
"github.com/spf13/cobra"
warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
"github.com/warewulf/warewulf/internal/pkg/configure"
)
func CobraRunE(cmd *cobra.Command, args []string) error {
return configure.SSH()
if len(keyTypes) == 0 {
keyTypes = append(keyTypes, warewulfconf.Get().SSH.KeyTypes...)
}
return configure.SSH(keyTypes...)
}

View File

@@ -1,6 +1,8 @@
package ssh
import "github.com/spf13/cobra"
import (
"github.com/spf13/cobra"
)
var (
baseCmd = &cobra.Command{
@@ -12,6 +14,7 @@ var (
"keys.",
RunE: CobraRunE,
}
keyTypes []string
)
func init() {
@@ -19,5 +22,6 @@ func init() {
// GetRootCommand returns the root cobra.Command for the application.
func GetCommand() *cobra.Command {
baseCmd.PersistentFlags().StringArrayVarP(&keyTypes, "keytypes", "t", []string{}, "ssh key types to be created")
return baseCmd
}

View File

@@ -38,6 +38,7 @@ type RootConf struct {
DHCP *DHCPConf `yaml:"dhcp"`
TFTP *TFTPConf `yaml:"tftp"`
NFS *NFSConf `yaml:"nfs"`
SSH *SSHConf `yaml:"ssh,omitempty"`
MountsContainer []*MountEntry `yaml:"container mounts" default:"[{\"source\": \"/etc/resolv.conf\", \"dest\": \"/etc/resolv.conf\"}]"`
Paths *BuildConfig `yaml:"paths"`
@@ -53,6 +54,7 @@ func New() *RootConf {
cachedConf.DHCP = new(DHCPConf)
cachedConf.TFTP = new(TFTPConf)
cachedConf.NFS = new(NFSConf)
cachedConf.SSH = new(SSHConf)
cachedConf.Paths = new(BuildConfig)
if err := defaults.Set(&cachedConf); err != nil {
panic(err)

View File

@@ -0,0 +1,5 @@
package config
type SSHConf struct {
KeyTypes []string `yaml:"key types" default:"[\"rsa\",\"dsa\",\"ecdsa\",\"ed25519\"]"`
}

View File

@@ -11,7 +11,11 @@ import (
"github.com/warewulf/warewulf/internal/pkg/wwlog"
)
func SSH() error {
/*
Create password less ssh keys in the home of the user who its
calling this function. (root in our case)
*/
func SSH(keyTypes ...string) error {
if os.Getuid() == 0 {
fmt.Printf("Updating system keys\n")
conf := warewulfconf.Get()
@@ -23,7 +27,7 @@ func SSH() error {
os.Exit(1)
}
for _, k := range [4]string{"rsa", "dsa", "ecdsa", "ed25519"} {
for _, k := range keyTypes {
keytype := "ssh_host_" + k + "_key"
if !util.IsFile(path.Join(wwkeydir, keytype)) {
fmt.Printf("Setting up key: %s\n", keytype)
@@ -48,21 +52,26 @@ func SSH() error {
}
authorizedKeys := path.Join(homeDir, "/.ssh/authorized_keys")
rsaPriv := path.Join(homeDir, "/.ssh/id_rsa")
rsaPub := path.Join(homeDir, "/.ssh/id_rsa.pub")
if !util.IsFile(authorizedKeys) {
fmt.Printf("Setting up: %s\n", authorizedKeys)
err = util.ExecInteractive("ssh-keygen", "-q", "-t", "rsa", "-f", rsaPriv, "-C", "", "-N", "")
if err != nil {
return errors.Wrap(err, "failed to exec ssh-keygen command")
}
err := util.CopyFile(rsaPub, authorizedKeys)
if err != nil {
return errors.Wrap(err, "failed to copy keys")
if len(keyTypes) > 0 {
keyType := keyTypes[0]
fmt.Printf("Setting up: %s\n", authorizedKeys)
privKey := path.Join(homeDir, "/.ssh/id_"+keyType)
pubKey := privKey + ".pub"
err = util.ExecInteractive("ssh-keygen", "-q", "-t", keyType, "-f", privKey, "-C", "", "-N", "")
if err != nil {
return errors.Wrap(err, "Failed to exec ssh-keygen command")
}
err := util.CopyFile(pubKey, authorizedKeys)
if err != nil {
return errors.Wrap(err, fmt.Sprintf("Failed to copy %s to authorized_keys", pubKey))
}
} else {
fmt.Printf("Skipping authorized_keys: no key types configured\n")
}
} else {
fmt.Printf("Skipping, authorized_keys already exists: %s\n", authorizedKeys)
fmt.Printf("Skipping authorized_keys: already exists: %s\n", authorizedKeys)
}
return nil

View File

@@ -31,6 +31,7 @@ type TemplateStruct struct {
Ipv6 bool
Dhcp warewulfconf.DHCPConf
Nfs warewulfconf.NFSConf
Ssh warewulfconf.SSHConf
Warewulf warewulfconf.WarewulfConf
Tftp warewulfconf.TFTPConf
Paths warewulfconf.BuildConfig
@@ -60,6 +61,7 @@ func InitStruct(nodeInfo *node.NodeInfo) TemplateStruct {
tstruct.Id = nodeInfo.Id.Get()
tstruct.Hostname = nodeInfo.Id.Get()
tstruct.Nfs = *controller.NFS
tstruct.Ssh = *controller.SSH
tstruct.Dhcp = *controller.DHCP
tstruct.Tftp = *controller.TFTP
tstruct.Paths = *controller.Paths

View File

@@ -108,6 +108,15 @@ data from other structures.
- Mount: {{ $export.Mount }}
{{- end }}
### SSH
{{- if gt (len .Ssh.KeyTypes) 0 }}
- Key types:
{{- range $index, $keyType := .Ssh.KeyTypes }}
- {{ $keyType }}
{{- end }}
- First key type: {{ index .Ssh.KeyTypes 0 }}
{{- end }}
### Warewulf

View File

@@ -3,12 +3,13 @@
## Automatically configure SSH keys for a user on C SHell login
## Copy this file to /etc/profile.d along with ssh_setup.sh
{{- if gt (len .Ssh.KeyTypes) 0 }}
{{ $keyType := index .Ssh.KeyTypes 0 }}
set _UID=`id -u`
if ( ( $_UID > 500 || $_UID == 0 ) && ( ! -f "$HOME/.ssh/config" && ! -f "$HOME/.ssh/cluster" ) ) then
echo "Configuring SSH for cluster access"
install -d -m 700 $HOME/.ssh
ssh-keygen -t rsa -f $HOME/.ssh/cluster -N '' -C "Warewulf Cluster key" >& /dev/null
ssh-keygen -t {{ $keyType }} -f $HOME/.ssh/cluster -N '' -C "Warewulf Cluster key" >& /dev/null
cat $HOME/.ssh/cluster.pub >>! $HOME/.ssh/authorized_keys
chmod 0600 $HOME/.ssh/authorized_keys
@@ -20,3 +21,6 @@ if ( ( $_UID > 500 || $_UID == 0 ) && ( ! -f "$HOME/.ssh/config" && ! -f "$HOME/
echo " StrictHostKeyChecking=no" >> $HOME/.ssh/config
chmod 0600 $HOME/.ssh/config
endif
{{- else }}
# No ssh key types configured
{{- end }}

View File

@@ -11,12 +11,13 @@
## Automatically configure SSH keys for a user on login
## Copy this file to /etc/profile.d
{{- if gt (len .Ssh.KeyTypes) 0 }}
{{ $keyType := index .Ssh.KeyTypes 0 }}
_UID=`id -u`
if [ $_UID -ge 500 -o $_UID -eq 0 ] && [ ! -f "$HOME/.ssh/config" -a ! -f "$HOME/.ssh/cluster" ]; then
echo "Configuring SSH for cluster access"
install -d -m 700 $HOME/.ssh
ssh-keygen -t rsa -f $HOME/.ssh/cluster -N '' -C "Warewulf Cluster key" > /dev/null 2>&1
ssh-keygen -t {{ $keyType }} -f $HOME/.ssh/cluster -N '' -C "Warewulf Cluster key" > /dev/null 2>&1
cat $HOME/.ssh/cluster.pub >> $HOME/.ssh/authorized_keys
chmod 0600 $HOME/.ssh/authorized_keys
@@ -26,3 +27,6 @@ if [ $_UID -ge 500 -o $_UID -eq 0 ] && [ ! -f "$HOME/.ssh/config" -a ! -f "$HOME
echo " StrictHostKeyChecking=no" >> $HOME/.ssh/config
chmod 0600 $HOME/.ssh/config
fi
{{- else }}
# No ssh key types configured
{{- end }}

View File

@@ -49,6 +49,12 @@ Warewulf (4.5.1):
- source: /etc/resolv.conf
dest: /etc/resolv.conf
readonly: true
ssh:
key types:
- rsa
- dsa
- ecdsa
- ed25519
Generally you can leave this file as is, as long as you set the
appropriate networking information. Specifically the following
@@ -151,6 +157,25 @@ may be overridden using ``warewulf.conf:paths``.
* ``wwclientdir``: Where the Warewulf client looks for its configuration on a provisioned node.
SSH key types
-------------
*New in Warewulf v4.5.1*
SSH key types to generate during ``wwctl configure ssh`` may be overridden using ``warewulf.conf:ssh:key types``.
.. code-block:: yaml
ssh:
key types:
- rsa
- dsa
- ecdsa
- ed25519
Warewulf will generate host keys for each listed key type.
The first listed key type is used to generate authentication ssh keys.
nodes.conf
==========