提交 08e173f2 编写于 作者: P Peter Maydell

Merge remote-tracking branch 'remotes/berrange/tags/qcrypto-next-pull-request' into staging

# gpg: Signature made Fri 06 Apr 2018 14:29:10 BST
# gpg:                using RSA key BE86EBB415104FDF
# gpg: Good signature from "Daniel P. Berrange <dan@berrange.com>"
# gpg:                 aka "Daniel P. Berrange <berrange@redhat.com>"
# Primary key fingerprint: DAF3 A6FD B26B 6291 2D0E  8E3F BE86 EBB4 1510 4FDF

* remotes/berrange/tags/qcrypto-next-pull-request:
  crypto: ensure we use a predictable TLS priority setting
  docs: Document -object tls-creds-x509 priority=xxx
  docs: update information for TLS certificate management
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
...@@ -140,6 +140,7 @@ accelerator is required to use more than one host CPU for emulation. ...@@ -140,6 +140,7 @@ accelerator is required to use more than one host CPU for emulation.
* direct_linux_boot:: Direct Linux Boot * direct_linux_boot:: Direct Linux Boot
* pcsys_usb:: USB emulation * pcsys_usb:: USB emulation
* vnc_security:: VNC security * vnc_security:: VNC security
* network_tls:: TLS setup for network services
* gdb_usage:: GDB usage * gdb_usage:: GDB usage
* pcsys_os_specific:: Target OS specific information * pcsys_os_specific:: Target OS specific information
@end menu @end menu
...@@ -1041,7 +1042,6 @@ considerations depending on the deployment scenarios. ...@@ -1041,7 +1042,6 @@ considerations depending on the deployment scenarios.
* vnc_sec_certificate_pw:: * vnc_sec_certificate_pw::
* vnc_sec_sasl:: * vnc_sec_sasl::
* vnc_sec_certificate_sasl:: * vnc_sec_certificate_sasl::
* vnc_generate_cert::
* vnc_setup_sasl:: * vnc_setup_sasl::
@end menu @end menu
@node vnc_sec_none @node vnc_sec_none
...@@ -1161,25 +1161,105 @@ with the aforementioned TLS + x509 options: ...@@ -1161,25 +1161,105 @@ with the aforementioned TLS + x509 options:
qemu-system-i386 [...OPTIONS...] -vnc :1,tls,x509,sasl -monitor stdio qemu-system-i386 [...OPTIONS...] -vnc :1,tls,x509,sasl -monitor stdio
@end example @end example
@node vnc_setup_sasl
@node vnc_generate_cert @subsection Configuring SASL mechanisms
@subsection Generating certificates for VNC
The GNU TLS packages provides a command called @code{certtool} which can The following documentation assumes use of the Cyrus SASL implementation on a
be used to generate certificates and keys in PEM format. At a minimum it Linux host, but the principles should apply to any other SASL implementation
is necessary to setup a certificate authority, and issue certificates to or host. When SASL is enabled, the mechanism configuration will be loaded from
each server. If using certificates for authentication, then each client system default SASL service config /etc/sasl2/qemu.conf. If running QEMU as an
will also need to be issued a certificate. The recommendation is for the unprivileged user, an environment variable SASL_CONF_PATH can be used to make
server to keep its certificates in either @code{/etc/pki/qemu} or for it search alternate locations for the service config file.
unprivileged users in @code{$HOME/.pki/qemu}.
If the TLS option is enabled for VNC, then it will provide session encryption,
otherwise the SASL mechanism will have to provide encryption. In the latter
case the list of possible plugins that can be used is drastically reduced. In
fact only the GSSAPI SASL mechanism provides an acceptable level of security
by modern standards. Previous versions of QEMU referred to the DIGEST-MD5
mechanism, however, it has multiple serious flaws described in detail in
RFC 6331 and thus should never be used any more. The SCRAM-SHA-1 mechanism
provides a simple username/password auth facility similar to DIGEST-MD5, but
does not support session encryption, so can only be used in combination with
TLS.
When not using TLS the recommended configuration is
@example
mech_list: gssapi
keytab: /etc/qemu/krb5.tab
@end example
This says to use the 'GSSAPI' mechanism with the Kerberos v5 protocol, with
the server principal stored in /etc/qemu/krb5.tab. For this to work the
administrator of your KDC must generate a Kerberos principal for the server,
with a name of 'qemu/somehost.example.com@@EXAMPLE.COM' replacing
'somehost.example.com' with the fully qualified host name of the machine
running QEMU, and 'EXAMPLE.COM' with the Kerberos Realm.
When using TLS, if username+password authentication is desired, then a
reasonable configuration is
@example
mech_list: scram-sha-1
sasldb_path: /etc/qemu/passwd.db
@end example
The @code{saslpasswd2} program can be used to populate the @code{passwd.db}
file with accounts.
Other SASL configurations will be left as an exercise for the reader. Note that
all mechanisms, except GSSAPI, should be combined with use of TLS to ensure a
secure data channel.
@node network_tls
@section TLS setup for network services
Almost all network services in QEMU have the ability to use TLS for
session data encryption, along with x509 certificates for simple
client authentication. What follows is a description of how to
generate certificates suitable for usage with QEMU, and applies to
the VNC server, character devices with the TCP backend, NBD server
and client, and migration server and client.
At a high level, QEMU requires certificates and private keys to be
provided in PEM format. Aside from the core fields, the certificates
should include various extension data sets, including v3 basic
constraints data, key purpose, key usage and subject alt name.
The GnuTLS package includes a command called @code{certtool} which can
be used to easily generate certificates and keys in the required format
with expected data present. Alternatively a certificate management
service may be used.
At a minimum it is necessary to setup a certificate authority, and
issue certificates to each server. If using x509 certificates for
authentication, then each client will also need to be issued a
certificate.
Assuming that the QEMU network services will only ever be exposed to
clients on a private intranet, there is no need to use a commercial
certificate authority to create certificates. A self-signed CA is
sufficient, and in fact likely to be more secure since it removes
the ability of malicious 3rd parties to trick the CA into mis-issuing
certs for impersonating your services. The only likely exception
where a commercial CA might be desirable is if enabling the VNC
websockets server and exposing it directly to remote browser clients.
In such a case it might be useful to use a commercial CA to avoid
needing to install custom CA certs in the web browsers.
The recommendation is for the server to keep its certificates in either
@code{/etc/pki/qemu} or for unprivileged users in @code{$HOME/.pki/qemu}.
@menu @menu
* vnc_generate_ca:: * tls_generate_ca::
* vnc_generate_server:: * tls_generate_server::
* vnc_generate_client:: * tls_generate_client::
* tls_creds_setup::
@end menu @end menu
@node vnc_generate_ca @node tls_generate_ca
@subsubsection Setup the Certificate Authority @subsection Setup the Certificate Authority
This step only needs to be performed once per organization / organizational This step only needs to be performed once per organization / organizational
unit. First the CA needs a private key. This key must be kept VERY secret unit. First the CA needs a private key. This key must be kept VERY secret
...@@ -1190,11 +1270,10 @@ issued with it is lost. ...@@ -1190,11 +1270,10 @@ issued with it is lost.
# certtool --generate-privkey > ca-key.pem # certtool --generate-privkey > ca-key.pem
@end example @end example
A CA needs to have a public certificate. For simplicity it can be a self-signed To generate a self-signed certificate requires one core piece of information,
certificate, or one issue by a commercial certificate issuing authority. To the name of the organization. A template file @code{ca.info} should be
generate a self-signed certificate requires one core piece of information, the populated with the desired data to avoid having to deal with interactive
name of the organization. prompts from certtool:
@example @example
# cat > ca.info <<EOF # cat > ca.info <<EOF
cn = Name of your organization cn = Name of your organization
...@@ -1207,123 +1286,224 @@ EOF ...@@ -1207,123 +1286,224 @@ EOF
--outfile ca-cert.pem --outfile ca-cert.pem
@end example @end example
The @code{ca-cert.pem} file should be copied to all servers and clients wishing to utilize The @code{ca} keyword in the template sets the v3 basic constraints extension
TLS support in the VNC server. The @code{ca-key.pem} must not be disclosed/copied at all. to indicate this certificate is for a CA, while @code{cert_signing_key} sets
the key usage extension to indicate this will be used for signing other keys.
The generated @code{ca-cert.pem} file should be copied to all servers and
clients wishing to utilize TLS support in the VNC server. The @code{ca-key.pem}
must not be disclosed/copied anywhere except the host responsible for issuing
certificates.
@node vnc_generate_server @node tls_generate_server
@subsubsection Issuing server certificates @subsection Issuing server certificates
Each server (or host) needs to be issued with a key and certificate. When connecting Each server (or host) needs to be issued with a key and certificate. When connecting
the certificate is sent to the client which validates it against the CA certificate. the certificate is sent to the client which validates it against the CA certificate.
The core piece of information for a server certificate is the hostname. This should The core pieces of information for a server certificate are the hostnames and/or IP
be the fully qualified hostname that the client will connect with, since the client addresses that will be used by clients when connecting. The hostname / IP address
will typically also verify the hostname in the certificate. On the host holding the that the client specifies when connecting will be validated against the hostname(s)
secure CA private key: and IP address(es) recorded in the server certificate, and if no match is found
the client will close the connection.
@example
# cat > server.info <<EOF Thus it is recommended that the server certificate include both the fully qualified
and unqualified hostnames. If the server will have permanently assigned IP address(es),
and clients are likely to use them when connecting, they may also be included in the
certificate. Both IPv4 and IPv6 addresses are supported. Historically certificates
only included 1 hostname in the @code{CN} field, however, usage of this field for
validation is now deprecated. Instead modern TLS clients will validate against the
Subject Alt Name extension data, which allows for multiple entries. In the future
usage of the @code{CN} field may be discontinued entirely, so providing SAN
extension data is strongly recommended.
On the host holding the CA, create template files containing the information
for each server, and use it to issue server certificates.
@example
# cat > server-hostNNN.info <<EOF
organization = Name of your organization organization = Name of your organization
cn = server.foo.example.com cn = hostNNN.foo.example.com
dns_name = hostNNN
dns_name = hostNNN.foo.example.com
ip_address = 10.0.1.87
ip_address = 192.8.0.92
ip_address = 2620:0:cafe::87
ip_address = 2001:24::92
tls_www_server tls_www_server
encryption_key encryption_key
signing_key signing_key
EOF EOF
# certtool --generate-privkey > server-key.pem # certtool --generate-privkey > server-hostNNN-key.pem
# certtool --generate-certificate \ # certtool --generate-certificate \
--load-ca-certificate ca-cert.pem \ --load-ca-certificate ca-cert.pem \
--load-ca-privkey ca-key.pem \ --load-ca-privkey ca-key.pem \
--load-privkey server-key.pem \ --load-privkey server-hostNNN-key.pem \
--template server.info \ --template server-hostNNN.info \
--outfile server-cert.pem --outfile server-hostNNN-cert.pem
@end example @end example
The @code{server-key.pem} and @code{server-cert.pem} files should now be securely copied The @code{dns_name} and @code{ip_address} fields in the template are setting
to the server for which they were generated. The @code{server-key.pem} is security the subject alt name extension data. The @code{tls_www_server} keyword is the
sensitive and should be kept protected with file mode 0600 to prevent disclosure. key purpose extension to indicate this certificate is intended for usage in
a web server. Although QEMU network services are not in fact HTTP servers
(except for VNC websockets), setting this key purpose is still recommended.
The @code{encryption_key} and @code{signing_key} keyword is the key usage
extension to indicate this certificate is intended for usage in the data
session.
@node vnc_generate_client The @code{server-hostNNN-key.pem} and @code{server-hostNNN-cert.pem} files
@subsubsection Issuing client certificates should now be securely copied to the server for which they were generated,
and renamed to @code{server-key.pem} and @code{server-cert.pem} when added
to the @code{/etc/pki/qemu} directory on the target host. The @code{server-key.pem}
file is security sensitive and should be kept protected with file mode 0600
to prevent disclosure.
@node tls_generate_client
@subsection Issuing client certificates
The QEMU x509 TLS credential setup defaults to enabling client verification
using certificates, providing a simple authentication mechanism. If this
default is used, each client also needs to be issued a certificate. The client
certificate contains enough metadata to uniquely identify the client with the
scope of the certificate authority. The client certificate would typically
include fields for organization, state, city, building, etc.
Once again on the host holding the CA, create template files containing the
information for each client, and use it to issue client certificates.
If the QEMU VNC server is to use the @code{x509verify} option to validate client
certificates as its authentication mechanism, each client also needs to be issued
a certificate. The client certificate contains enough metadata to uniquely identify
the client, typically organization, state, city, building, etc. On the host holding
the secure CA private key:
@example @example
# cat > client.info <<EOF # cat > client-hostNNN.info <<EOF
country = GB country = GB
state = London state = London
locality = London locality = City Of London
organization = Name of your organization organization = Name of your organization
cn = client.foo.example.com cn = hostNNN.foo.example.com
tls_www_client tls_www_client
encryption_key encryption_key
signing_key signing_key
EOF EOF
# certtool --generate-privkey > client-key.pem # certtool --generate-privkey > client-hostNNN-key.pem
# certtool --generate-certificate \ # certtool --generate-certificate \
--load-ca-certificate ca-cert.pem \ --load-ca-certificate ca-cert.pem \
--load-ca-privkey ca-key.pem \ --load-ca-privkey ca-key.pem \
--load-privkey client-key.pem \ --load-privkey client-hostNNN-key.pem \
--template client.info \ --template client-hostNNN.info \
--outfile client-cert.pem --outfile client-hostNNN-cert.pem
@end example
The subject alt name extension data is not required for clients, so the
the @code{dns_name} and @code{ip_address} fields are not included.
The @code{tls_www_client} keyword is the key purpose extension to indicate
this certificate is intended for usage in a web client. Although QEMU
network clients are not in fact HTTP clients, setting this key purpose is
still recommended. The @code{encryption_key} and @code{signing_key} keyword
is the key usage extension to indicate this certificate is intended for
usage in the data session.
The @code{client-hostNNN-key.pem} and @code{client-hostNNN-cert.pem} files
should now be securely copied to the client for which they were generated,
and renamed to @code{client-key.pem} and @code{client-cert.pem} when added
to the @code{/etc/pki/qemu} directory on the target host. The @code{client-key.pem}
file is security sensitive and should be kept protected with file mode 0600
to prevent disclosure.
If a single host is going to be using TLS in both a client and server
role, it is possible to create a single certificate to cover both roles.
This would be quite common for the migration and NBD services, where a
QEMU process will be started by accepting a TLS protected incoming migration,
and later itself be migrated out to another host. To generate a single
certificate, simply include the template data from both the client and server
instructions in one.
@example
# cat > both-hostNNN.info <<EOF
country = GB
state = London
locality = City Of London
organization = Name of your organization
cn = hostNNN.foo.example.com
dns_name = hostNNN
dns_name = hostNNN.foo.example.com
ip_address = 10.0.1.87
ip_address = 192.8.0.92
ip_address = 2620:0:cafe::87
ip_address = 2001:24::92
tls_www_server
tls_www_client
encryption_key
signing_key
EOF
# certtool --generate-privkey > both-hostNNN-key.pem
# certtool --generate-certificate \
--load-ca-certificate ca-cert.pem \
--load-ca-privkey ca-key.pem \
--load-privkey both-hostNNN-key.pem \
--template both-hostNNN.info \
--outfile both-hostNNN-cert.pem
@end example @end example
The @code{client-key.pem} and @code{client-cert.pem} files should now be securely When copying the PEM files to the target host, save them twice,
copied to the client for which they were generated. once as @code{server-cert.pem} and @code{server-key.pem}, and
again as @code{client-cert.pem} and @code{client-key.pem}.
@node tls_creds_setup
@subsection TLS x509 credential configuration
@node vnc_setup_sasl QEMU has a standard mechanism for loading x509 credentials that will be
used for network services and clients. It requires specifying the
@code{tls-creds-x509} class name to the @code{--object} command line
argument for the system emulators. Each set of credentials loaded should
be given a unique string identifier via the @code{id} parameter. A single
set of TLS credentials can be used for multiple network backends, so VNC,
migration, NBD, character devices can all share the same credentials. Note,
however, that credentials for use in a client endpoint must be loaded
separately from those used in a server endpoint.
@subsection Configuring SASL mechanisms When specifying the object, the @code{dir} parameters specifies which
directory contains the credential files. This directory is expected to
contain files with the names mentioned previously, @code{ca-cert.pem},
@code{server-key.pem}, @code{server-cert.pem}, @code{client-key.pem}
and @code{client-cert.pem} as appropriate. It is also possible to
include a set of pre-generated Diffie-Hellman (DH) parameters in a file
@code{dh-params.pem}, which can be created using the
@code{certtool --generate-dh-params} command. If omitted, QEMU will
dynamically generate DH parameters when loading the credentials.
The following documentation assumes use of the Cyrus SASL implementation on a The @code{endpoint} parameter indicates whether the credentials will
Linux host, but the principals should apply to any other SASL impl. When SASL be used for a network client or server, and determines which PEM
is enabled, the mechanism configuration will be loaded from system default files are loaded.
SASL service config /etc/sasl2/qemu.conf. If running QEMU as an
unprivileged user, an environment variable SASL_CONF_PATH can be used
to make it search alternate locations for the service config.
If the TLS option is enabled for VNC, then it will provide session encryption, The @code{verify} parameter determines whether x509 certificate
otherwise the SASL mechanism will have to provide encryption. In the latter validation should be performed. This defaults to enabled, meaning
case the list of possible plugins that can be used is drastically reduced. In clients will always validate the server hostname against the
fact only the GSSAPI SASL mechanism provides an acceptable level of security certificate subject alt name fields and/or CN field. It also
by modern standards. Previous versions of QEMU referred to the DIGEST-MD5 means that servers will request that clients provide a certificate
mechanism, however, it has multiple serious flaws described in detail in and validate them. Verification should never be turned off for
RFC 6331 and thus should never be used any more. The SCRAM-SHA-1 mechanism client endpoints, however, it may be turned off for server endpoints
provides a simple username/password auth facility similar to DIGEST-MD5, but if an alternative mechanism is used to authenticate clients. For
does not support session encryption, so can only be used in combination with example, the VNC server can use SASL to authenticate clients
TLS. instead.
When not using TLS the recommended configuration is To load server credentials with client certificate validation
enabled
@example @example
mech_list: gssapi $QEMU -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server
keytab: /etc/qemu/krb5.tab
@end example @end example
This says to use the 'GSSAPI' mechanism with the Kerberos v5 protocol, with while to load client credentials use
the server principal stored in /etc/qemu/krb5.tab. For this to work the
administrator of your KDC must generate a Kerberos principal for the server,
with a name of 'qemu/somehost.example.com@@EXAMPLE.COM' replacing
'somehost.example.com' with the fully qualified host name of the machine
running QEMU, and 'EXAMPLE.COM' with the Kerberos Realm.
When using TLS, if username+password authentication is desired, then a
reasonable configuration is
@example @example
mech_list: scram-sha-1 $QEMU -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=client
sasldb_path: /etc/qemu/passwd.db
@end example @end example
The saslpasswd2 program can be used to populate the passwd.db file with Network services which support TLS will all have a @code{tls-creds}
accounts. parameter which expects the ID of the TLS credentials object. For
example with VNC:
Other SASL configurations will be left as an exercise for the reader. Note that @example
all mechanisms except GSSAPI, should be combined with use of TLS to ensure a $QEMU -vnc 0.0.0.0:0,tls-creds=tls0
secure data channel. @end example
@node gdb_usage @node gdb_usage
@section GDB usage @section GDB usage
......
...@@ -4112,7 +4112,7 @@ expensive operation that consumes random pool entropy, so it is ...@@ -4112,7 +4112,7 @@ expensive operation that consumes random pool entropy, so it is
recommended that a persistent set of parameters be generated recommended that a persistent set of parameters be generated
upfront and saved. upfront and saved.
@item -object tls-creds-x509,id=@var{id},endpoint=@var{endpoint},dir=@var{/path/to/cred/dir},verify-peer=@var{on|off},passwordid=@var{id} @item -object tls-creds-x509,id=@var{id},endpoint=@var{endpoint},dir=@var{/path/to/cred/dir},priority=@var{priority},verify-peer=@var{on|off},passwordid=@var{id}
Creates a TLS anonymous credentials object, which can be used to provide Creates a TLS anonymous credentials object, which can be used to provide
TLS support on network backends. The @option{id} parameter is a unique TLS support on network backends. The @option{id} parameter is a unique
...@@ -4145,6 +4145,15 @@ version by providing the @var{passwordid} parameter. This provides ...@@ -4145,6 +4145,15 @@ version by providing the @var{passwordid} parameter. This provides
the ID of a previously created @code{secret} object containing the the ID of a previously created @code{secret} object containing the
password for decryption. password for decryption.
The @var{priority} parameter allows to override the global default
priority used by gnutls. This can be useful if the system administrator
needs to use a weaker set of crypto priorities for QEMU without
potentially forcing the weakness onto all applications. Or conversely
if one wants wants a stronger default for QEMU than for all other
applications, they can do this through this parameter. Its format is
a gnutls priority string as described at
@url{https://gnutls.org/manual/html_node/Priority-Strings.html}.
@item -object filter-buffer,id=@var{id},netdev=@var{netdevid},interval=@var{t}[,queue=@var{all|rx|tx}][,status=@var{on|off}] @item -object filter-buffer,id=@var{id},netdev=@var{netdevid},interval=@var{t}[,queue=@var{all|rx|tx}][,status=@var{on|off}]
Interval @var{t} can't be 0, this filter batches the packet delivery: all Interval @var{t} can't be 0, this filter batches the packet delivery: all
......
...@@ -75,6 +75,7 @@ static QCryptoTLSCreds *test_tls_creds_create(QCryptoTLSCredsEndpoint endpoint, ...@@ -75,6 +75,7 @@ static QCryptoTLSCreds *test_tls_creds_create(QCryptoTLSCredsEndpoint endpoint,
"server" : "client"), "server" : "client"),
"dir", certdir, "dir", certdir,
"verify-peer", "yes", "verify-peer", "yes",
"priority", "NORMAL",
/* We skip initial sanity checks here because we /* We skip initial sanity checks here because we
* want to make sure that problems are being * want to make sure that problems are being
* detected at the TLS session validation stage, * detected at the TLS session validation stage,
......
...@@ -78,6 +78,7 @@ static QCryptoTLSCreds *test_tls_creds_create(QCryptoTLSCredsEndpoint endpoint, ...@@ -78,6 +78,7 @@ static QCryptoTLSCreds *test_tls_creds_create(QCryptoTLSCredsEndpoint endpoint,
"server" : "client"), "server" : "client"),
"dir", certdir, "dir", certdir,
"verify-peer", "yes", "verify-peer", "yes",
"priority", "NORMAL",
/* We skip initial sanity checks here because we /* We skip initial sanity checks here because we
* want to make sure that problems are being * want to make sure that problems are being
* detected at the TLS session validation stage, * detected at the TLS session validation stage,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册