Description: Remote communications with the LXD daemon happen using JSON over HTTPS. This requires the LXD API to be exposed over the network; see How to expose LXD to the network for instructions. To be able t...

Hide navigation sidebar
Hide table of contents sidebar
Skip to content
Back to top
View this page
Toggle table of contents sidebar

# Remote API authentication

Remote communications with the LXD daemon happen using JSON over HTTPS. This requires the LXD API to be exposed over the network; see How to expose LXD to the network for instructions.

To be able to access the remote API, clients must authenticate with the LXD server. The following authentication methods are supported:

- TLS client certificates

- OpenID Connect authentication

## TLS client certificates

▶ Watch on YouTube

When using TLS client certificates for authentication, both the client and the server will generate a key pair the first time they’re launched. The server will use that key pair for all HTTPS connections to the LXD socket. The client will use its certificate as a client certificate for any client-server communication.

To cause certificates to be regenerated, simply remove the old ones. On the next connection, a new certificate is generated.

### Communication protocol

The supported protocol must be TLS 1.3 or better.

It’s possible to force LXD to accept TLS 1.2 by setting the `LXD_INSECURE_TLS` environment variable on both client and server. However this isn’t a supported setup and should only ever be used when forced to use an outdated corporate proxy.

All communications must use perfect forward secrecy, and ciphers must be limited to strong elliptic curve ones (such as ECDHE-RSA or ECDHE-ECDSA).

Any generated key should be at least 4096 bit RSA, preferably 384 bit ECDSA. When using signatures, only SHA-2 signatures should be trusted.

Since we control both client and server, there is no reason to support any backward compatibility to broken protocol or ciphers.

### Trusted TLS clients

You can obtain the list of TLS certificates trusted by a LXD server with `lxc config trust list`.

Trusted clients can be added in either of the following ways:

- Adding trusted certificates to the server

- Adding client certificates using tokens

The workflow to authenticate with the server is similar to that of SSH, where an initial connection to an unknown server triggers a prompt:

1. When the user adds a server with `lxc remote add`, the server is contacted over HTTPS, its certificate is downloaded and the fingerprint is shown to the user.

2. The user is asked to confirm that this is indeed the server’s fingerprint, which they can manually check by connecting to the server or by asking someone with access to the server to run the info command and compare the fingerprints.

3. The server attempts to authenticate the client:

   - If the client certificate is in the server’s trust store, the connection is granted.

   - If the client certificate is not in the server’s trust store, the server prompts the user for a token. If the provided token matches, the client certificate is added to the server’s trust store and the connection is granted. Otherwise, the connection is rejected.

To revoke trust to a client, remove its certificate from the server with `lxc config trust remove <fingerprint>`.

TLS clients can be restricted to a subset of projects, see Restricted TLS certificates for more information.

#### Adding trusted certificates to the server

The preferred way to add trusted clients is to directly add their certificates to the trust store on the server. To do so, copy the client certificate to the server and register it using `lxc config trust add <file>`.

#### Adding client certificates using tokens

You can also add new clients by using tokens. These tokens expire after a configurable time (`core.remote_token_expiry`) or once they’ve been used.

To use this method, generate a token for each client by calling `lxc config trust add`, which will prompt for the client name. The clients can then add their certificates to the server’s trust store by providing the generated token.

Note

If your LXD server is behind NAT, you must specify its external public address when adding it as a remote for a client:

    lxc remote add <name> <IP_address>

When you are prompted for the token, specify the generated token from the previous step. Alternatively, use the `--token` flag:

    lxc remote add <name> <IP_address> --token <token>

When generating the token on the server, LXD includes a list of IP addresses that the client can use to access the server. However, if the server is behind NAT, these addresses might be local addresses that the client cannot connect to. In this case, you must specify the external address manually.

Alternatively, the clients can provide the token directly when adding the remote: `lxc remote add <name> <token>`.

### Using a PKI system

In a PKI setup, a system administrator manages a central PKI that issues client certificates for all the LXD clients and server certificates for all the LXD daemons.

In PKI mode, TLS authentication requires that client certificates are signed be the CA. This requirement does not apply to clients that authenticate via OIDC.

To enable PKI mode, complete the following steps:

1. Add the CA certificate to all machines:

   - Place the `client.ca` file in the clients’ configuration directories (`~/.config/lxc` or `~/snap/lxd/common/config` for snap users).

   - Place the `server.ca` file in the server’s configuration directory (`/var/lib/lxd` or `/var/snap/lxd/common/lxd` for snap users).

2. Place the certificates issued by the CA in the clients’ configuration directories, replacing the automatically generated `client.crt` and `client.key` files.

3. If you want clients to automatically trust the server, place the certificates issued by the CA in the server’s configuration directory, replacing the automatically generated `server.crt` and `server.key` files.

   When a client adds a PKI-enabled server as a remote, it checks the server certificate and prompts the user to trust the server certificate only if the certificate has not been signed by the CA.

4. Restart the LXD daemon.

Note that CA-signed client certificates are not automatically trusted. You must still add them to the server in one of the ways described in Trusted TLS clients.

