mirror of
https://github.com/rancher/rke.git
synced 2025-08-01 23:33:39 +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:
parent
f76f954b42
commit
ad0bc6c0aa
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
@ -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, "")
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -11,23 +11,25 @@ import (
|
|||||||
type DialerFactory func(h *Host) (func(network, address string) (net.Conn, error), error)
|
type DialerFactory func(h *Host) (func(network, address string) (net.Conn, error), error)
|
||||||
|
|
||||||
type dialer struct {
|
type dialer struct {
|
||||||
signer ssh.Signer
|
signer ssh.Signer
|
||||||
sshKeyString string
|
sshKeyString string
|
||||||
sshAddress string
|
sshAddress string
|
||||||
sshPassphrase []byte
|
sshPassphrase []byte
|
||||||
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) {
|
||||||
dialer := &dialer{
|
dialer := &dialer{
|
||||||
sshAddress: fmt.Sprintf("%s:%s", h.Address, h.Port),
|
sshAddress: fmt.Sprintf("%s:%s", h.Address, h.Port),
|
||||||
username: h.User,
|
username: h.User,
|
||||||
dockerSocket: h.DockerSocket,
|
dockerSocket: h.DockerSocket,
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
@ -82,22 +82,25 @@ 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(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if sshAgentSock := os.Getenv("SSH_AUTH_SOCK"); sshAgentSock != "" {
|
// Kind of a double check now.
|
||||||
sshAgent, err := net.Dial("unix", sshAgentSock)
|
if useAgentAuth {
|
||||||
if err != nil {
|
if sshAgentSock := os.Getenv("SSH_AUTH_SOCK"); sshAgentSock != "" {
|
||||||
return config, fmt.Errorf("Cannot connect to SSH Auth socket %q: %s", sshAgentSock, err)
|
sshAgent, err := net.Dial("unix", sshAgentSock)
|
||||||
|
if err != nil {
|
||||||
|
return config, fmt.Errorf("Cannot connect to SSH Auth socket %q: %s", sshAgentSock, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Auth = append(config.Auth, ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers))
|
||||||
|
|
||||||
|
logrus.Debugf("using %q SSH_AUTH_SOCK", sshAgentSock)
|
||||||
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Auth = append(config.Auth, ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers))
|
|
||||||
|
|
||||||
logrus.Debugf("using %q SSH_AUTH_SOCK", sshAgentSock)
|
|
||||||
return config, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
signer, err := getPrivateKeySigner(sshPrivateKeyString, passphrase)
|
signer, err := getPrivateKeySigner(sshPrivateKeyString, passphrase)
|
||||||
|
Loading…
Reference in New Issue
Block a user