sampledoc

SSLCA

SSLCA is a generator plugin designed to handle creation of SSL private keys and certificates on request.

Borrowing ideas from Genshi Templates and the SSHbase plugin, SSLCA automates the generation of SSL certificates by allowing you to specify key and certificate definitions. Then, when a client requests a Path that contains such a definition within the SSLCA repository, the matching key/cert is generated, and stored in a hostfile in the repo so that subsequent requests do not result in repeated key/cert recreation. In the event that a new key or cert is needed, the offending hostfile can simply be removed from the repository, and the next time that host checks in, a new file will be created. If that file happens to be the key, any dependent certificates will also be regenerated.

Getting started

In order to use SSLCA, you must first have at least one CA configured on your system. For details on setting up your own OpenSSL based CA, please see http://www.openssl.org/docs/apps/ca.html for details of the suggested directory layout and configuration directives.

For SSLCA to work, the openssl.cnf (or other configuration file) for that CA must contain full (not relative) paths.

  1. Add SSLCA to the plugins line in /etc/bcfg2.conf and restart the server – This enables the SSLCA plugin on the Bcfg2 server.

  2. Add a section to your /etc/bcfg2.conf called sslca_foo, replacing foo with the name you wish to give your CA so you can reference it in certificate definitions.

  3. Under that section, add an entry for config that gives the location of the openssl configuration file for your CA.

  4. If necessary, add an entry for passphrase containing the passphrase for the CA’s private key. We store this in /etc/bcfg2.conf as the permissions on that file should have it only readable by the bcfg2 user. If no passphrase entry exists, it is assumed that the private key is stored unencrypted.

  5. Optionally, Add an entry chaincert that points to the location of your ssl chaining certificate. This is used when preexisting certificate hostfiles are found, so that they can be validated and only regenerated if they no longer meet the specification. If you’re using a self signing CA this would be the CA cert that you generated. If the chain cert is a root CA cert (e.g., if it is a self-signing CA), also add an entry root_ca = true. If chaincert is omitted, certificate verification will not be performed.

  6. Once all this is done, you should have a section in your /etc/bcfg2.conf that looks similar to the following:

    [sslca_default]
    config = /etc/pki/CA/openssl.cnf
    passphrase = youReallyThinkIdShareThis?
    chaincert = /etc/pki/CA/chaincert.crt
    root_ca = true
  7. You are now ready to create key and certificate definitions. For this example we’ll assume you’ve added Path entries for the key, /etc/pki/tls/private/localhost.key, and the certificate, /etc/pki/tls/certs/localhost.crt to a bundle or base.

  8. Defining a key or certificate is similar to defining a Cfg file. Under your Bcfg2’s SSLCA/ directory, create the directory structure to match the path to your key. In this case this would be something like /var/lib/bcfg2/SSLCA/etc/pki/tls/private/localhost.key.

  9. Within that directory, create a key.xml file containing the following:

    <KeyInfo>
      <Key type="rsa" bits="2048" />
    </KeyInfo>
    
  10. This will cause the generation of an 2048 bit RSA key when a client requests that Path. Alternatively you can specify dsa as the keytype, or a different number of bits.

  11. Similarly, create the matching directory structure for the certificate path, and a cert.xml containing the following:

    <CertInfo>
      <Cert format="pem" key="/etc/pki/tls/private/localhost.key"
            ca="default" days="365" c="US" l="New York" st="New York"
            o="Your Company Name" />
    </CertInfo>
    
  12. When a client requests the cert path, a certificate will be generated using the key hostfile at the specified key location, using the CA matching the ca attribute. ie. ca=”default” will match [sslca_default] in your /etc/bcfg2.conf

Configuration

bcfg2.conf

bcfg2.conf contains miscellaneous configuration options for the SSLCA plugin. These are described in some detail above in getting-started, but are also enumerated here as a reference. Any booleans in the config file accept the values “1”, “yes”, “true”, and “on” for True, and “0”, “no”, “false”, and “off” for False.

Each directive below should appear at most once in each [sslca_<name>] section. The following directives are understood:

Name Description Values Default
config Path to the openssl config for the CA String None
passphrase Passphrase for the CA private key String None
chaincert Path to the SSL chaining certificate for verification String None
root_ca Whether or not <chaincert> is a root CA (as opposed to an intermediate cert) Boolean false

Only config is required.

cert.xml

