From Fedora Project Wiki
(→‎Common Guidelines: Complete rewrite)
(Major rewrite)
Line 91: Line 91:
If your service makes use of the SSL/TLS protocol for transport security, your service will require a service certificate. Ideally the administrator deploying a new service should obtain an X.509 certificate from an appropriate Certificate Authority (CA), which should be from a globally operating CA (such as a commercial SSL certificate vendor) if your service will be available on the public Internet, or from a private CA (such as a domain controller CA) if your service will run inside an Intranet.
If your service makes use of the SSL/TLS protocol for transport security, your service will require a service certificate. Ideally the administrator deploying a new service should obtain an X.509 certificate from an appropriate Certificate Authority (CA), which should be from a globally operating CA (such as a commercial SSL certificate vendor) if your service will be available on the public Internet, or from a private CA (such as a domain controller CA) if your service will run inside an Intranet.


However, it is often desirable to start using a self-signed certificate, which can be immediately created, and allows the administrator to immediately proceed doing the installation tasks. This document will explain how to obtain a self-signed certificate, but it is recommended that it gets replaced prior to deployment.
However, it is often desirable to start using a self-signed certificate, which can be immediately created, and allows the administrator to immediately proceed doing the installation tasks. This document will explain how to obtain a self-signed certificate, but it is recommended that it gets replaced prior to public deployment.


The disadvantage of self-signed certificates is that most client software (like web browsers) will reject them as untrusted, and if at all, will require the user to override and trust it explicitly. The way this can be done varies depending on the client software. It is easier to add a CA certificate to the system store and mark it as trusted.
The disadvantage of self-signed certificates is that most client software (like web browsers) will reject them as untrusted, and if at all, will require the user to override and trust it explicitly. The way this can be done varies depending on the client software. It is easier to add a CA certificate to the system store and mark it as trusted.
Line 97: Line 97:
Therefore, instead of creating a self-signed certificate, we will create a temporary CA certificate and use it to sign the certificate used by the service. Afterwards we will delete the private key of the CA certificate, which will remove the ability to use it to create additional certificates. Afterwards we can import the CA certificate as trusted into the local system certificate store, and consequently every local client software that respects the system CA store will accept the service certificate as trusted.
Therefore, instead of creating a self-signed certificate, we will create a temporary CA certificate and use it to sign the certificate used by the service. Afterwards we will delete the private key of the CA certificate, which will remove the ability to use it to create additional certificates. Afterwards we can import the CA certificate as trusted into the local system certificate store, and consequently every local client software that respects the system CA store will accept the service certificate as trusted.


=== OpenSSL and PEM Certificates ===
=== Easy implementation with sscg ===


This tutorial will provide the steps to produce something akin to a self-signed certificate, except that the resulting service certificate cannot be used to sign further certificates (thus closing a potential security issue). In broad terms, what we are doing is creating a short-lived certificate authority, using that to sign a service certificate and then destroying the key material for the temporary authority.
There is a simple tool in Fedora called sscg (Self-Signed Certificate Generator) that will create a certificate using the above mechanism for you. See the tog-pegasus example above for a simple invocation.


