Skip to content

Commit

Permalink
eliminate hardcoded from lib/cloud/gcp (#47606)
Browse files Browse the repository at this point in the history
  • Loading branch information
nklaassen authored Oct 17, 2024
1 parent 4edc539 commit 77f531d
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 17 deletions.
28 changes: 13 additions & 15 deletions lib/cloud/gcp/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ import (
"github.com/gravitational/teleport/api/internalutils/stream"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/utils/sshutils"
"github.com/gravitational/teleport/lib/auth/native"
gcpimds "github.com/gravitational/teleport/lib/cloud/imds/gcp"
"github.com/gravitational/teleport/lib/cryptosuites"
)

// sshUser is the user to log in as on GCP VMs.
Expand Down Expand Up @@ -473,6 +473,8 @@ type RunCommandRequest struct {
Script string
// SSHPort is the ssh server port to connect to. Defaults to 22.
SSHPort string
// SSHKeyAlgo is the algorithm to use for generated SSH keys.
SSHKeyAlgo cryptosuites.Algorithm

dialContext func(ctx context.Context, network, addr string) (net.Conn, error)
}
Expand All @@ -487,6 +489,9 @@ func (req *RunCommandRequest) CheckAndSetDefaults() error {
if req.SSHPort == "" {
req.SSHPort = "22"
}
if req.SSHKeyAlgo == cryptosuites.Algorithm(0) {
return trace.BadParameter("ssh key algorithm must be set")
}
if req.dialContext == nil {
dialer := net.Dialer{
Timeout: sshDefaultTimeout,
Expand All @@ -496,20 +501,13 @@ func (req *RunCommandRequest) CheckAndSetDefaults() error {
return nil
}

func generateKeyPair() (ssh.Signer, ssh.PublicKey, error) {
rawPriv, rawPub, err := native.GenerateKeyPair()
if err != nil {
return nil, nil, trace.Wrap(err)
}
signer, err := ssh.ParsePrivateKey(rawPriv)
func generateKeyPair(keyAlgo cryptosuites.Algorithm) (ssh.Signer, error) {
signer, err := cryptosuites.GenerateKeyWithAlgorithm(keyAlgo)
if err != nil {
return nil, nil, trace.Wrap(err)
}
publicKey, _, _, _, err := ssh.ParseAuthorizedKey(rawPub)
if err != nil {
return nil, nil, trace.Wrap(err)
return nil, trace.Wrap(err)
}
return signer, publicKey, nil
sshSigner, err := ssh.NewSignerFromSigner(signer)
return sshSigner, trace.Wrap(err)
}

// RunCommand runs a command on an instance.
Expand All @@ -519,7 +517,7 @@ func RunCommand(ctx context.Context, req *RunCommandRequest) error {
}

// Generate keys and add them to the instance.
signer, publicKey, err := generateKeyPair()
signer, err := generateKeyPair(req.SSHKeyAlgo)
if err != nil {
return trace.Wrap(err)
}
Expand All @@ -543,7 +541,7 @@ https://cloud.google.com/solutions/connecting-securely#storing_host_keys_by_enab
}
keyReq := &SSHKeyRequest{
Instance: instance,
PublicKey: publicKey,
PublicKey: signer.PublicKey(),
}
if err := req.Client.AddSSHKey(ctx, keyReq); err != nil {
return trace.Wrap(err)
Expand Down
6 changes: 4 additions & 2 deletions lib/cloud/gcp/vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import (

"github.com/gravitational/teleport/api/internalutils/stream"
gcpimds "github.com/gravitational/teleport/lib/cloud/imds/gcp"
"github.com/gravitational/teleport/lib/cryptosuites"
"github.com/gravitational/teleport/lib/sshutils"
"github.com/gravitational/teleport/lib/utils"
)
Expand Down Expand Up @@ -224,7 +225,7 @@ func TestRunCommand(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
t.Cleanup(cancel)

signer, publicKey, err := generateKeyPair()
signer, err := generateKeyPair(cryptosuites.ECDSAP256)
require.NoError(t, err)
clientConn, serverConn, err := utils.DualPipeNetConn(
&utils.NetAddr{Addr: "server", AddrNetwork: "tcp"},
Expand All @@ -234,7 +235,7 @@ func TestRunCommand(t *testing.T) {
mock := newMockInstance(t, signer, &mockListener{Conn: serverConn, ctx: ctx})
require.NoError(t, mock.Start())
t.Cleanup(mock.Stop)
mock.hostKeys = []ssh.PublicKey{publicKey}
mock.hostKeys = []ssh.PublicKey{signer.PublicKey()}

inst := &gcpimds.Instance{
Name: "my-instance",
Expand All @@ -257,6 +258,7 @@ func TestRunCommand(t *testing.T) {
dialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return clientConn, nil
},
SSHKeyAlgo: cryptosuites.ECDSAP256,
}))
require.Equal(t, 1, mock.execCount)
}
Expand Down
6 changes: 6 additions & 0 deletions lib/srv/discovery/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import (
"github.com/gravitational/teleport/lib/auth/authclient"
"github.com/gravitational/teleport/lib/cloud"
gcpimds "github.com/gravitational/teleport/lib/cloud/imds/gcp"
"github.com/gravitational/teleport/lib/cryptosuites"
"github.com/gravitational/teleport/lib/integrations/awsoidc"
"github.com/gravitational/teleport/lib/services"
"github.com/gravitational/teleport/lib/srv/discovery/common"
Expand Down Expand Up @@ -1242,6 +1243,10 @@ func (s *Server) handleGCPInstances(instances *server.GCPInstances) error {
s.Log.Debugf("Running Teleport installation on these virtual machines: ProjectID: %s, VMs: %s",
instances.ProjectID, genGCPInstancesLogStr(instances.Instances),
)
sshKeyAlgo, err := cryptosuites.AlgorithmForKey(s.ctx, cryptosuites.GetCurrentSuiteFromPing(s.AccessPoint), cryptosuites.UserSSH)
if err != nil {
return trace.Wrap(err, "finding algorithm for SSH key from ping response")
}
req := server.GCPRunRequest{
Client: client,
Instances: instances.Instances,
Expand All @@ -1250,6 +1255,7 @@ func (s *Server) handleGCPInstances(instances *server.GCPInstances) error {
Params: instances.Parameters,
ScriptName: instances.ScriptName,
PublicProxyAddr: instances.PublicProxyAddr,
SSHKeyAlgo: sshKeyAlgo,
}
if err := s.gcpInstaller.Run(s.ctx, req); err != nil {
return trace.Wrap(err)
Expand Down
3 changes: 3 additions & 0 deletions lib/srv/server/gcp_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
apievents "github.com/gravitational/teleport/api/types/events"
"github.com/gravitational/teleport/lib/cloud/gcp"
gcpimds "github.com/gravitational/teleport/lib/cloud/imds/gcp"
"github.com/gravitational/teleport/lib/cryptosuites"
)

// GCPInstaller handles running commands that install Teleport on GCP
Expand All @@ -47,6 +48,7 @@ type GCPRunRequest struct {
ProjectID string
ScriptName string
PublicProxyAddr string
SSHKeyAlgo cryptosuites.Algorithm
}

// Run runs a command on a set of virtual machines and then blocks until the
Expand All @@ -72,6 +74,7 @@ func (gi *GCPInstaller) Run(ctx context.Context, req GCPRunRequest) error {
req.PublicProxyAddr,
req.Params,
),
SSHKeyAlgo: req.SSHKeyAlgo,
}
return trace.Wrap(gcp.RunCommand(ctx, &runRequest))
})
Expand Down

0 comments on commit 77f531d

Please sign in to comment.