schema sslca-cert.xsd
Schema for SSLCA cert.xml
element CertInfo
Top-level tag for describing an SSLCA generated certificate.
Child elements:
  • element Cert

    Attributes:

    Name

    Description

    Values

    Required

    Default

    key

    The full path to the key entry to use for this certificate. This is the client path; e.g., for a key defined at /var/lib/bcfg2/SSLCA/etc/pki/tls/private/foo.key/key.xml, key should be /etc/pki/tls/private/foo.key.

    string

    Yes

    None

    append_chain

    Append the CA chain certificate to the generated certificate (e.g., to produce a certificate in the format required by Nginx.)

    true | false

    No

    false

    c

    Override the country set in the CA config

    string

    No

    None

    ca

    The name of the CA (from bcfg2.conf) to use to generate this certificate.

    string

    No

    default

    days

    Time (in days) the certificate will be valid for.

    integer

    No

    365

    emailaddress

    Override the email address set in the CA config

    string

    No

    None

    format

    The certificate format to produce.

    pem

    No

    pem

    l

    Override the location set in the CA config

    string

    No

    None

    o

    Override the organization set in the CA config

    string

    No

    None

    ou

    Override the organizational unit set in the CA config

    string

    No

    None

    st

    Override the state set in the CA config

    string

    No

    None

  • element Group

    Type: SSLCACertGroupType

  • element Client

    Type: SSLCACertGroupType

  • element subjectAltName

    subjectAltName takes only text content, which may be the following values: string

complexType SSLCACertGroupType
An SSLCACertGroupType is a tag used to provide logic. Child entries of an SSLCACertGroupType tag only apply to machines that match the condition specified – either membership in a group, or a matching client name. negate can be set to negate the sense of the match.
Attributes:
Name Description Values Required Default
name
The name of the client or group to match on. Child entries will only apply to this client or group (unless negate is set).
string No None
negate
Negate the sense of the match, so that child entries only apply to a client if it is not a member of the given group or does not have the given name.
true | false No None
Child elements:

Example

<CertInfo>
  <subjectAltName>test.example.com</subjectAltName>
  <Group name="apache">
    <Cert key="/etc/pki/tls/private/foo.key" days="730"/>
  </Group>
  <Group name="nginx">
    <Cert key="/etc/pki/tls/private/foo.key" days="730"
          append_chain="true"/>
  </Group>
</CertInfo>

key.xml

schema sslca-key.xsd
Schema for SSLCA key.xml
element KeyInfo
Top-level tag for describing an SSLCA generated key.
Child elements:
complexType SSLCAKeyGroupType
An SSLCAKeyGroupType is a tag used to provide logic. Child entries of an SSLCAKeyGroupType tag only apply to machines that match the condition specified – either membership in a group, or a matching client name. negate can be set to negate the sense of the match.
Attributes:
Name Description Values Required Default
name
The name of the client or group to match on. Child entries will only apply to this client or group (unless negate is set).
string No None
negate
Negate the sense of the match, so that child entries only apply to a client if it is not a member of the given group or does not have the given name.
true | false No None
Child elements:

Example

<KeyInfo>
  <Group name="fast">
    <Key type="rsa" bits="1024"/>
  </Group>
  <Group name="secure">
    <Key type="rsa" bits="4096"/>
  </Group>
</KeyInfo>

Automated Bcfg2 SSL Authentication

This section describes one possible scenario for automating ssl certificate generation and distribution for bcfg2 client/server communication using SSLCA. The process involves configuring a certificate authority (CA), generating the CA cert and key pair, configuring the bcfg2 SSLCA plugin and a Bundle to use the SSLCA generated certs to authenticate the bcfg2 client and server.

OpenSSL CA

If you already have a SSL CA available you can skip this section, otherwise you can easily build one on the server using openssl. The paths should be adjusted to suite your preferences.

  1. Prepare the directories and files:

    mkdir -p /etc/pki/CA/newcerts
    mkdir /etc/pki/CA/crl
    echo '01' > /etc/pki/CA/serial
    touch /etc/pki/CA/index.txt
    touch /etc/pki/CA/crlnumber
  2. Edit the openssl.cnf config file, and in the [ CA_default ] section adjust the following parameters:

    dir         = /etc/pki          # Where everything is kept
    certs       = /etc/pki/CA/certs     # Where the issued certs are kept
    database    = /etc/pki/CA/index.txt # database index file.
    new_certs_dir   = /etc/pki/CA/newcerts      # default place for new certs.
    certificate = /etc/pki/CA/certs/bcfg2ca.crt     # The CA certificate
    serial      = /etc/pki/CA/serial        # The current serial number
    crl_dir     = /etc/pki/CA/crl           # Where the issued crl are kept
    crlnumber   = /etc/pki/CA/crlnumber # the current crl number
    crl     = /etc/pki/CA/crl.pem       # The current CRL
    private_key = /etc/pki/CA/private/bcfg2ca.key # The private key
  3. Create the CA root certificate and key pair. You’ll be asked to supply a passphrase, and some organizational info. The most important bit is Common Name which you should set to be the hostname of your bcfg2 server that your clients will see when doing a reverse DNS query on it’s ip address.:

    openssl req -new -x509 -extensions v3_ca -keyout bcfg2ca.key \
        -out bcfg2ca.crt -days 3650
  4. Move the generated cert and key to the locations specified in openssl.cnf:

    mv bcfg2ca.key /etc/pki/CA/private/
    mv bcfg2ca.crt /etc/pki/CA/certs/