(Note: for any instance of <code>$package</code> below, substitute the name of your package)
==== Create Short-Lived Certificate Authority ====
First, create an OpenSSL configuration file for the CA certificate. It should be similar to this:
<pre>
[ req ]
distinguished_name    = req_distinguished_name
prompt                = no
x509_extensions        = v3_ca
[ req_distinguished_name ]
C                      = --
ST                    = SomeState
L                      = SomeCity
O                      = Private CA for $package on <real_fqdn> at <date> UTC
OU                    = $package
CN                    = $package.<real_fqdn>
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = CA:TRUE
</pre>
Most of the organizational values above can be changed, but CN must be <code>$package.<real_fqdn></code>. Additionally, the Organization (O) field should remain as in the example so that it provides clues to administrators who may wish to import the public CA certificate. The date field should match the output of <code>date -u +'%Y-%m-%d %H:%M:%S'</code>
Create this file with the name <code>$package-ssl-ca.cnf</code> in a location owned by your package. You may retain or destroy this file later as you prefer.
Next, we will generate the private key for this temporary Certificate Authority. '''Set the umask so that only root/owner can read the files we create'''. Then create the key file with the <code>openssl</code> command. We will create the temporary key file in <code>/dev/shm</code> so that it is unlikely to ever be written to persistent media.
<pre>
OLDUMASK=`umask`
umask 0077
TMPKEY=`mktemp --tmpdir=/dev/shm XXXXXXXXXXXX`
/usr/bin/openssl genrsa -out $TMPKEY 2048
</pre>
Note: it is *highly* recommended to use a 2048-bit or greater key. Any package that is not compatible with 2048-bit keys should have a bug open to track this shortcoming.
Next, we will use this private key to create the temporary CA Certificate:
<pre>
/usr/bin/openssl req -new -x509 -days 3650 -sha256 \
                    -config /path/to/$package-ssl-ca.cnf \
                    -key $TMPKEY \
                    -out /path/to/$package-ssl-ca.crt
</pre>
You can adjust the value of -days as you prefer. Store the <code>$package-ssl-ca.crt</code> file in the same location as the <code>$package-ssl-ca.cnf</code>. Now we have a certificate authority available to sign our service certificate.
==== Create and Sign a Service Certificate ====
Similar to the CA certificate generation, we need to create an OpenSSL configuration file for the service certificate as below:
<pre>
[ req ]
distinguished_name    = req_distinguished_name
prompt                = no
req_extensions        = v3_req
[ req_distinguished_name ]
C                      = --
ST                    = SomeState
L                      = SomeCity
O                      = The Fedora Project
OU                    = $package
CN                    = <real FQDN>
[ v3_req ]
basicConstraints      = CA:FALSE
</pre>
Note the specific differences from the CA certificate configuration file: the <code>v3_ca</code> reference and section has been replaced by a <code>v3_req</code> section which asserts that this certificate is '''not''' a Certificate Authority (and cannot be used to sign other certificates). Also note that unlike the CA certificate, this configuration requires the CN to match the machine's real fully-qualified hostname. If you do not provide this, clients will be unable to validate this machine's certificate.
Save this file as <code>$package-ssl-service.cnf</code> in the same location as the CA configuration. As with that configuration, this file can be removed after processing is complete.
Next, we will generate a secure private key for the service certificate. This key '''must''' be retained and provided in the location that the service expects it for SSL to function properly. Substitute the correct location for your package below:
<pre>
/usr/bin/openssl genrsa -out /path/to/service/key 2048
</pre>
As above, this generates a 2048-bit key. This should be considered the recommended minimum key strength. If a package does not support 2048-bit or higher keys, a bug should be opened.
Next, we will create a signing request for this key and sign it with our temporary CA.
<pre>
/usr/bin/openssl req -new \
                    -config /path/to/$package-ssl-service.cnf \
                    -key /path/to/service/key \
                    -out /path/to/$package-ssl.csr
/usr/bin/openssl x509 -req -days 3650 -sha256 \
                      -in /path/to/$package-ssl.csr \
                      -CA /path/to/$package-ssl-ca.crt \
                      -CAkey $TMPKEY \
                      -CAcreateserial \
                      -set_serial 0x`/usr/bin/openssl rand -hex 8` \
                      -out /path/to/service/certificate \
                      -extfile /path/to/$package-ssl-ca.cnf
</pre>
'''Carefully note the "-ca" suffixes there'''; it can be tricky to see where to use the CA certificate information vs. the service certificate information.
The last step is to clean up the resulting files, as they are all owned by root with restrictive permissions:
<pre>
# Delete the temporary CA key so nothing else can be signed with it
# We'll also overwrite it with zeros before deleting it, just in case.
dd if=/dev/zero of=$TMPKEY bs=1k count=16
rm -f $TMPKEY
# Optionally delete unneeded CSR and the OpenSSL Configuration Files
rm -f /path/to/$package-ssl.csr \
      /path/to/$package-ssl-ca.cnf \
      /path/to/$package-ssl-service.cnf
