Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use user identify from $LIMA_HOME/_config/user #83

Merged
merged 2 commits into from
Jun 29, 2021

Conversation

jandubois
Copy link
Member

By default lima uses the public keys from ~/.ssh/*.pub.

This change makes it try $LIME_HOME/_config/user.pub first and only fall back on the ~/.ssh/*.pub keys when that one does not exist. It will create the key under $LIMA_HOME/_config if there aren't any public keys under ~/.ssh.

Fixes #78

return nil
} else {
// Check that private key exists and then try to read public key
if _, err := os.Stat(privateKeyPath); err == nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return err if !error.Is(err, os.ErrNorExist)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DefaultPubKeys doesn't return any errors; it just ignores key files it cannot read. So not sure what to do here.

In the end the user would be told to run ssh-keygen when DefaultPubKeys returns an empty list, so not sure that aborting on the first error is really helpful.

@@ -83,5 +124,12 @@ func SSHArgs(instDir string) ([]string, error) {
"-o", "Compression=no",
"-o", "BatchMode=yes",
}
configDir, err := store.LimaConfigDir()
if err == nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return err if !error.Is(err, os.ErrNorExist)

configDir, err := store.LimaConfigDir()
if err == nil {
privateKeyPath := filepath.Join(configDir, "user")
if _, err := os.Stat(privateKeyPath); err == nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return err if !error.Is(err, os.ErrNorExist)

pkg/sshutil/sshutil.go Outdated Show resolved Hide resolved
pkg/sshutil/sshutil.go Outdated Show resolved Hide resolved
@@ -29,6 +29,20 @@ func LimaDir() (string, error) {
return dir, nil
}

// LimaConfigDir returns the path of the config directory, $LIMA_HOME/_config.
// It will create the directory if it doesn't yet exist.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not sure this function should make the dir.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it is inconsistent with what LimaDir does, but I was thinking about letting that one create the directory too. Would that simplify the calling code?

if err != nil {
return "", err
}
configDir := filepath.Join(limaDir, "_config")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

“_config” should be a constant.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I was tempted to put it into store/filenames, but that package claims it only defines names for the instance directories. So where should _config be defined? New package?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pkg/store.ConfigDir

@jandubois jandubois force-pushed the ssh-key branch 2 times, most recently from b8c126b to 6242841 Compare June 26, 2021 01:48
@jandubois
Copy link
Member Author

@AkihiroSuda I believe I've addresses all issues you pointed out. Can you please confirm?

But I'm wondering now if the user filename shouldn't be a constant too, but again don't know where to put it.

Should store/filenames be extended to cover both config and instance filenames?

@jandubois
Copy link
Member Author

Sorry, I refactored DefaultPubKeys once more, so that it can actually reflect an error back to the caller.

By tightening the error handling I've also reduced the logic nesting level a bit, as it was getting out of hand.

I've also gone ahead and added other file and directory names to the filenames package. Let me know, if this is not how you want it to be!

I believe I'm done with it now (unless you have more feedback).

By default lima uses the public keys from ~/.ssh/*.pub

This change makes it try $LIME_HOME/_config/user.pub first and
only fall back on the ~/.ssh/*.pub keys when that one does not
exist. It will create the key under $LIMA_HOME/_config if there
aren't any public keys under ~/.ssh.

Signed-off-by: Jan Dubois <jan.dubois@suse.com>
@jandubois
Copy link
Member Author

@AkihiroSuda The latest CI failure is different, but I've seen a lot of errors like this before:

time="2021-06-28T21:49:58Z" level=fatal msg="failed to resolve reference \"ghcr.io/stargz-containers/nginx:1.19-alpine-org\": failed to do request: Head \"https://ghcr.io/v2/stargz-containers/nginx/manifests/1.19-alpine-org\": net/http: TLS handshake timeout"

Any idea why that is happening? You would think the connection between gha and ghcr should be pretty solid...

@AkihiroSuda
Copy link
Member

I guess macOS instances might be running on a different infra that isn't optimal for ghcr?

if err := os.MkdirAll(configDir, 0700); err != nil {
return nil, errors.Wrapf(err, "could not create %q directory", configDir)
}
keygenCmd := exec.Command("ssh-keygen", "-t", "ed25519", "-q", "-N", "", "-f",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should lock the directory. I can open a follow-up PR.

args := []string{
"-i", privateKeyPath,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: would it be possible to let ssh read both ~/.lima/_config keys and ~/.ssh keys?

Otherwise this will break existing instances.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: would it be possible to let ssh read both ~/.lima/_config keys and ~/.ssh keys?

Yes, you can specify multiple -i options, and the identities will be tried in sequence. I think the server may be limiting the number of attempts to 3, so it could still fail if the user added multiple keys after creating the instance. But that is already a problem with the current implementation, so doesn't change anything. Just another reason to have a lima-specific identity, and always specify that one first.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: would it be possible to let ssh read both ~/.lima/_config keys and ~/.ssh keys?

I've pushed the change in a separate commit for easier review; lmk if you want me to squash it!

@AkihiroSuda AkihiroSuda added this to the v0.5.0 milestone Jun 29, 2021
Otherwise instances created with the previous release of lima would
become inaccessible by the `limactl shell` command.

Signed-off-by: Jan Dubois <jan.dubois@suse.com>
Copy link
Member

@AkihiroSuda AkihiroSuda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

@AkihiroSuda AkihiroSuda merged commit 11da9c1 into lima-vm:master Jun 29, 2021
@jandubois jandubois deleted the ssh-key branch June 29, 2021 06:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make ssh keys configurable
2 participants