Your self-signing CA is now ready to use.

Bcfg2

SSLCA

The SSLCA plugin was not designed specifically to manage bcfg2 client/server communication though it is certainly able to provide certificate generation and management services for that purpose. You’ll need to configure the SSLCA plugin to serve the key, and certificate paths that we will define later in our client’s bcfg2.conf file.

The rest of these instructions will assume that you’ve configured the SSLCA plugin as described above and that the files SSLCA/etc/pki/tls/certs/bcfg2client.crt/cert.xml and SSLCA/etc/pki/tls/private/bcfg2client.key/key.xml represent the cert and key paths you want generated for SSL auth.

Client Bundle

To automate the process of generating and distributing certs to the clients we need define at least the Cert and Key paths served by the SSLCA plugin, as well as the ca certificate path in a Bundle. For example:

<Path name='/etc/pki/tls/certs/bcfg2ca.crt'/>
<Path name='/etc/pki/tls/bcfg2client.crt'/>
<Path name='/etc/pki/tls/private/bcfg2client.key'/>

Here’s a more complete example bcfg2-client bundle:

<Bundle name='bcfg2-client'>
  <Path name='/etc/bcfg2.conf'/>
  <Path name='/etc/cron.d/bcfg2-client'/>
  <Package name='bcfg2'/>
  <Service name='bcfg2'/>
  <Group name='rpm'>
    <Path name='/etc/sysconfig/bcfg2'/>
    <Path name='/etc/pki/tls/certs/bcfg2ca.crt'/>
    <Path name='/etc/pki/tls/certs/bcfg2client.crt'/>
    <Path name='/etc/pki/tls/private/bcfg2client.key'/>
  </Group>
  <Group name='deb'>
    <Path name='/etc/default/bcfg2' altsrc='/etc/sysconfig/bcfg2'/>
    <Path name='/etc/ssl/certs/bcfg2ca.crt' altsrc='/etc/pki/tls/certs/bcfg2ca.crt'/>
    <Path name='/etc/ssl/certs/bcfg2client.crt' altsrc='/etc/pki/tls/certs/bcfg2client.crt'/>
    <Path name='/etc/ssl/private/bcfg2client.key' altsrc='/etc/pki/tls/private/bcfg2client.key'/>
  </Group>
</Bundle>

In the above example we told Bcfg2 that it also needs to serve /etc/bcfg2.conf. This is optional but convenient.

The bcfg2.conf client config needs at least 5 parameters set for SSL auth.

  1. key : This is the host specific key that SSLCA will generate.
  2. certificate : This is the host specific cert that SSLCA will generate.
  3. ca : This is a copy of your CA certificate. Not generated by SSLCA.
  4. user : Usually set to fqdn of client. This shouldn’t be required but is as of 1.3.0. See: http://trac.mcs.anl.gov/projects/bcfg2/ticket/1019
  5. password : Set to arbitrary string when using certificate auth. This also shouldn’t be required. See: http://trac.mcs.anl.gov/projects/bcfg2/ticket/1019

Here’s what a functional [communication] section in a bcfg2.conf genshi template for clients might look like.:

[communication]
protocol = xmlrpc/ssl
{% if metadata.uuid != None %}\
user = ${metadata.uuid}
{% end %}\
password = DUMMYPASSWORDFORCERTAUTH
{% choose %}\
{% when 'rpm' in metadata.groups %}\
certificate = /etc/pki/tls/certs/bcfg2client.crt
key = /etc/pki/tls/private/bcfg2client.key
ca = /etc/pki/tls/certs/bcfg2ca.crt
{% end %}\
{% when 'deb' in metadata.groups %}\
certificate = /etc/ssl/certs/bcfg2client.crt
key = /etc/ssl/private/bcfg2client.key
ca = /etc/ssl/certs/bcfg2ca.crt
{% end %}\
{% end %}\

As a client will not be able to authenticate with certificates it does not yet possess we need to overcome the chicken and egg scenario the first time we try to connect such a client to the server. We can do so using password based auth to boot strap the client manually specifying all the relevant auth parameters like so:

bcfg2 -qv -S https://fqdn.of.bcfg2-server:6789 -u fqdn.of.client \
    -x SUPER_SECRET_PASSWORD

If all goes well the client should recieve a freshly generated key and cert and you should be able to run bcfg2 again without specifying the connection parameters.

If you do run into problems you may want to review Authentication.

TODO

  1. Add generation of pkcs12 format certs

Table Of Contents

Previous topic

SSHbase

Next topic

TCheetah

This Page