# Restore the original umask
umask $OLDUMASK
chown pkguser:pkguser /path/to/service/certificate \
                      /path/to/service/key
# Appropriate chmod() calls here
</pre>
As a final, optional step, the private temporary CA certificate can be added to the local root CA list so that requests from the local machine will be able to connect as trusted clients without having to skip validation (as would be normal for self-signed certificates). Unlike traditional self-signed certificates, since this temporary CA cannot be used to sign anything else, this does not open your system to a risk of the service certificate being used to falsely sign something.
<pre>
cp /path/to/$package-ssl-ca.crt /etc/pki/ca-trust/source/anchors/
update-ca-trust extract
</pre>
=== Mozilla NSS Certificate Database ===
==== Pre-requisites ====
First, you must decide whether your package will rely on the system database or a private package database for storing certificates and associated private keys.
The system database is located at <code>/etc/pki/nssdb/</code>. This database could be used if you want to share certificate information with other services on the system.
A private database should be used if you want to isolate the private keys used by your package's certificate from other services and users on the system.
If you decide to create a private database, you will need to create a directory to store that database. We will call that directory <code>NSSPATH</code> in this document.
<pre>
NSSPATH=/path/to/service/nss-database/directory
</pre>
It is highly recommended to use the modern NSS file format, which means that whenever NSS utilities require the database directory (dbdir) as a parameter, you should prefix the <code>NSSPATH</code> with <code>sql:</code> to request the modern file format. (The resulting files in the <code>NSSPATH</code> directory will be key4.db, cert9.db, pkcs11.txt.) This file format is based on sqlite, and it allows multiple applications to concurrently access the same NSSPATH (if desired). This means you may use the NSS command line tools to inspect <code>NSSPATH</code> while your service is running.
==== Initialization of the Database ====
If you are using a private database, you will need to initialize the <code>NSSPATH</code> database. If you are using the system database or another previously-existing database, you may skip to the next step.
You need to decide if you'd like a master password on the database that will protect the private keys stored in it. If your service is supposed to start up automatically, you probably don't want a password (equivalent to empty password).
Run:
<pre>
certutil -d sql:$NSSPATH -N --empty-password
</pre>
==== Create Short-Lived Certificate Authority ====
Next, we will create a temporary Certificate Authority that will be used to sign the service certificate. First, we will need to gather the identification text used to identify the CA certificate. This tutorial will use <code>BASH</code> syntax as an example, but it can be adapted as needed:
<pre>
<pre>
HOSTNAME=<system FQDN>
usage: sscg [-h] [--debug] [--cert-format {PEM,ASN1}] [--lifetime LIFETIME]
 
            [--key-strength {512,1024,2048,4096}]
PACKAGE_NAME=<insert appropriate value>
            [--hash-alg {md4,md5,ripemd160,sha,sha1,sha224,sha256,sha384,sha512,whirlpool}]
</pre>
            --package PACKAGE [--ca-file CA_FILE] --cert-file CERT_FILE
 
            --cert-key-file CERT_KEY_FILE [--hostname HOSTNAME]
HOSTNAME should be set to the fully qualified hostname, to ensure that client software that attempts to validate the service certificate won't complain about hostname mismatches.
            [--subject-alt-names SUBJECT_ALT_NAMES [SUBJECT_ALT_NAMES ...]]
 
            [--country COUNTRY] [--state STATE] [--locality LOCALITY]
We'll also include the service setup time in the CN, to minimize the risk that we'll ever create two certificates that have the same value of {name,serial-number} as that would cause issues for software verifying the certificates.
            [--organization ORGANIZATION]
