[lxc-devel] [lxd/master] PKI mode and some fixes
stgraber on Github
lxc-bot at linuxcontainers.org
Wed Jun 1 22:55:15 UTC 2016
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160601/c69d4284/attachment.bin>
-------------- next part --------------
From f636e5f89364ba5491c3125ca111106bd4850ff6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 27 May 2016 20:07:48 -0400
Subject: [PATCH 1/3] Fix parsing of <FQDN>:<PORT>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxc/remote.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lxc/remote.go b/lxc/remote.go
index e5573b5..a01b0f6 100644
--- a/lxc/remote.go
+++ b/lxc/remote.go
@@ -113,7 +113,7 @@ func (c *remoteCmd) addServer(config *lxd.Config, server string, addr string, ac
// Fix broken URL parser
if !strings.Contains(addr, "://") && remoteURL.Scheme != "" && remoteURL.Scheme != "unix" && remoteURL.Host == "" {
- remoteURL.Host = remoteURL.Scheme
+ remoteURL.Host = addr
remoteURL.Scheme = ""
}
From 9bdd37997a279a259e8d99e3b3ebfe311dcb1dad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 13 May 2016 22:51:48 -0400
Subject: [PATCH 2/3] Implement PKI authentication
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This adds support for enteprise PKI mode where a central Certificate
Authority is used to issue certificates for the LXD daemons as well as
the clients.
To enable this, replace or add the following files on the daemon side:
- server.crt (CA generated server certificate)
- server.key (key for the above certificate)
- server.ca (Certificate Authority root certificate)
And on the client side:
- client.crt (CA generated client certificate)
- client.key (key for the above certificate)
- client.ca (Certificate Authority root certificate)
In such mode, only clients using certificates issued by the PKI will be
able to connect. Normal password authentication is still used on first
handshake.
Closes #1985
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
client.go | 19 ++++++++++++++++---
doc/lxd-ssl-authentication.md | 13 +++++++++++--
lxc/remote.go | 2 +-
lxd/api_1.0.go | 8 ++++++++
lxd/containers_post.go | 2 +-
lxd/daemon.go | 26 ++++++++++++++++++++++----
lxd/images.go | 2 +-
shared/network.go | 29 ++++++++++++++++++++++++++---
shared/simplestreams.go | 2 +-
9 files changed, 87 insertions(+), 16 deletions(-)
diff --git a/client.go b/client.go
index 213b9cb..db12ed0 100644
--- a/client.go
+++ b/client.go
@@ -186,6 +186,17 @@ func NewClient(config *Config, remote string) (*Client, error) {
info.ClientPEMKey = string(keyBytes)
}
+ // Read the client key (if it exists)
+ clientCaPath := path.Join(config.ConfigDir, "client.ca")
+ if shared.PathExists(clientCaPath) {
+ caBytes, err := ioutil.ReadFile(clientCaPath)
+ if err != nil {
+ return nil, err
+ }
+
+ info.ClientPEMCa = string(caBytes)
+ }
+
// Read the server certificate (if it exists)
serverCertPath := config.ServerCertPath(remote)
if shared.PathExists(serverCertPath) {
@@ -222,6 +233,8 @@ type ConnectInfo struct {
ClientPEMCert string
// ClientPEMKey is the PEM encoded private bytes of the client's key associated with its certificate
ClientPEMKey string
+ // ClientPEMCa is the PEM encoded client certificate authority (if any)
+ ClientPEMCa string
// ServerPEMCert is the PEM encoded server certificate that we are
// connecting to. It can be the empty string if we do not know the
// server's certificate yet.
@@ -264,8 +277,8 @@ func connectViaUnix(c *Client, remote *RemoteConfig) error {
return nil
}
-func connectViaHttp(c *Client, remote *RemoteConfig, clientCert, clientKey, serverCert string) error {
- tlsconfig, err := shared.GetTLSConfigMem(clientCert, clientKey, serverCert)
+func connectViaHttp(c *Client, remote *RemoteConfig, clientCert, clientKey, clientCA, serverCert string) error {
+ tlsconfig, err := shared.GetTLSConfigMem(clientCert, clientKey, clientCA, serverCert)
if err != nil {
return err
}
@@ -307,7 +320,7 @@ func NewClientFromInfo(info ConnectInfo) (*Client, error) {
if strings.HasPrefix(info.RemoteConfig.Addr, "unix:") {
err = connectViaUnix(c, &info.RemoteConfig)
} else {
- err = connectViaHttp(c, &info.RemoteConfig, info.ClientPEMCert, info.ClientPEMKey, info.ServerPEMCert)
+ err = connectViaHttp(c, &info.RemoteConfig, info.ClientPEMCert, info.ClientPEMKey, info.ClientPEMCa, info.ServerPEMCert)
}
if err != nil {
return nil, err
diff --git a/doc/lxd-ssl-authentication.md b/doc/lxd-ssl-authentication.md
index f648b8e..bf50ed5 100644
--- a/doc/lxd-ssl-authentication.md
+++ b/doc/lxd-ssl-authentication.md
@@ -56,8 +56,8 @@ A CRL may also accompany the CA certificate.
In that mode, any connection to a LXD daemon will be done using the
preseeded CA certificate. If the server certificate isn't signed by the
-CA, or if it has been revoked, the connection will simply go through the
-normal authentication mechanism.
+CA, the connection will simply go through the normal authentication
+mechanism.
If the server certificate is valid and signed by the CA, then the
connection continues without prompting the user for the certificate.
@@ -67,6 +67,15 @@ it matches, the client certificate is added to the server's trust store
and the client can now connect to the server without having to provide
any additional credentials.
+Enabling PKI mode is done by replacing adding a client.ca file in the
+client's configuration directory (~/.config/lxc) and a server.ca file in
+the server's configuration directory (/var/lib/lxd). Then a client
+certificate must be issued by the CA for the client and a server
+certificate for the server. Those must then replace the existing
+pre-generated files.
+
+After this is done, restarting the server will have it run in PKI mode.
+
# Password prompt
To establish a new trust relationship, a password must be set on the
server and send by the client when adding itself.
diff --git a/lxc/remote.go b/lxc/remote.go
index a01b0f6..df75e8a 100644
--- a/lxc/remote.go
+++ b/lxc/remote.go
@@ -58,7 +58,7 @@ func (c *remoteCmd) flags() {
func getRemoteCertificate(address string) (*x509.Certificate, error) {
// Setup a permissive TLS config
- tlsConfig, err := shared.GetTLSConfig("", "", nil)
+ tlsConfig, err := shared.GetTLSConfig("", "", "", nil)
if err != nil {
return nil, err
}
diff --git a/lxd/api_1.0.go b/lxd/api_1.0.go
index 19c5516..6ac93e9 100644
--- a/lxd/api_1.0.go
+++ b/lxd/api_1.0.go
@@ -45,9 +45,17 @@ var api10 = []Command{
func api10Get(d *Daemon, r *http.Request) Response {
body := shared.Jmap{
+ /* List of API extensions in the order they were added
+ * Is considered an API extension, any new configuration keys,
+ * any new argument to a REST endpoint or any new REST endpoint.
+ *
+ * Extra authentication methods should also be included.
+ */
"api_extensions": []string{
"syscall_filtering",
+ "auth_pki",
},
+
"api_status": "stable",
"api_version": shared.APIVersion,
}
diff --git a/lxd/containers_post.go b/lxd/containers_post.go
index 25e37ca..c124621 100644
--- a/lxd/containers_post.go
+++ b/lxd/containers_post.go
@@ -260,7 +260,7 @@ func createFromMigration(d *Daemon, req *containerPostReq) Response {
}
}
- config, err := shared.GetTLSConfig("", "", cert)
+ config, err := shared.GetTLSConfig("", "", "", cert)
if err != nil {
c.Delete()
return err
diff --git a/lxd/daemon.go b/lxd/daemon.go
index 49a6f7f..d8bf79d 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -118,7 +118,7 @@ func (d *Daemon) httpGetSync(url string, certificate string) (*lxd.Response, err
}
}
- tlsConfig, err := shared.GetTLSConfig("", "", cert)
+ tlsConfig, err := shared.GetTLSConfig("", "", "", cert)
if err != nil {
return nil, err
}
@@ -170,7 +170,7 @@ func (d *Daemon) httpGetFile(url string, certificate string) (*http.Response, er
}
}
- tlsConfig, err := shared.GetTLSConfig("", "", cert)
+ tlsConfig, err := shared.GetTLSConfig("", "", "", cert)
if err != nil {
return nil, err
}
@@ -212,7 +212,6 @@ func readMyCert() (string, string, error) {
certf := shared.VarPath("server.crt")
keyf := shared.VarPath("server.key")
shared.Log.Info("Looking for existing certificates", log.Ctx{"cert": certf, "key": keyf})
-
err := shared.FindOrGenCert(certf, keyf)
return certf, keyf, err
@@ -223,14 +222,17 @@ func (d *Daemon) isTrustedClient(r *http.Request) bool {
// Unix socket
return true
}
+
if r.TLS == nil {
return false
}
+
for i := range r.TLS.PeerCertificates {
if d.CheckTrustState(*r.TLS.PeerCertificates[i]) {
return true
}
}
+
return false
}
@@ -247,6 +249,7 @@ func isJSONRequest(r *http.Request) bool {
func (d *Daemon) isRecursionRequest(r *http.Request) bool {
recursionStr := r.FormValue("recursion")
+
recursion, err := strconv.Atoi(recursionStr)
if err != nil {
return false
@@ -798,6 +801,21 @@ func (d *Daemon) Init() error {
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
PreferServerCipherSuites: true,
}
+
+ if shared.PathExists(shared.VarPath("server.ca")) {
+ ca, err := shared.ReadCert(shared.VarPath("server.ca"))
+ if err != nil {
+ return err
+ }
+
+ caPool := x509.NewCertPool()
+ caPool.AddCert(ca)
+ tlsConfig.RootCAs = caPool
+ tlsConfig.ClientCAs = caPool
+
+ shared.Log.Info("LXD is in CA mode, only CA-signed certificates will be allowed")
+ }
+
tlsConfig.BuildNameToCertificate()
d.tlsConfig = tlsConfig
@@ -1009,8 +1027,8 @@ func (d *Daemon) CheckTrustState(cert x509.Certificate) bool {
shared.Log.Debug("Found cert", log.Ctx{"k": k})
return true
}
- shared.Log.Debug("Client cert != key", log.Ctx{"k": k})
}
+
return false
}
diff --git a/lxd/images.go b/lxd/images.go
index 5013787..3410b6b 100644
--- a/lxd/images.go
+++ b/lxd/images.go
@@ -323,7 +323,7 @@ func imgPostURLInfo(d *Daemon, req imagePostReq, op *operation) error {
}
// Resolve the image URL
- tlsConfig, err := shared.GetTLSConfig("", "", nil)
+ tlsConfig, err := shared.GetTLSConfig("", "", "", nil)
if err != nil {
return err
}
diff --git a/shared/network.go b/shared/network.go
index 08e7019..cfd2017 100644
--- a/shared/network.go
+++ b/shared/network.go
@@ -47,7 +47,10 @@ func initTLSConfig() *tls.Config {
func finalizeTLSConfig(tlsConfig *tls.Config, tlsRemoteCert *x509.Certificate) {
// Trusted certificates
if tlsRemoteCert != nil {
- caCertPool := x509.NewCertPool()
+ caCertPool := tlsConfig.RootCAs
+ if caCertPool == nil {
+ caCertPool = x509.NewCertPool()
+ }
// Make it a valid RootCA
tlsRemoteCert.IsCA = true
@@ -66,7 +69,7 @@ func finalizeTLSConfig(tlsConfig *tls.Config, tlsRemoteCert *x509.Certificate) {
tlsConfig.BuildNameToCertificate()
}
-func GetTLSConfig(tlsClientCertFile string, tlsClientKeyFile string, tlsRemoteCert *x509.Certificate) (*tls.Config, error) {
+func GetTLSConfig(tlsClientCertFile string, tlsClientKeyFile string, tlsClientCAFile string, tlsRemoteCert *x509.Certificate) (*tls.Config, error) {
tlsConfig := initTLSConfig()
// Client authentication
@@ -79,11 +82,23 @@ func GetTLSConfig(tlsClientCertFile string, tlsClientKeyFile string, tlsRemoteCe
tlsConfig.Certificates = []tls.Certificate{cert}
}
+ if tlsClientCAFile != "" {
+ caCertificates, err := ioutil.ReadFile(tlsClientCAFile)
+ if err != nil {
+ return nil, err
+ }
+
+ caPool := x509.NewCertPool()
+ caPool.AppendCertsFromPEM(caCertificates)
+
+ tlsConfig.RootCAs = caPool
+ }
+
finalizeTLSConfig(tlsConfig, tlsRemoteCert)
return tlsConfig, nil
}
-func GetTLSConfigMem(tlsClientCert string, tlsClientKey string, tlsRemoteCertPEM string) (*tls.Config, error) {
+func GetTLSConfigMem(tlsClientCert string, tlsClientKey string, tlsClientCA string, tlsRemoteCertPEM string) (*tls.Config, error) {
tlsConfig := initTLSConfig()
// Client authentication
@@ -106,6 +121,14 @@ func GetTLSConfigMem(tlsClientCert string, tlsClientKey string, tlsRemoteCertPEM
return nil, err
}
}
+
+ if tlsClientCA != "" {
+ caPool := x509.NewCertPool()
+ caPool.AppendCertsFromPEM([]byte(tlsClientCA))
+
+ tlsConfig.RootCAs = caPool
+ }
+
finalizeTLSConfig(tlsConfig, tlsRemoteCert)
return tlsConfig, nil
diff --git a/shared/simplestreams.go b/shared/simplestreams.go
index 7842e75..9db9994 100644
--- a/shared/simplestreams.go
+++ b/shared/simplestreams.go
@@ -222,7 +222,7 @@ type SimpleStreamsIndexStream struct {
func SimpleStreamsClient(url string, proxy func(*http.Request) (*url.URL, error)) (*SimpleStreams, error) {
// Setup a http client
- tlsConfig, err := GetTLSConfig("", "", nil)
+ tlsConfig, err := GetTLSConfig("", "", "", nil)
if err != nil {
return nil, err
}
From 22137da015111d1244915e12f74c11f5d55e2caf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 1 Jun 2016 17:17:29 -0400
Subject: [PATCH 3/3] Properly export and document recent API additions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
doc/api_extensions.md | 40 ++++++++++++++++++++++
doc/configuration.md | 94 +++++++++++++++++++++++++--------------------------
lxd/api_1.0.go | 4 ++-
3 files changed, 90 insertions(+), 48 deletions(-)
create mode 100644 doc/api_extensions.md
diff --git a/doc/api_extensions.md b/doc/api_extensions.md
new file mode 100644
index 0000000..691ebdd
--- /dev/null
+++ b/doc/api_extensions.md
@@ -0,0 +1,40 @@
+# API extensions
+
+The changes below were introduced to the LXD API after the 1.0 API was finalized.
+
+They are all backward compatible and can be detected by client tools by
+looking at the api\_extensions field in GET /1.0/.
+
+
+## storage\_zfs\_remove\_snapshots
+A storage.zfs\_remove\_snapshots daemon configuration key was introduced.
+
+It's a boolean that defaults to false and that when set to true instructs LXD
+to remove any needed snapshot when attempting to restore another.
+
+This is needed as ZFS will only let you restore the latest snapshot.
+
+## container\_host\_shutdown\_timeout
+A boot.host\_shutdown\_timeout container configuration key was introduced.
+
+It's an integer which indicates how long LXD should wait for the container
+to stop before killing it.
+
+Its value is only used on clean LXD daemon shutdown. It defaults to 30s.
+
+## container\_syscall\_filtering
+A number of new syscalls related container configuration keys were introduced.
+
+ * security.syscalls.blacklist\_default
+ * security.syscalls.blacklist\_compat
+ * security.syscalls.blacklist
+ * security.syscalls.whitelist
+
+See configuration.md for how to use them.
+
+## auth\_pki
+This indicates support for PKI authentication mode.
+
+In this mode, the client and server both must use certificates issued by the same PKI.
+
+See lxd-ssl-authentication.md for details.
diff --git a/doc/configuration.md b/doc/configuration.md
index 0e0de40..5b6fba4 100644
--- a/doc/configuration.md
+++ b/doc/configuration.md
@@ -17,26 +17,26 @@ currently supported:
- images (image configuration)
- storage (storage configuration)
-Key | Type | Default | Description
-:-- | :--- | :------ | :----------
-core.https\_address | string | - | Address to bind for the remote API
-core.https\_allowed\_origin | string | - | Access-Control-Allow-Origin http header value
-core.https\_allowed\_methods | string | - | Access-Control-Allow-Methods http header value
-core.https\_allowed\_headers | string | - | Access-Control-Allow-Headers http header value
-core.proxy\_https | string | - | https proxy to use, if any (falls back to HTTPS\_PROXY environment variable)
-core.proxy\_http | string | - | http proxy to use, if any (falls back to HTTP\_PROXY environment variable)
-core.proxy\_ignore\_hosts | string | - | hosts which don't need the proxy for use (similar format to NO\_PROXY, e.g. 1.2.3.4,1.2.3.5, falls back to NO\_PROXY environment variable)
-core.trust\_password | string | - | Password to be provided by clients to setup a trust
-storage.lvm\_vg\_name | string | - | LVM Volume Group name to be used for container and image storage. A default Thin Pool is created using 100% of the free space in the Volume Group, unless `storage.lvm_thinpool_name` is set.
-storage.lvm\_thinpool\_name | string | "LXDPool" | LVM Thin Pool to use within the Volume Group specified in `storage.lvm_vg_name`, if the default pool parameters are undesirable.
-storage.lvm\_fstype | string | ext4 | Format LV with filesystem, for now it's value can be only ext4 (default) or xfs.
-storage.lvm\_volume\_size | string | 10GiB | Size of the logical volume
-storage.zfs\_pool\_name | string | - | ZFS pool name
-storage.zfs\_remove\_snapshots | boolean | false | Automatically remove any needed snapshot when attempting a container restore
-images.compression\_algorithm | string | gzip | Compression algorithm to use for new images (bzip2, gzip, lzma, xz or none)
-images.remote\_cache\_expiry | integer | 10 | Number of days after which an unused cached remote image will be flushed
-images.auto\_update\_interval | integer | 6 | Interval in hours at which to look for update to cached images (0 disables it)
-images.auto\_update\_cached | boolean | true | Whether to automatically update any image that LXD caches
+Key | Type | Default | API extension | Description
+:-- | :--- | :------ | :------------ | :----------
+core.https\_address | string | - | - | Address to bind for the remote API
+core.https\_allowed\_origin | string | - | - | Access-Control-Allow-Origin http header value
+core.https\_allowed\_methods | string | - | - | Access-Control-Allow-Methods http header value
+core.https\_allowed\_headers | string | - | - | Access-Control-Allow-Headers http header value
+core.proxy\_https | string | - | - | https proxy to use, if any (falls back to HTTPS\_PROXY environment variable)
+core.proxy\_http | string | - | - | http proxy to use, if any (falls back to HTTP\_PROXY environment variable)
+core.proxy\_ignore\_hosts | string | - | - | hosts which don't need the proxy for use (similar format to NO\_PROXY, e.g. 1.2.3.4,1.2.3.5, falls back to NO\_PROXY environment variable)
+core.trust\_password | string | - | - | Password to be provided by clients to setup a trust
+storage.lvm\_vg\_name | string | - | - | LVM Volume Group name to be used for container and image storage. A default Thin Pool is created using 100% of the free space in the Volume Group, unless `storage.lvm_thinpool_name` is set.
+storage.lvm\_thinpool\_name | string | "LXDPool" | - | LVM Thin Pool to use within the Volume Group specified in `storage.lvm_vg_name`, if the default pool parameters are undesirable.
+storage.lvm\_fstype | string | ext4 | - | Format LV with filesystem, for now it's value can be only ext4 (default) or xfs.
+storage.lvm\_volume\_size | string | 10GiB | - | Size of the logical volume
+storage.zfs\_pool\_name | string | - | - | ZFS pool name
+storage.zfs\_remove\_snapshots | boolean | false | storage\_zfs\_remove\_snapshots | Automatically remove any needed snapshot when attempting a container restore
+images.compression\_algorithm | string | gzip | - | Compression algorithm to use for new images (bzip2, gzip, lzma, xz or none)
+images.remote\_cache\_expiry | integer | 10 | - | Number of days after which an unused cached remote image will be flushed
+images.auto\_update\_interval | integer | 6 | - | Interval in hours at which to look for update to cached images (0 disables it)
+images.auto\_update\_cached | boolean | true | - | Whether to automatically update any image that LXD caches
Those keys can be set using the lxc tool with:
@@ -64,33 +64,33 @@ currently supported:
The currently supported keys are:
-Key | Type | Default | Live update | Description
-:-- | :--- | :------ | :---------- | :----------
-boot.autostart | boolean | false | n/a | Always start the container when LXD starts
-boot.autostart.delay | integer | 0 | n/a | Number of seconds to wait after the container started before starting the next one
-boot.autostart.priority | integer | 0 | n/a | What order to start the containers in (starting with highest)
-boot.host_shutdown_timeout | integer | 30 | yes | Seconds to wait for container to shutdown before it is force stopped
-environment.\* | string | - | yes (exec) | key/value environment variables to export to the container and set on exec
-limits.cpu | string | - (all) | yes | Number or range of CPUs to expose to the container
-limits.cpu.allowance | string | 100% | yes | How much of the CPU can be used. Can be a percentage (e.g. 50%) for a soft limit or hard a chunk of time (25ms/100ms)
-limits.cpu.priority | integer | 10 (maximum) | yes | CPU scheduling priority compared to other containers sharing the same CPUs (overcommit)
-limits.disk.priority | integer | 5 (medium) | yes | When under load, how much priority to give to the container's I/O requests
-limits.memory | string | - (all) | yes | Percentage of the host's memory or fixed value in bytes (supports kB, MB, GB, TB, PB and EB suffixes)
-limits.memory.enforce | string | hard | yes | If hard, container can't exceed its memory limit. If soft, the container can exceed its memory limit when extra host memory is available.
-limits.memory.swap | boolean | true | yes | Whether to allow some of the container's memory to be swapped out to disk
-limits.memory.swap.priority | integer | 10 (maximum) | yes | The higher this is set, the least likely the container is to be swapped to disk
-limits.network.priority | integer | 0 (minimum) | yes | When under load, how much priority to give to the container's network requests
-limits.processes | integer | - (max) | yes | Maximum number of processes that can run in the container
-linux.kernel\_modules | string | - | yes | Comma separated list of kernel modules to load before starting the container
-raw.apparmor | blob | - | yes | Apparmor profile entries to be appended to the generated profile
-raw.lxc | blob | - | no | Raw LXC configuration to be appended to the generated one
-security.nesting | boolean | false | yes | Support running lxd (nested) inside the container
-security.privileged | boolean | false | no | Runs the container in privileged mode
-security.syscalls.blacklist\_default | boolean | true | no | Enables the default syscall blacklist
-security.syscalls.blacklist\_compat | boolean | false | no | On x86\_64 this enables blocking of compat\_\* syscalls, it is a no-op on other arches
-security.syscalls.blacklist | string | - | no | A '\n' separated list of syscalls to blacklist
-seucrity.syscalls.whitelist | string | - | no | A '\n' separated list of syscalls to whitelist (mutually exclusive with security.syscalls.blacklist\*)
-user.\* | string | - | n/a | Free form user key/value storage (can be used in search)
+Key | Type | Default | Live update | API extension | Description
+:-- | :--- | :------ | :---------- | :------------ | :----------
+boot.autostart | boolean | false | n/a | - | Always start the container when LXD starts
+boot.autostart.delay | integer | 0 | n/a | - | Number of seconds to wait after the container started before starting the next one
+boot.autostart.priority | integer | 0 | n/a | - | What order to start the containers in (starting with highest)
+boot.host\_shutdown\_timeout | integer | 30 | yes | container\_host\_shutdown\_timeout | Seconds to wait for container to shutdown before it is force stopped
+environment.\* | string | - | yes (exec) | - | key/value environment variables to export to the container and set on exec
+limits.cpu | string | - (all) | yes | - | Number or range of CPUs to expose to the container
+limits.cpu.allowance | string | 100% | yes | - | How much of the CPU can be used. Can be a percentage (e.g. 50%) for a soft limit or hard a chunk of time (25ms/100ms)
+limits.cpu.priority | integer | 10 (maximum) | yes | - | CPU scheduling priority compared to other containers sharing the same CPUs (overcommit)
+limits.disk.priority | integer | 5 (medium) | yes | - | When under load, how much priority to give to the container's I/O requests
+limits.memory | string | - (all) | yes | - | Percentage of the host's memory or fixed value in bytes (supports kB, MB, GB, TB, PB and EB suffixes)
+limits.memory.enforce | string | hard | yes | - | If hard, container can't exceed its memory limit. If soft, the container can exceed its memory limit when extra host memory is available.
+limits.memory.swap | boolean | true | yes | - | Whether to allow some of the container's memory to be swapped out to disk
+limits.memory.swap.priority | integer | 10 (maximum) | yes | - | The higher this is set, the least likely the container is to be swapped to disk
+limits.network.priority | integer | 0 (minimum) | yes | - | When under load, how much priority to give to the container's network requests
+limits.processes | integer | - (max) | yes | - | Maximum number of processes that can run in the container
+linux.kernel\_modules | string | - | yes | - | Comma separated list of kernel modules to load before starting the container
+raw.apparmor | blob | - | yes | - | Apparmor profile entries to be appended to the generated profile
+raw.lxc | blob | - | no | - | Raw LXC configuration to be appended to the generated one
+security.nesting | boolean | false | yes | - | Support running lxd (nested) inside the container
+security.privileged | boolean | false | no | - | Runs the container in privileged mode
+security.syscalls.blacklist\_default | boolean | true | no | container\_syscall\_filtering | Enables the default syscall blacklist
+security.syscalls.blacklist\_compat | boolean | false | no | container\_syscall\_filtering | On x86\_64 this enables blocking of compat\_\* syscalls, it is a no-op on other arches
+security.syscalls.blacklist | string | - | no | container\_syscall\_filtering | A '\n' separated list of syscalls to blacklist
+security.syscalls.whitelist | string | - | no | container\_syscall\_filtering | A '\n' separated list of syscalls to whitelist (mutually exclusive with security.syscalls.blacklist\*)
+user.\* | string | - | n/a | - |Free form user key/value storage (can be used in search)
The following volatile keys are currently internally used by LXD:
diff --git a/lxd/api_1.0.go b/lxd/api_1.0.go
index 6ac93e9..ac854c8 100644
--- a/lxd/api_1.0.go
+++ b/lxd/api_1.0.go
@@ -52,7 +52,9 @@ func api10Get(d *Daemon, r *http.Request) Response {
* Extra authentication methods should also be included.
*/
"api_extensions": []string{
- "syscall_filtering",
+ "storage_zfs_remove_snapshots",
+ "container_host_shutdown_timeout",
+ "container_syscall_filtering",
"auth_pki",
},
More information about the lxc-devel
mailing list