To automatically trust CA-signed client certificates, set the `core.trust_ca_certificates` server configuration to true. When `core.trust_ca_certificates` is enabled, any new clients with a CA-signed certificate will have full access to LXD.

To revoke certificates via the PKI, place a certificate revocation list in the server’s configuration directory as `ca.crl` and restart the LXD daemon. A client with a CA-signed certificate that has been revoked, and is present in `ca.crl`, will not be able to authenticate with LXD, nor add LXD as a remote via mutual TLS.

## OpenID Connect authentication

LXD supports using OpenID Connect to authenticate users through an OIDC Identity Provider.

To configure LXD to use OIDC authentication, set the `oidc.*` server configuration options. Your OIDC provider must be configured to enable the Device Authorization Grant type.

To add a remote pointing to a LXD server configured with OIDC authentication, run `lxc remote add <remote_name> <remote_address>`. You are then prompted to authenticate through your web browser, where you must confirm that the device code displayed in the browser matches the device code that is displayed in the terminal window. The LXD client then retrieves and stores an access token, which it provides to LXD for all interactions. The identity provider might also provide a refresh token. In this case, the LXD client uses this refresh token to attempt to retrieve another access token when the current access token has expired.

When an OIDC client initially authenticates with LXD, it does not have access to the majority of the LXD API. OIDC clients must be granted access by an administrator, see Fine-grained authorization.

## TLS server certificate

LXD supports issuing server certificates using ACME services, for example, Let’s Encrypt.

To enable this feature, set the following server configuration:

- `acme.domain`: The domain for which the certificate should be issued.

- `acme.email`: The email address used for the account of the ACME service.

- `acme.agree_tos`: Must be set to `true` to agree to the ACME service’s terms of service.

- `acme.ca_url`: The directory URL of the ACME service. By default, LXD uses “Let’s Encrypt”.

For this feature to work, LXD must be reachable from port 80. This can be achieved by using a reverse proxy such as HAProxy.

Here’s a minimal HAProxy configuration that uses `lxd.example.net` as the domain. After the certificate has been issued, LXD will be reachable from `https://lxd.example.net/`.

Note

A PKI system can be used alongside an ACME provider to verify client certificates. In this case, a secondary CA issues certificates to clients. A `server.ca` and `ca.crl` file should still be added to the server’s configuration directory, but server certificates must not be issued by the secondary CA, as they are managed by the ACME provider. Client certificates issued by the secondary CA should be added to the clients’ configuration directories, but the `client.ca` file must not be added to the clients’ configuration directories. This is because the server certificates were issued by the ACME provider and not the secondary CA.

    # Global configuration
    global
      log /dev/log local0
      chroot /var/lib/haproxy
      stats socket /run/haproxy/admin.sock mode 660 level admin
      stats timeout 30s
      user haproxy
      group haproxy
      daemon
      ssl-default-bind-options ssl-min-ver TLSv1.2
      tune.ssl.default-dh-param 2048
      maxconn 100000

    # Default settings
    defaults
      mode tcp
      timeout connect 5s
      timeout client 30s
      timeout client-fin 30s
      timeout server 120s
      timeout tunnel 6h
      timeout http-request 5s
      maxconn 80000

    # Default backend - Return HTTP 301 (TLS upgrade)
    backend http-301
      mode http
      redirect scheme https code 301

    # Default backend - Return HTTP 403
    backend http-403
      mode http
      http-request deny deny_status 403

    # HTTP dispatcher
    frontend http-dispatcher
      bind :80
      mode http

      # Backend selection
      tcp-request inspect-delay 5s

      # Dispatch
      default_backend http-403
      use_backend http-301 if { hdr(host) -i lxd.example.net }

    # SNI dispatcher
    frontend sni-dispatcher
      bind :443
      mode tcp

      # Backend selection
      tcp-request inspect-delay 5s

      # require TLS
      tcp-request content reject unless { req.ssl_hello_type 1 }

      # Dispatch
      default_backend http-403
      use_backend lxd-nodes if { req.ssl_sni -i lxd.example.net }

    # LXD nodes
    backend lxd-nodes
      mode tcp

      option tcp-check

      # Multiple servers should be listed when running a cluster
      server lxd-node01 1.2.3.4:8443 check
      server lxd-node02 1.2.3.5:8443 check
      server lxd-node03 1.2.3.6:8443 check

## Failure scenarios

In the following scenarios, authentication is expected to fail.

### Server certificate changed

The server certificate might change in the following cases:

- The server was fully reinstalled and therefore got a new certificate.

- The connection is being intercepted (MITM).

In such cases, the client will refuse to connect to the server because the certificate fingerprint does not match the fingerprint in the configuration for this remote.

It is then up to the user to contact the server administrator to check if the certificate did in fact change. If it did, the certificate can be replaced by the new one, or the remote can be removed altogether and re-added.

### Server trust relationship revoked

The server trust relationship is revoked for a client if another trusted client or the local server administrator removes the trust entry for the client on the server.

In this case, the server still uses the same certificate, but all API calls return a 403 code with an error indicating that the client isn’t trusted.

## Related topics

Explanation:

- About security

How-to guides:

- How to expose LXD to the network