<pre>
            [--organizational-unit ORGANIZATIONAL_UNIT]
CURRENT_TIME=`date -u +'%Y-%m-%d %H:%M:%S UTC'`
 
CA_CN="O=Private CA for $PACKAGE_NAME on $HOSTNAME created at $CURRENT_TIME"
 
CERT_CN="O=Administrator for $PACKAGE_NAME on $HOSTNAME, CN=$HOSTNAME"
</pre>


In an NSS database, a certificate is usually identified by a user-defined nickname. Set it to something that makes sense for your package.
Generate a self-signed service certificate


<pre>
optional arguments:
CA_NICKNAME=my-ca-cert-nickname
  -h, --help            show this help message and exit
CERT_NICKNAME=my-service-cert-nickname
  --debug              Enable logging of debug messages.
</pre>


The authors of this tutorial strongly recommend that any real certificate that is manually generated should have a much shorter valid lifetime. However, for automatically-generated certificates, we want to reduce the risk that they will expire too quickly, so we will set its lifetime to ten years.
Output:
<pre>
  --cert-format {PEM,ASN1}
VALIDITY_IN_MONTHS=120
                        Certificate file format. Default=PEM
</pre>
  --lifetime LIFETIME  Certificate lifetime (days). Default=3650 (10 years)
  --key-strength {512,1024,2048,4096}
                        Strength of the certificate private keys in bits.
                        Default=2048
  --hash-alg {md4,md5,ripemd160,sha,sha1,sha224,sha256,sha384,sha512,whirlpool}
                        Hashing algorithm to use for signing. Default=sha256
  --package PACKAGE    The name of the package needing a certificate
  --ca-file CA_FILE    Path where the public CA certificate will be stored.
                        Default: ca.crt in service certificate directory
  --cert-file CERT_FILE
                        Path where the public service certificate will be
                        stored.
  --cert-key-file CERT_KEY_FILE
                        Path where the private key of the service certificate
                        will be stored


In addition, we will generate a random serial number for the CA, and a value increased by one for the serial of the service cert.
Certificate Details:
 
  --hostname HOSTNAME  The valid hostname of the certificate. Must be an
<pre>
                        FQDN. Default: system hostname
CA_SERIAL=$RANDOM
  --subject-alt-names SUBJECT_ALT_NAMES [SUBJECT_ALT_NAMES ...]
CERT_SERIAL=$(($CA_SERIAL + 1))
                        One or more additional valid hostnames for the
</pre>
                        certificate
 
  --country COUNTRY    Certificate DN: Country (C)
We should use a certificate with a modern hash algorithm, let's use SHA256
  --state STATE        Certificate DN: State (ST)
<pre>
  --locality LOCALITY  Certificate DN: Locality (L)
HASH_ALG=SHA256
  --organization ORGANIZATION
</pre>
                        Certificate DN: Organization (O)
 
  --organizational-unit ORGANIZATIONAL_UNIT
We should use at least 2048 bits for the RSA key size:
                        Certificate DN: Organizational Unit (OU)
<pre>
KEY_SIZE=2048
</pre>
 
The certutil tool will by default block to interactively read keystrokes for seeding the random number generator. This isn't strictly necessary any more, because the NSS RNG is considered sufficiently good, however, the feature is still there by default. In order to prevent certutil from blocking, we must provide a file with some random data. Since the size isn't relevant, let's use /proc/uptime
<pre>
RANDOM_SEED_FILE=/proc/uptime
</pre>
 
The certutil tool will attempt to interactively read the choices for several parameters. In order to make it fully unattended, we must provide a file that can be passed to certutil to automatically read the choices from.
 
<pre>
CA_CU_IN=$NSSPATH/ca-input
CERT_CU_IN=$NSSPATH/cert-input
 
