wiki:Web/SecureProfileDelivery

Introduction

In Quattor, profiles contain very sensitive information: sudo configuration, password hashes and even cleartext passwords. It's obvious that they shouldn't be transmitted on untrusted channels, nor to unauthorized peers. We'll explain here how to use X.509 certificates to authenticate clients and servers, and a few Apache directives to avoid that an authenticated client downloads a profile other than his own.

The manual way

Setting up the CA

Administering a CA is a complex task. Here we'll only sketch how to set a mini-CA, with the help of OpenSSL. If you are using a Red Hat variant, the easiest way is to use the package openss-perl for this. It contains a script called CA.pl, which will do everything we need.

/etc/pki/tls/misc/CA.pl -newca

Then, answer all the questions it will prompt. You'll find your generated CA on ../../CA.

Generating certificates for each node

You can use the same script to generate certificates for each node, and then manually distribute them. You should not use a password for the private keys, as you want the node to access the certificate with no human interaction. Please note that packaging the certificates in an RPM is dangerous.

Using SINDES

This documentation is being updated and moved to Doc/OS/SINDES

The above solution doesn't scale if you have many nodes. Instead, it's much better to automate the node profile generation, and to do it in a way the private key doesn't travel on the network. At CERN, and on the Quattor community, the favourite tool for this is SINDES. It requires a database as its backend, but if you are running a mid-sized site chances are that you already have one, so there is no overhead. We'll show now how to use SINDES with Quattor, based on BEgrid's instructions.

Generating the CA

Install the package SINDES-ca, which is available at CERN's repository. I need a link here!** Then, edit /etc/sindes/ca.config; make sure to set O, OU and CN.

 [ req_distinguished_name ]
 O = IIHE
 OU = GRID
 CN = Local BEgrid client CA

Edit /etc/sindes/sindesrc: in ![MISC], set correctly domain (and use it correctly in sindessh !). Next, set the default validity of the certificates, f.i, 10 years:

 default_days = 3650

Run "sindes-bootstrap-ca -a" to generate all certificates etc, and check the output carefully. This also generates a rpm with the CA certificat called eg. Now, edit /etc/httpd/conf.d/sindes-ssl.conf, and make sure your profile directory is not readable by any other virtual host.

Configuring the AII server

Edit /etc/aii/aii-shellfe.conf to ensure it uses the correct certificates, too:

 cdburl = https://f.q.d.n/profiles
 cert_file = /etc/sindes/certs/apache.crt
 key_file = /etc/sindes/keys/apache.key
 ca_file = /etc/sindes/certs/ca.crt

Node configuration

Nodes should request their certificate during the installation. And it should be granted to them, so the SINDES time window should be open by that time. For this, we need a few extra configurations on the node's profile.

Enabling the sindes_getcert component

You'll have to include somewhere on your profile:

include {'components/sindes_getcert/config'};

Next, you have to install the SINDES-client package:

 "/software/packages"=pkg_repl("SINDES-client","1.0.0-3","noarch");

(check that package is already present on your repositories!!). Now, we choose the X.509 fields for our certificate and assign them to the component's tree:

 "/software/components/sindes_getcert/x509_O" = "desired crt /o field";
 "/software/components/sindes_getcert/x509_OU" = "desired crt /ou field";

Next, decide where to store the certificate, key and CA information:

 "/software/components/sindes_getcert/cert_dir" = "/etc/sindes/certs";
 "/software/components/sindes_getcert/client_key" = "client_key.pem";
 "/software/components/sindes_getcert/client_cert" = "client_cert.pem";
 "/software/components/sindes_getcert/client_cert_key" = "client_cert_key.pem";
 "/software/components/sindes_getcert/ca_cert" = SINDES_SITE_CA_CERT_NAME;
 "/software/components/sindes_getcert/ca_cert_rpm" = SINDES_SITE_CA_RPM_NAME;

Configuring AII

During the node's installation, it must use the values of the sindes_getcert component to generate the certificates. We said we want to download the profile only if there is a certificate. How do we solve this? Easy: let AII configure SINDES first, then generate the certificates and finally, download the profile. We handle this with a simple AII hook, present in SVN. Its name is aii-sindes.

 "/system/aii/hooks/post_reboot/0/module" = "aii_sindes";
 "/system/aii/hooks/remove/0/module" = "aii_sindes";
 "/system/aii/hooks/boot/0/module" = "aii_sindes";

The remove hook will make all actions needed to revoke the host's certificate. The boot hook will open the time window. The post_reboot hook will generate the bash script that will request the certificates during the node's installation.

Configuring CCM

No matter the way you choose for generating your certificates, you need to tell CCM to use them to download the profile. Just set the following on the profile:

 "/software/components/ccm/key_file" = "/path/to/key/file";
 "/software/components/ccm/cert_file" = "/path/to/cert/file";
 "/software/components/ccm/ca_file" = "/path/to/ca/file";
 "/software/components/ccm/ca_dir" = "/path/to/ca/dir";
 "/software/components/ccm/world_readable"= 0;

If you use SINDES, those paths can be automatically derived, like this:

 "/software/components/ccm/key_file" =
     value("/software/components/sindes_getcert/cert_dir") + "/" +
     value("/software/components/sindes_getcert/client_key");
 "/software/components/ccm/cert_file" =
     value("/software/components/sindes_getcert/cert_dir") + "/" +
     value("/software/components/sindes_getcert/client_cert");
 "/software/components/ccm/ca_file" =
     value("/software/components/sindes_getcert/cert_dir") + "/" +
     value("/software/components/sindes_getcert/ca_cert");
 "/software/components/ccm/ca_dir" =
     value("/software/components/sindes_getcert/cert_dir");
 "/software/components/ccm/world_readable"= 0;

Configuring Apache

Make sure your profile directory is not readable by any other virtual host. We will need to check that the certificate belongs to the node that presents it, so we allow DNS lookups:

 HostnameLookups On

Now, restrict the access to the profiles directory:

 <Directory "/var/www/https/profiles">
     Options +Indexes
     SSLOptions +StdEnvVars
     SSLRequireSSL
     SSLVerifyClient require
     SSLOptions +StrictRequire
     SSLVerifyDepth 1
     SSLOptions +OptRenegotiate
     SSLRequire %{SSL_CLIENT_S_DN_CN} eq %{REMOTE_HOST}
 </Directory>

Finally, the installation server is special: it must be allowed to download all profiles, to generate the appropriate Kickstarts:

 RewriteMap ACLmap txt:/var/www/acl/ACLmap.txt
 RewriteCond ${ACLmap:%{REMOTE_HOST}|NO} NO
 RewriteRule ^/profiles/.*$ /profiles/profile_%{REMOTE_HOST}.xml

And to let the install server to download all profiles, edit /var/www/acl/ACLmap.txt:

 echo aii-server.my.domain YES > /var/www/acl/ACLmap.txt

References

The SINDES instructions and Apache configuration are based on BEgrid's instructions

Last modified 13 years ago Last modified on Dec 16, 2010, 4:05:36 PM