Connecting to a remote host using LXD Client API

I’m trying to connect to a remote host (in my local network) using the LXD Go Client

Currently my code looks like this (a copy from the examples):

func main(){
err := start()

if err != nil {
log.Fatal(err)
}
}

func start() (error) {
c, err := lxd.ConnectLXD(“https://10.10.0.5:8443”, nil)
if err != nil {
return err
}

// Container creation request
req := api.ContainersPost{
Name: “my-container”,
Source: api.ContainerSource{
Type: “image”,
Alias: “my-image”,
},
}

// Get LXD to create the container (background operation)
op, err := c.CreateContainer(req)
if err != nil {
return err
}

// Wait for the operation to complete
err = op.Wait()
if err != nil {
return err
}

When I execute this code, it returns:

Get https://10.10.0.5:8443/1.0: x509: certificate signed by unknown authority

So I guess that I should pass some kind of certificate to make it works, but how can I generate and pass this certificate?

I’m using MacOS and I added the lxd server as a remote using the command:

lxc remote add foo 10.10.0.5

This command created a certificate and a key, so if I pass then using curl command, I’m able to authenticate, for example:

curl -sb -H “Accept: application/json” -s -k --cert ~/.config/lxc/client.crt --key ~/.config/lxc/client.key https://10.10.0.5:8443/1.0

I opened that post again but I have get the same error. I’m little bit confused. Can someone enlighten me what cause this problem or how can I overcome?
Regards.

Go’s http library wants to validate the TLS/SSL endpoint its connecting to is using a valid certificate like one issued by Lets-encrypt ETC. If its not it will emit errors like above.

By default LXD uses a self signed cert, so the options are;

  • Use a real cert
  • Add the self signed cert to your hosts system
  • do as this stackoverflow awnser says

Thanks @turtle0x1 for the explanation,

How can I perform that option?
Thanks.

# Download the cert from lxd (assuming locahost)
openssl s_client -showcerts -connect localhost:8443 -servername localhost  </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > lxd_cert.crt
# Copy cert to store (must have the extension `crt`)
sudo cp lxd_cert.crt /usr/share/ca-certificates
# Reload trusted certs from store (chose the "ask" option and mark your cert for install)
sudo dpkg-reconfigure ca-certificates
# Run a test to make sure it works (if you dont use your PC name you will get an error about subjectAltnames not matching, you CANT use "localhost" here
curl https://YOUR_PC_NAME:8443

Haven’t actually tested it with go but it should use the system store for certs.

stackoverflow link for adding certs.
stackoverflow link for downloading certs

Thanks for the information, I applied your procedure and go source code reply with another error.

go run testlxd.go 
&{0xc000158c40 0xc000030180 [] {0 0} 0xc000365ec0  https://127.0.0.1:8443  https  <nil> [] false  }
Container cant created: not authorizedpanic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x48 pc=0x92fd51]

goroutine 1 [running]:
main.main()
        /home/indiana/go/src/github.com/gotest/hello/golxd/testlxd.go:37 +0x2e1
exit status 2

Is the certificate the library is using connect to LXD authorised with LXD? You’ll have to add your certificate first.

lxc config trust --help

Yes, you are right. I have added the lxd_cert.crt certificate but same error.

To be sure were talking about the same thing;

lxd_cert.crt from above is the certificate LXD uses to server HTTPS traffic. We added this to your systems certificate store to “trick” the go library into thinking its a valid certificate (valid meaning one signed by a known CA like LetsEncrypt ETC).

Now your “go app” needs to generate a certificate which is then added to the LXD “trust store” so your “go app” app can be authenticated when trying to create containers.

Thanks @turtle0x1 for information to share, I overcome the problem like that, create a certificate as follows and change the source code like this. By the way, lxc config trust add needed for the certificate authentication.

//----------------------------------------------------------------
	c, err := lxd.ConnectLXD("https://127.0.0.1:8443", &lxd.ConnectionArgs{
		//		TLSServerCert:      "",
		TLSClientCert:      "-----BEGIN CERTIFICATE-----\nMIIDETCCAfkCFALqVoVJL8r63VZNzJjqJfKhqGRqMA0GCSqGSIb3DQEBCwUAMEUx\nCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl\nr2ITTsDsk4WyMlK8l7IPSLxPvxNT\n-----END CERTIFICATE-----\n",
		TLSClientKey:       "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDHCfwJQQjRi5B6\n5tp2HigN6JWc57KITmfMB4xG9XJbucQD2xGVimRuMpuIzsF0zS0dTlWZkCzDZU0H\nX0CcooBbsCAl3ma1iku1BA==\n-----END PRIVATE KEY-----\n",
		InsecureSkipVerify: false,
		SkipGetServer:      false,
		//		CacheExpiry:        0,
	})
openssl req -newkey rsa:2048 -nodes -keyout lxd.key -out lxd.csr
openssl x509 -signkey lxd.key -in lxd.csr -req -days 365 -out lxd.crt

@stgraber , appreciate your help again. :+1:

1 Like