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

lxc: Prevent accept-certificate flag when using trust token #14149

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
24 changes: 17 additions & 7 deletions lxc/remote.go
Copy link
Member

Choose a reason for hiding this comment

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

Please can you add more detail to the commit message explaining what you fixed.

Copy link
Member

Choose a reason for hiding this comment

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

If a remote is added, and then removed from the local config (lxc remote delete)
and the certificate remains trusted on the remote server, when remote is added
again it will fail because it is already trusted.

Is this the current state now and what you've fixed, or what you are changing it to be?

I struggled to understand the change here.

Copy link
Member

Choose a reason for hiding this comment

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

Because:

when remote is added again it will fail because it is already trusted.

Sounds like the wrong behaviour to me, so wanted to understand if this is new or what is being fixed?

Copy link
Member Author

@MusicDin MusicDin Sep 30, 2024

Choose a reason for hiding this comment

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

This is the current behavior. If remote is removed, and readded, it will fail when trying to add client certificate into remote's trust store, because it is already present there - failing with Client is already trusted error, and remote not being added.

IMO, we should instead just continue and add the remote.

Example of current behaviour (LXD running in a VM v2 is our remote server):

$ lxc ls
+------+---------+------------------------+-------------------------------------------------+-----------------+-----------+
| NAME |  STATE  |          IPV4          |                      IPV6                       |      TYPE       | SNAPSHOTS |
+------+---------+------------------------+-------------------------------------------------+-----------------+-----------+
| v2   | RUNNING | 10.70.164.239 (enp5s0) | fd42:2bf4:ef35:8266:216:3eff:fea8:9da4 (enp5s0) | VIRTUAL-MACHINE | 0         |
+------+---------+------------------------+-------------------------------------------------+-----------------+-----------+

# Add the remote (initially).
$ token=$(lxc exec v2 -- lxc config trust add --name test --quiet)
$ lxc remote add test $token

# Remove the remote.
$ lxc remote rm test

# Add the remote (again). The client certificate is already present in remote's trust store.
$ token=$(lxc exec v2 -- lxc config trust add --name test --quiet)
$ lxc remote add test $token
Error: Failed to create certificate: Client is already trusted

Copy link
Member

Choose a reason for hiding this comment

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

Does lxc remote add test work after doing lxc remote rm test?

Copy link
Member Author

@MusicDin MusicDin Sep 30, 2024

Choose a reason for hiding this comment

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

Yes, if target URL is specified:

lxc remote add 10.70.164.239
# or
lxc remote add test 10.70.164.239

When token is used, the address is extracted from the token itself (if specific URL is not provided), so it should work even when token is provided.

Copy link
Member

Choose a reason for hiding this comment

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

Got you. Will the new token still get expired once its used (even though its not really used)?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, the token is not consumed.

Copy link
Member

Choose a reason for hiding this comment

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

Should it not be? From the user's PoV we've used it.

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 think that makes sense. Will fix that.

Original file line number Diff line number Diff line change
Expand Up @@ -449,22 +449,32 @@ func (c *cmdRemoteAdd) run(cmd *cobra.Command, args []string) error {

// Handle certificate prompt
if certificate != nil {
// Prompt for certificate acceptance if user did not allow us to blindly
// accept the remote certificate.
if !c.flagAcceptCert {
digest := shared.CertFingerprint(certificate)

fmt.Printf("%s: %s\n", i18n.G("Certificate fingerprint"), digest)
fmt.Print(i18n.G("ok (y/n/[fingerprint])?") + " ")
line, err := shared.ReadStdin()
if err != nil {
return err
}
for {
line, err := shared.ReadStdin()
if err != nil {
return err
}

if string(line) != digest {
// Continue with adding the remote if digest matches, or the user
// confirmed a fingerprint.
if string(line) == digest || strings.ToLower(string(line[0])) == i18n.G("y") {
break
}

// Error out if the user didn't confirm the fingerprint.
if len(line) < 1 || strings.ToLower(string(line[0])) == i18n.G("n") {
return errors.New(i18n.G("Server certificate NACKed by user"))
} else if strings.ToLower(string(line[0])) != i18n.G("y") {
return errors.New(i18n.G("Please type 'y', 'n' or the fingerprint:"))
}

// Ask again for any other invalid input.
fmt.Print(i18n.G("Please type 'y', 'n' or the fingerprint:"))
}
}

Expand Down