1
0
mirror of https://github.com/rancher/rke.git synced 2025-08-11 11:42:44 +00:00

Leverage global SSHAgentAuth setting

This addresses users issues in being unable to use RKE command line
using SSH_AUTH_SOCK. On OSX the socket env var is set, but nothing
is listening. Also, Linux users have reported issues. To address this
the default mode is to not use SSH Agent Auth. A user must set it
explicitly in either the config file or on the CLI. The only way
to use a passphrase protected key file is with a properly configured
SSH Agent and using SSH Agent Auth.
This commit is contained in:
Bill Maxwell 2018-03-05 17:52:43 -07:00
parent f76f954b42
commit ad0bc6c0aa
6 changed files with 74 additions and 24 deletions

View File

@ -46,6 +46,7 @@ func (c *Cluster) setClusterDefaults(ctx context.Context) {
if len(c.SSHKeyPath) == 0 { if len(c.SSHKeyPath) == 0 {
c.SSHKeyPath = DefaultClusterSSHKeyPath c.SSHKeyPath = DefaultClusterSSHKeyPath
} }
for i, host := range c.Nodes { for i, host := range c.Nodes {
if len(host.InternalAddress) == 0 { if len(host.InternalAddress) == 0 {
c.Nodes[i].InternalAddress = c.Nodes[i].Address c.Nodes[i].InternalAddress = c.Nodes[i].Address
@ -60,7 +61,11 @@ func (c *Cluster) setClusterDefaults(ctx context.Context) {
if len(host.Port) == 0 { if len(host.Port) == 0 {
c.Nodes[i].Port = DefaultSSHPort c.Nodes[i].Port = DefaultSSHPort
} }
// For now, you can set at the global level only.
c.Nodes[i].SSHAgentAuth = c.SSHAgentAuth
} }
if len(c.Authorization.Mode) == 0 { if len(c.Authorization.Mode) == 0 {
c.Authorization.Mode = DefaultAuthorizationMode c.Authorization.Mode = DefaultAuthorizationMode
} }

View File

@ -6,9 +6,17 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/rancher/types/apis/management.cattle.io/v3"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
var sshCliOptions = []cli.Flag{
cli.BoolFlag{
Name: "ssh-agent-auth",
Usage: "Use SSH Agent Auth defined by SSH_AUTH_SOCK",
},
}
func resolveClusterFile(ctx *cli.Context) (string, string, error) { func resolveClusterFile(ctx *cli.Context) (string, string, error) {
clusterFile := ctx.String("config") clusterFile := ctx.String("config")
fp, err := filepath.Abs(clusterFile) fp, err := filepath.Abs(clusterFile)
@ -27,3 +35,11 @@ func resolveClusterFile(ctx *cli.Context) (string, string, error) {
clusterFileBuff := string(buf) clusterFileBuff := string(buf)
return clusterFileBuff, clusterFile, nil return clusterFileBuff, clusterFile, nil
} }
func setOptionsFromCLI(c *cli.Context, rkeConfig *v3.RancherKubernetesEngineConfig) (*v3.RancherKubernetesEngineConfig, error) {
// If true... override the file.. else let file value go through
if c.Bool("ssh-agent-auth") {
rkeConfig.SSHAgentAuth = c.Bool("ssh-agent-auth")
}
return rkeConfig, nil
}

View File

@ -34,6 +34,9 @@ func RemoveCommand() cli.Command {
Usage: "Deploy Kubernetes cluster locally", Usage: "Deploy Kubernetes cluster locally",
}, },
} }
removeFlags = append(removeFlags, sshCliOptions...)
return cli.Command{ return cli.Command{
Name: "remove", Name: "remove",
Usage: "Teardown the cluster and clean cluster nodes", Usage: "Teardown the cluster and clean cluster nodes",
@ -96,6 +99,12 @@ func clusterRemoveFromCli(ctx *cli.Context) error {
if err != nil { if err != nil {
return fmt.Errorf("Failed to parse cluster file: %v", err) return fmt.Errorf("Failed to parse cluster file: %v", err)
} }
rkeConfig, err = setOptionsFromCLI(ctx, rkeConfig)
if err != nil {
return err
}
return ClusterRemove(context.Background(), rkeConfig, nil, nil, false, "") return ClusterRemove(context.Background(), rkeConfig, nil, nil, false, "")
} }
@ -113,5 +122,11 @@ func clusterRemoveLocal(ctx *cli.Context) error {
} }
rkeConfig.Nodes = []v3.RKEConfigNode{*cluster.GetLocalRKENodeConfig()} rkeConfig.Nodes = []v3.RKEConfigNode{*cluster.GetLocalRKENodeConfig()}
} }
rkeConfig, err = setOptionsFromCLI(ctx, rkeConfig)
if err != nil {
return err
}
return ClusterRemove(context.Background(), rkeConfig, nil, nil, true, "") return ClusterRemove(context.Background(), rkeConfig, nil, nil, true, "")
} }