rm -f $CA_CU_IN
echo "y" > $CA_CU_IN
echo "1" >> $CA_CU_IN
echo "n" >> $CA_CU_IN
echo "3" >> $CA_CU_IN
echo "$HOSTNAME" >> $CA_CU_IN
echo "1" >> $CA_CU_IN
echo "n" >> $CA_CU_IN
echo "n" >> $CA_CU_IN
 
rm -f $CERT_CU_IN
echo "n" > $CERT_CU_IN
echo "" >> $CERT_CU_IN
echo "n" >> $CERT_CU_IN
</pre>
 
Now to actually create the CA we execute:
<pre>
certutil -d sql:$NSSPATH \
        -S -n "$CA_NICKNAME" \
        -s "$CA_CN" \
        -t C,C,C \
        -x -m $CA_SERIAL \
        -v $VALIDITY_IN_MONTHS \
        -Z $HASH_ALG \
        -g $KEY_SIZE \
        --extNC \
        -z $RANDOM_SEED_FILE \
        -2 < $CA_CU_IN
</pre>
 
Once the new certificate is created, you can optionally view it with
<pre>
certutil -d sql:$NSSPATH -L -n "$CA_NICKNAME"
</pre>
 
==== Create and Sign a Service Certificate ====
Now we need to generate (and at the same time, sign) a certificate for the package service to use. To create the certificate, run:
<pre>
certutil -d sql:$NSSPATH \
        -S -n "$CERT_NICKNAME" \
        -s "$CERT_CN" \
        -t ,, \
        -c "$CA_NICKNAME" \
        -m $CERT_SERIAL \
        -v $VALIDITY_IN_MONTHS \
        -Z $HASH_ALG \
        -g $KEY_SIZE \
        -z $RANDOM_SEED_FILE \
        -2 < $CERT_CU_IN
</pre>
 
Finally, we want to delete the private key of the CA certificate, to make it less likely that anyone can use this CA for any other purposes.
 
certutil doesn't offer a way to delete a private key directly (-F will also remove the associated certificate), so we must export the CA certificate without the key to a file, then delete it from the database, then import it back.
 
<pre>
CA_FILE=$NSSPATH/ca.pem
 
certutil -d sql:$NSSPATH -L -n "$CA_NICKNAME" -a > $CA_FILE
 
certutil -d sql:$NSSPATH -F -n "$CA_NICKNAME"
 
certutil -d sql:$NSSPATH -A -n "$CA_NICKNAME" -t C,C,C -a -i $CA_FILE
</pre>
 
You can verify that the service cert is indeed recognized as a valid TLS server cert by running:
<pre>
certutil -d sql:$NSSPATH -V -n "$CERT_NICKNAME" -u V
</pre>
 
As a final, optional step, the private temporary CA certificate can be added to the local root CA list so that requests from the local machine will be able to connect as trusted clients without having to skip validation (as would be normal for self-signed certificates). Unlike traditional self-signed certificates, since this temporary CA cannot be used to sign anything else, this does not open your system to a risk of the service certificate being used to falsely sign something.
 
<pre>
cp $CA_FILE /etc/pki/ca-trust/source/anchors/
update-ca-trust extract
</pre>
</pre>


== Open Questions ==
=== Do-it-yourself ===
# Should we change the Organization in the service certificate configuration examples? Kai Engert raises the following point: "I think the owner of the private key, and thus the one who is responsible for the actions that will be taken with that private key, isn't the fedora project... we're not making certificates for the package, but for a service instance"
[[Sgallagh:SelfSignedCertGuidelinesDraft|Guidelines for scripting openssl or nss]]
# Should we modify the CA certificate capabilities so that it is only permitted to sign certificates for the machine hostname (or sub-names thereof)? Kai Engert raised this question, Miloslav Trmac countered that since the signing key is short-lived, this is probably not urgent.
# Should we consider creation of a framework for runtime data (such as an empty database or log directory) to be "system-specific configuration"?. They may *become* populated with additional data that should be cleaned out before cloning, but the framework *itself* is not really system-specific.
# What do we do if the machine's hostname is "localhost" or "localhost.localdomain" or similar? This could cause issues with validation.

