Repository : http://git.fedorahosted.org/git/?p=secure-coding.git
On branch : master
commit 95c297659e14411959ae36ae6a3a29a550c668c0 Author: Florian Weimer fweimer@redhat.com Date: Fri Apr 25 16:33:08 2014 +0200
RPM packaging: X.509 key pair generation
defensive-coding/en-US/Defensive_Coding.xml | 1 + defensive-coding/en-US/Tasks-Packaging.xml | 131 +++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 0 deletions(-)
diff --git a/defensive-coding/en-US/Defensive_Coding.xml b/defensive-coding/en-US/Defensive_Coding.xml index b8ca3de..7ca3f46 100644 --- a/defensive-coding/en-US/Defensive_Coding.xml +++ b/defensive-coding/en-US/Defensive_Coding.xml @@ -18,6 +18,7 @@ <xi:include href="Tasks-Processes.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> <xi:include href="Tasks-Serialization.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> <xi:include href="Tasks-Cryptography.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> + <xi:include href="Tasks-Packaging.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> </part> <part> <title>Implementing Security Features</title> diff --git a/defensive-coding/en-US/Tasks-Packaging.xml b/defensive-coding/en-US/Tasks-Packaging.xml new file mode 100644 index 0000000..95bfbc6 --- /dev/null +++ b/defensive-coding/en-US/Tasks-Packaging.xml @@ -0,0 +1,131 @@ +<?xml version='1.0' encoding='utf-8' ?> +<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ +]> +<chapter id="chap-Defensive_Coding-Tasks-Packaging"> + <title>RPM packaging</title> + <para> + This chapter deals with security-related concerns around RPM + packaging. It has to be read in conjunction with + distribution-specific packaging guidelines. + </para> + <section id="sect-Defensive_Coding-Tasks-Packaging-Certificates"> + <title>Generating X.509 self-signed certificates during + installation</title> + <para> + Some applications need X.509 certificates for authentication + purposes. For example, a single private/public key pair could + be used to define cluster membership, enabling authentication + and encryption of all intra-cluster communication. (Lack of + certification from a CA matters less in such a context.) For + such use, generating the key pair at package installation time + when preparing system images for use in the cluster is + reasonable. For other use cases, it is necessary to generate + the key pair before the service is started for the first time. + </para> + <important> + <para> + The way the key is generated may not be suitable for key + material of critical value. (<command>openssl + genrsa</command> uses, but does not require, entropy from a + physical source of randomness, among other things.) Such keys + should be stored in a hardware security module if possible, + and generated from random bits reserved for this purpose + derived from a non-deterministic physical source. + </para> + </important> + <para> + In the spec file, we define two RPM variables which contain the + names of the files used to store the private and public key, and + the user name for the service: + </para> + <informalexample> + <programlisting language="RPM Spec"> +# Name of the user owning the file with the private key +%define tlsuser %{name} +# Name of the directory which contains the key and certificate files +%define tlsdir %{_sysconfdir}/%{name} +%define tlskey %{tlsdir}/%{name}.key +%define tlscert %{tlsdir}/%{name}.crt + </programlisting> + </informalexample> + <para> + These variables likely need adjustment based on the needs of the + package. + </para> + <para> + Typically, the file with the private key needs to be owned by + the system user which needs to read it, + <literal>%{tlsuser}</literal> (not <literal>root</literal>). In + order to avoid races, if the <emphasis>directory</emphasis> + <literal>%{tlsdir}</literal> is <emphasis>owned by the services + user</emphasis>, you should use the code in <xref + linkend="ex-Defensive_Coding-Packaging-Certificates-Owned"/>. + The invocation of <application>su</application> with the + <option>-s /bin/bash</option> argument is necessary in case the + login shell for the user has been disabled. + </para> + <example id="ex-Defensive_Coding-Packaging-Certificates-Owned"> + <title>Creating a key pair in a user-owned directory</title> + <programlisting language="Bash"> +%post +if [ $1 -eq 1 ] ; then + if ! test -e %{tlskey} ; then + su -s /bin/bash \ + -c "umask 077 && openssl genrsa -out %{tlskey} 2048 2>/dev/null" \ + %{tlsuser} + fi + if ! test -e %{tlscert} ; then + cn="Automatically generated certificate for the %{tlsuser} service" + req_args="-key %{tlskey} -out %{tlscert} -days 7305 -subj "/CN=$cn/"" + su -s /bin/bash \ + -c "openssl req -new -x509 -extensions usr_cert $req_args" \ + %{tlsuser} + fi +fi + +%files +%dir %attr(0755,%{tlsuser},%{tlsuser]) %{tlsdir} +%ghost %attr(0600,%{tlsuser},%{tlsuser}) %{tlskey} +%ghost %attr(0644,%{tlsuser},%{tlsuser}) %{tlscert} + </programlisting> + </example> + <para> + If the <emphasis>directory</emphasis> + <literal>%{tlsdir}</literal> <emphasis>is owned by</emphasis> + <literal>root</literal>, use the code in <xref + linkend="ex-Defensive_Coding-Packaging-Certificates-Unowned"/>. + </para> + <example id="ex-Defensive_Coding-Packaging-Certificates-Unowned"> + <title>Creating a key pair in a <literal>root</literal>-owned directory</title> + <programlisting language="Bash"> +%post +if [ $1 -eq 1 ] ; then + if ! test -e %{tlskey} ; then + (umask 077 && openssl genrsa -out %{tlskey} 2048 2>/dev/null) + chown %{tlsuser} %{tlskey} + fi + if ! test -e %{tlscert} ; then + cn="Automatically generated certificate for the %{tlsuser} service" + openssl req -new -x509 -extensions usr_cert \ + -key %{tlskey} -out %{tlscert} -days 7305 -subj "/CN=$cn/" + fi +fi + +%files +%dir %attr(0755,%{root},%{root}]) %{tlsdir} +%ghost %attr(0600,%{tlsuser},%{tlsuser}) %{tlskey} +%ghost %attr(0644,%{root},%{root}) %{tlscert} + </programlisting> + </example> + <para> + In order for this to work, the package which generates the keys + must require the <application>openssl</application> package. If + the user which owns the key file is generated by a different + package, the package generating the certificate must specify a + <literal>Requires(pre):</literal> on the package which creates + the user. This ensures that the user account will exist when it + is needed for the <application>su</application> or + <application>chmod</application> invocation. + </para> + </section> +</chapter>
On Fri, Apr 25, 2014 at 02:33:43PM +0000, fweimer@fedoraproject.org wrote:
- if ! test -e %{tlscert} ; then
- cn="Automatically generated certificate for the %{tlsuser} service"
- openssl req -new -x509 -extensions usr_cert \
-key %{tlskey} -out %{tlscert} -days 7305 -subj "/CN=$cn/"
We also pass here:
-serial $RANDOM -sha256
in the mod_ssl %post, possibly recommend these also? We had a couple of user complaints when the serial number wasn't set; not a big issue but simple to work around.
I'm not sure whether current OpenSSL is using a SHA256 hash by default already, that part might be redundant.
Regards, Joe
----- Original Message -----
From: "Joe Orton" jorton@redhat.com To: security@lists.fedoraproject.org Sent: Monday, 28 April, 2014 10:39:09 AM Subject: Re: [Secure Coding] master: RPM packaging: X.509 key pair generation (95c2976)
On Fri, Apr 25, 2014 at 02:33:43PM +0000, fweimer@fedoraproject.org wrote:
- if ! test -e %{tlscert} ; then
- cn="Automatically generated certificate for the %{tlsuser} service"
- openssl req -new -x509 -extensions usr_cert \
-key %{tlskey} -out %{tlscert} -days 7305 -subj "/CN=$cn/"
We also pass here:
-serial $RANDOM -sha256
in the mod_ssl %post, possibly recommend these also? We had a couple of user complaints when the serial number wasn't set; not a big issue but simple to work around.
I'm not sure whether current OpenSSL is using a SHA256 hash by default already, that part might be redundant.
It should use SHA256 be default, but that's irrelevant for self signed certificates. They have the same threat model as CA trust anchors, either you trust them as is or you don't, the signature is essentially just a checksum.
security@lists.fedoraproject.org