View File

@ -29,6 +29,9 @@ func UpCommand() cli.Command {
Usage: "Deploy Kubernetes cluster locally", Usage: "Deploy Kubernetes cluster locally",
}, },
} }
upFlags = append(upFlags, sshCliOptions...)
return cli.Command{ return cli.Command{
Name: "up", Name: "up",
Usage: "Bring the cluster up", Usage: "Bring the cluster up",
@ -139,6 +142,12 @@ func clusterUpFromCli(ctx *cli.Context) error {
if err != nil { if err != nil {
return fmt.Errorf("Failed to parse cluster file: %v", err) return fmt.Errorf("Failed to parse cluster file: %v", err)
} }
rkeConfig, err = setOptionsFromCLI(ctx, rkeConfig)
if err != nil {
return err
}
_, _, _, _, err = ClusterUp(context.Background(), rkeConfig, nil, nil, nil, false, "") _, _, _, _, err = ClusterUp(context.Background(), rkeConfig, nil, nil, nil, false, "")
return err return err
} }

View File

@ -18,6 +18,7 @@ type dialer struct {
username string username string
netConn string netConn string
dockerSocket string dockerSocket string
useSSHAgentAuth bool
} }
func newDialer(h *Host, kind string) (*dialer, error) { func newDialer(h *Host, kind string) (*dialer, error) {
@ -28,6 +29,7 @@ func newDialer(h *Host, kind string) (*dialer, error) {
sshKeyString: h.SSHKey, sshKeyString: h.SSHKey,
netConn: "unix", netConn: "unix",
sshPassphrase: []byte(h.SavedKeyPhrase), sshPassphrase: []byte(h.SavedKeyPhrase),
useSSHAgentAuth: h.SSHAgentAuth,
} }
if dialer.sshKeyString == "" { if dialer.sshKeyString == "" {
@ -84,7 +86,7 @@ func (d *dialer) Dial(network, addr string) (net.Conn, error) {
} }
func (d *dialer) getSSHTunnelConnection() (*ssh.Client, error) { func (d *dialer) getSSHTunnelConnection() (*ssh.Client, error) {
cfg, err := getSSHConfig(d.username, d.sshKeyString, d.sshPassphrase) cfg, err := getSSHConfig(d.username, d.sshKeyString, d.sshPassphrase, d.useSSHAgentAuth)
if err != nil { if err != nil {
return nil, fmt.Errorf("Error configuring SSH: %v", err) return nil, fmt.Errorf("Error configuring SSH: %v", err)
} }

View File

@ -82,12 +82,14 @@ func parsePrivateKeyWithPassPhrase(keyBuff string, passphrase []byte) (ssh.Signe
return ssh.ParsePrivateKeyWithPassphrase([]byte(keyBuff), passphrase) return ssh.ParsePrivateKeyWithPassphrase([]byte(keyBuff), passphrase)
} }
func getSSHConfig(username, sshPrivateKeyString string, passphrase []byte) (*ssh.ClientConfig, error) { func getSSHConfig(username, sshPrivateKeyString string, passphrase []byte, useAgentAuth bool) (*ssh.ClientConfig, error) {
config := &ssh.ClientConfig{ config := &ssh.ClientConfig{
User: username, User: username,
HostKeyCallback: ssh.InsecureIgnoreHostKey(), HostKeyCallback: ssh.InsecureIgnoreHostKey(),
} }
// Kind of a double check now.
if useAgentAuth {
if sshAgentSock := os.Getenv("SSH_AUTH_SOCK"); sshAgentSock != "" { if sshAgentSock := os.Getenv("SSH_AUTH_SOCK"); sshAgentSock != "" {
sshAgent, err := net.Dial("unix", sshAgentSock) sshAgent, err := net.Dial("unix", sshAgentSock)
if err != nil { if err != nil {
@ -99,6 +101,7 @@ func getSSHConfig(username, sshPrivateKeyString string, passphrase []byte) (*ssh
logrus.Debugf("using %q SSH_AUTH_SOCK", sshAgentSock) logrus.Debugf("using %q SSH_AUTH_SOCK", sshAgentSock)
return config, nil return config, nil
} }
}
signer, err := getPrivateKeySigner(sshPrivateKeyString, passphrase) signer, err := getPrivateKeySigner(sshPrivateKeyString, passphrase)
if err != nil { if err != nil {