Revision as of 16:14, 10 July 2015

This page is a DRAFT and is currently under development

First-time Service Setup

Many system services require some amount of initial setup before they can run properly for the first time. Common examples are the generation of private keys and certificates or a unique, system-specific identifier.

Traditionally, this was done by RPM scriptlets as part of the installation or upgrade of a package. This was sensible for a time when the majority of installations were performed by attended or unattended installers (such as anaconda and kickstart).

Today we see an increased reliance on generating virtual machine images for use in both traditional and cloud-computing environments. In those cases, having system-specific data created at package installation time is problematic. It means that the production of such images need to have significant care applied to remove any system-specific information about them and then additional tools written to apply the corrected information post-deployment. The goal of this guideline is to ensure that if a system clean-up service such as virt-sysprep is run on the system and then the machine is rebooted, any service that requires first-time configuration will re-run it. The mechanism by which we will accomplish this is to remove such first-time configuration from RPM scriptlets (e.g. %post) and instead execute this configuration as part of service startup with systemd.

This guideline describes a mechanism that can be used for both traditional and cloud-based deployment styles.

Note: this requirement can be waived if the equivalent functionality is incorporated as part of the service's own standard startup. These guidelines are meant to address services that require setup before the service can be started.

Defining System-Specific Setup

A particular setup task is defined thusly: "Any action that must be performed on the system where the service will be run whose output is not identical for all systems running that service."

Some non-exhaustive examples of system-specific configuration:

  • The SSH daemon generates a public/private host key
  • The mod_ssl httpd module creates a self-signed certificate for the machine's hostname
  • A remote logging service creates a UUID to represent this machine

A few examples that should not be considered system-specific configuration:

  • Creating a service user and/or group. This is safe to copy to clones of the system.
  • Any content that is automatically re-generated by the service upon deletion.

Common Guidelines

For all system-specific cases, we will take advantage of systemd's service functionality. Packagers will create a new service unit file for each service unit in their package that requires per-system configuration. This service unit will be named <servicename>-init.service and installed to /usr/lib/systemd/system. For example, the tog-pegasus.service configuration unit would be /usr/lib/systemd/tog-pegasus-init.service.

The contents of this service unit will be as follows:

[Unit]
Description=One-time configuration for <servicename>

ConditionPathExists=!/path/to/generated/config
ConditionPathExists=|!/path/to/other/generated/config (one or more lines optional)

[Service]
Type=oneshot
RemainAfterExit=no

ExecStart=/path/to/config/script

The syntax for ConditionPathExists= uses the ! to indicate negation (the file is not present). The | is used to create an OR logical pairing (resulting in the lack of ANY of these files causing the configuration to be run).

To use tog-pegasus.service as an example:

[Unit]
Description=One-time configuration for <servicename>

ConditionPathExists=!/etc/Pegasus/server.pem
ConditionPathExists=|!/etc/Pegasus/file.pem
ConditionPathExists=|!/etc/Pegasus/client.pem

[Service]
Type=oneshot
RemainAfterExit=no

ExecStart=/usr/bin/sscg --package tog-pegasus --ca-file client.pem --cert-file server.pem --cert-key-file file.pem

The ExecStart command may do anything, so long as it returns 0 on success. In this case, we are generating a self-signed certificate for the service to use.

Packagers will also need to update their primary service unit to require this one and run after it:

[Unit]
...
Requires=<service>-init.service
After=<service>-init.service

To continue the tog-pegasus.service example:

[Unit]
Description=OpenPegasus CIM Server
After=syslog.target slpd.service

Requires=tog-pegasus-init.service
After=tog-pegasus-init.service

[Service]
Type=forking
ExecStart=/usr/sbin/cimserver
PIDFile=/var/run/tog-pegasus/cimserver.pid

[Install]
WantedBy=multi-user.target

