The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/2070
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) ===
From f636e5f89364ba5491c3125ca111106bd4850ff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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", },
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel