[libvirt-users] TLS and intermediate CA

I have been trying to get set of libvirtd system up and running. My PKI infrastructure involves a root CA and several intermediate CAs. I am trying to get the machines to trust each other across the different intermediate CAs. This is what I have so far: Libvirtd is starting and listening on tls port 16514 I have configured client/server certs/keys and it seems to be using all of these correctly. I have also configured the cacert.pem file (which has two certs in the chain). I have confirmed (recompiling with various debug statements) that the gnutls libraries are successfully loading both certs from the cacert.pem file. When I try to connect with openssl s_client -connect <host>:16514 I get something similar to this: --- Certificate chain 0 s:/CN=kvm999.example.com i:/C=US/ST=Utah/O=Qualtrics/OU=SRE/CN=intca1.example.com --- Server certificate -----BEGIN CERTIFICATE----- ... omitted for brevity -----END CERTIFICATE----- subject=/CN=kvm999.example.com issuer=/C=US/ST=Utah/O=Qualtrics/OU=SRE/CN=intca1.example.com --- Acceptable client certificate CA names /C=US/ST=Utah/O=Qualtrics/OU=SRE/CN=intca1.example.com /C=US/ST=Utah/O=Qualtrics/OU=SRE/CN=rootca.example.com --- The "Server certificate" and "Acceptable client certificate CA names" look right. The problem is that the certificate chain is just the single server cert and does not include the intermediate cert or root cert. As a result clients from other intermediate CAs fail to verify the libvirtd process. I have tried libvirtd 0.10.2 and 1.2.1 both on CentOS 6. Thanks. -- -Nathaniel Cook

On Mon, Apr 21, 2014 at 04:51:00PM -0600, Nathaniel Cook wrote:
I have been trying to get set of libvirtd system up and running. My PKI infrastructure involves a root CA and several intermediate CAs. I am trying to get the machines to trust each other across the different intermediate CAs.
This is what I have so far:
Libvirtd is starting and listening on tls port 16514 I have configured client/server certs/keys and it seems to be using all of these correctly.
I have also configured the cacert.pem file (which has two certs in the chain). I have confirmed (recompiling with various debug statements) that the gnutls libraries are successfully loading both certs from the cacert.pem file.
When I try to connect with openssl s_client -connect <host>:16514 I get something similar to this: --- Certificate chain 0 s:/CN=kvm999.example.com i:/C=US/ST=Utah/O=Qualtrics/OU=SRE/CN=intca1.example.com --- Server certificate -----BEGIN CERTIFICATE----- ... omitted for brevity -----END CERTIFICATE----- subject=/CN=kvm999.example.com issuer=/C=US/ST=Utah/O=Qualtrics/OU=SRE/CN=intca1.example.com --- Acceptable client certificate CA names /C=US/ST=Utah/O=Qualtrics/OU=SRE/CN=intca1.example.com /C=US/ST=Utah/O=Qualtrics/OU=SRE/CN=rootca.example.com ---
The "Server certificate" and "Acceptable client certificate CA names" look right. The problem is that the certificate chain is just the single server cert and does not include the intermediate cert or root cert. As a result clients from other intermediate CAs fail to verify the libvirtd process.
If you have a chain of CAs caroot -> child-ca1 -> child-ca2 -> server cert Then the cacert.pem file you create on the clients / server must include the certs for caroot, child-ca1 and child-ca2 all in one file. You can basically just concatenate the .pem files for all the CAs into one file and gnutls will load all the CA cert blocks it finds in that file Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

Thanks for the response. My current chain is as follows: caroot -> child-ca1 -> server cert My cacert.pem file has both the caroot and the child-ca1 certs. I have recompiled libvirt on my machine with some extra debug statements and verified that both the caroot cert and the child-ca1 certs are being loaded. But when I try to connect the caroot and child-ca1 certs only appear under the "Acceptable client certificate CA names" not the certificate chain. The error I get on the client when connecting is that the server identity could not be verified since the server isn't presenting the entire CA chain just its own cert. On Tue, Apr 22, 2014 at 4:37 AM, Daniel P. Berrange <berrange@redhat.com>wrote:
I have been trying to get set of libvirtd system up and running. My PKI infrastructure involves a root CA and several intermediate CAs. I am
On Mon, Apr 21, 2014 at 04:51:00PM -0600, Nathaniel Cook wrote: trying
to get the machines to trust each other across the different intermediate CAs.
This is what I have so far:
Libvirtd is starting and listening on tls port 16514 I have configured client/server certs/keys and it seems to be using all of these correctly.
I have also configured the cacert.pem file (which has two certs in the chain). I have confirmed (recompiling with various debug statements) that the gnutls libraries are successfully loading both certs from the cacert.pem file.
When I try to connect with openssl s_client -connect <host>:16514 I get something similar to this: --- Certificate chain 0 s:/CN=kvm999.example.com i:/C=US/ST=Utah/O=Qualtrics/OU=SRE/CN=intca1.example.com --- Server certificate -----BEGIN CERTIFICATE----- ... omitted for brevity -----END CERTIFICATE----- subject=/CN=kvm999.example.com issuer=/C=US/ST=Utah/O=Qualtrics/OU=SRE/CN=intca1.example.com --- Acceptable client certificate CA names /C=US/ST=Utah/O=Qualtrics/OU=SRE/CN=intca1.example.com /C=US/ST=Utah/O=Qualtrics/OU=SRE/CN=rootca.example.com ---
The "Server certificate" and "Acceptable client certificate CA names" look right. The problem is that the certificate chain is just the single server cert and does not include the intermediate cert or root cert. As a result clients from other intermediate CAs fail to verify the libvirtd process.
If you have a chain of CAs
caroot -> child-ca1 -> child-ca2 -> server cert
Then the cacert.pem file you create on the clients / server must include the certs for caroot, child-ca1 and child-ca2 all in one file. You can basically just concatenate the .pem files for all the CAs into one file and gnutls will load all the CA cert blocks it finds in that file
Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/:| |: http://libvirt.org -o- http://virt-manager.org:| |: http://autobuild.org -o- http://search.cpan.org/~danberr/:| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc:|
-- -Nathaniel Cook

On Tue, Apr 22, 2014 at 08:24:43AM -0600, Nathaniel Cook wrote:
Thanks for the response.
My current chain is as follows:
caroot -> child-ca1 -> server cert
My cacert.pem file has both the caroot and the child-ca1 certs. I have recompiled libvirt on my machine with some extra debug statements and verified that both the caroot cert and the child-ca1 certs are being loaded. But when I try to connect the caroot and child-ca1 certs only appear under the "Acceptable client certificate CA names" not the certificate chain. The error I get on the client when connecting is that the server identity could not be verified since the server isn't presenting the entire CA chain just its own cert.
Are you willing / able to share the output of certtool -i --infile <filename>.pem for the cacert.pem and servercert.pem on the server, and the likewise for the cacert.pem and clientcert.pem (if used) on the client the fails to connect? Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

OK, so I figured out my own problem. Basically I needed to add the ca chain to each of the cert files. The cacert.pem file had the entire chain but since the clientcert.pem and the servercert.pem files only had a single cert during the handshake the chains were not presented and so verification failed. Once I appended the chain to both the server and client certs the handshake passed. Thanks for the help. I hope this discussion helps others who have similar problems. In summary the contents of each of my files is as follows: servercert.pem -- cert unique to server child-ca1 cert caroot cert clientcert.pem -- cert unique to client child-ca1 cert caroot cert cacert.pem -- child-ca1 cert caroot cert On Tue, Apr 22, 2014 at 8:35 AM, Daniel P. Berrange <berrange@redhat.com>wrote:
Thanks for the response.
My current chain is as follows:
caroot -> child-ca1 -> server cert
My cacert.pem file has both the caroot and the child-ca1 certs. I have recompiled libvirt on my machine with some extra debug statements and verified that both the caroot cert and the child-ca1 certs are being loaded. But when I try to connect the caroot and child-ca1 certs only appear under the "Acceptable client certificate CA names" not the certificate chain. The error I get on the client when connecting is that the server identity could not be verified since the server isn't
On Tue, Apr 22, 2014 at 08:24:43AM -0600, Nathaniel Cook wrote: presenting
the entire CA chain just its own cert.
Are you willing / able to share the output of
certtool -i --infile <filename>.pem
for the cacert.pem and servercert.pem on the server, and the likewise for the cacert.pem and clientcert.pem (if used) on the client the fails to connect?
Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/:| |: http://libvirt.org -o- http://virt-manager.org:| |: http://autobuild.org -o- http://search.cpan.org/~danberr/:| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc:|
-- -Nathaniel Cook
participants (2)
-
Daniel P. Berrange
-
Nathaniel Cook