Special Case: Self-signed Certificate Generation

If your service makes use of the SSL/TLS protocol for transport security, your service will require a service certificate. Ideally the administrator deploying a new service should obtain an X.509 certificate from an appropriate Certificate Authority (CA), which should be from a globally operating CA (such as a commercial SSL certificate vendor) if your service will be available on the public Internet, or from a private CA (such as a domain controller CA) if your service will run inside an Intranet.

However, it is often desirable to start using a self-signed certificate, which can be immediately created, and allows the administrator to immediately proceed doing the installation tasks. This document will explain how to obtain a self-signed certificate, but it is recommended that it gets replaced prior to public deployment.

The disadvantage of self-signed certificates is that most client software (like web browsers) will reject them as untrusted, and if at all, will require the user to override and trust it explicitly. The way this can be done varies depending on the client software. It is easier to add a CA certificate to the system store and mark it as trusted.

Therefore, instead of creating a self-signed certificate, we will create a temporary CA certificate and use it to sign the certificate used by the service. Afterwards we will delete the private key of the CA certificate, which will remove the ability to use it to create additional certificates. Afterwards we can import the CA certificate as trusted into the local system certificate store, and consequently every local client software that respects the system CA store will accept the service certificate as trusted.

Easy implementation with sscg

There is a simple tool in Fedora called sscg (Self-Signed Certificate Generator) that will create a certificate using the above mechanism for you. See the tog-pegasus example above for a simple invocation.

usage: sscg [-h] [--debug] [--cert-format {PEM,ASN1}] [--lifetime LIFETIME]
            [--key-strength {512,1024,2048,4096}]
            [--hash-alg {md4,md5,ripemd160,sha,sha1,sha224,sha256,sha384,sha512,whirlpool}]
            --package PACKAGE [--ca-file CA_FILE] --cert-file CERT_FILE
            --cert-key-file CERT_KEY_FILE [--hostname HOSTNAME]
            [--subject-alt-names SUBJECT_ALT_NAMES [SUBJECT_ALT_NAMES ...]]
            [--country COUNTRY] [--state STATE] [--locality LOCALITY]
            [--organization ORGANIZATION]
            [--organizational-unit ORGANIZATIONAL_UNIT]

Generate a self-signed service certificate

optional arguments:
  -h, --help            show this help message and exit
  --debug               Enable logging of debug messages.

Output:
  --cert-format {PEM,ASN1}
                        Certificate file format. Default=PEM
  --lifetime LIFETIME   Certificate lifetime (days). Default=3650 (10 years)
  --key-strength {512,1024,2048,4096}
                        Strength of the certificate private keys in bits.
                        Default=2048
  --hash-alg {md4,md5,ripemd160,sha,sha1,sha224,sha256,sha384,sha512,whirlpool}
                        Hashing algorithm to use for signing. Default=sha256
  --package PACKAGE     The name of the package needing a certificate
  --ca-file CA_FILE     Path where the public CA certificate will be stored.
                        Default: ca.crt in service certificate directory
  --cert-file CERT_FILE
                        Path where the public service certificate will be
                        stored.
  --cert-key-file CERT_KEY_FILE
                        Path where the private key of the service certificate
                        will be stored

Certificate Details:
  --hostname HOSTNAME   The valid hostname of the certificate. Must be an
                        FQDN. Default: system hostname
  --subject-alt-names SUBJECT_ALT_NAMES [SUBJECT_ALT_NAMES ...]
                        One or more additional valid hostnames for the
                        certificate
  --country COUNTRY     Certificate DN: Country (C)
  --state STATE         Certificate DN: State (ST)
  --locality LOCALITY   Certificate DN: Locality (L)
  --organization ORGANIZATION
                        Certificate DN: Organization (O)
  --organizational-unit ORGANIZATIONAL_UNIT
                        Certificate DN: Organizational Unit (OU)

Do-it-yourself

Guidelines for scripting openssl or nss