#1 Generate SSL keys on service start
Merged 6 years ago by jorton. Opened 6 years ago by sgallagh.
rpms/ sgallagh/httpd sscg  into  master

file added
+12
@@ -0,0 +1,12 @@ 

+ [Unit]

+ Description=One-time configuration for httpd.service

+ 

+ ConditionPathExists=|!/etc/pki/tls/certs/localhost.crt

+ ConditionPathExists=|!/etc/pki/tls/certs/localhost-ca.crt

+ ConditionPathExists=|!/etc/pki/tls/private/localhost.key

+ 

+ [Service]

+ Type=oneshot

+ RemainAfterExit=no

+ 

+ ExecStart=/usr/libexec/httpd-ssl-gencerts

file added
+24
@@ -0,0 +1,24 @@ 

+ #!/usr/bin/bash

+ 

+ set -e

+ 

+ FQDN=`hostname`

+ # A >59 char FQDN means "root@FQDN" exceeds 64-char max length for emailAddress

+ if [ "x${FQDN}" = "x" -o ${#FQDN} -gt 59 ]; then

+    FQDN=localhost.localdomain

+ fi

+ 

+ sscg -q                                                             \

+      --cert-file           /etc/pki/tls/certs/localhost.crt         \

+      --cert-key-file       /etc/pki/tls/private/localhost.key       \

+      --ca-file             /etc/pki/tls/certs/localhost-ca.crt      \

+      --hash-alg            sha256                                   \

+      --key-strength        2048                                     \

Can we omit this and rely on sscg having good defaults? If we have to update 1 rather than N packages as minimum key size defaults evolve over time that's a massive benefit overall IMO.

+      --lifetime            365                                      \

+      --country             "--"                                     \

+      --state               SomeState                                \

+      --locality            SomeCity                                 \

+      --organization        SomeOrganization                         \

+      --organizational-unit SomeOrganizationalUnit                   \

+      --hostname            $FQDN                                    \

+      --email               root@$FQDN

file modified
+2 -1
@@ -13,7 +13,8 @@ 

  

  [Unit]

  Description=The Apache HTTP Server

- After=network.target remote-fs.target nss-lookup.target

+ Wants=httpd-init.service

+ After=network.target remote-fs.target nss-lookup.target httpd-init.service

  Documentation=man:httpd.service(8)

  

  [Service]

file modified
+16 -33
@@ -13,7 +13,7 @@ 

  Summary: Apache HTTP Server

  Name: httpd

  Version: 2.4.27

- Release: 8%{?dist}

+ Release: 8.4%{?dist}

  URL: https://httpd.apache.org/

  Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2

  Source1: index.html
@@ -48,6 +48,8 @@ 

  Source32: httpd.service.xml

  Source40: htcacheclean.service

  Source41: htcacheclean.sysconf

+ Source42: httpd-init.service

+ Source43: httpd-ssl-gencerts

  # build/scripts patches

  Patch1: httpd-2.4.1-apctl.patch

  Patch2: httpd-2.4.9-apxs.patch
@@ -155,6 +157,7 @@ 

  Requires(post): openssl, /bin/cat, hostname

  Requires(pre): httpd-filesystem

  Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}

+ Requires: sscg >= 2.1.0

  Obsoletes: stronghold-mod_ssl

  # Require an OpenSSL which supports PROFILE=SYSTEM

  Conflicts: openssl-libs < 1:1.0.1h-4
@@ -303,7 +306,7 @@ 

  

  # Install systemd service files

  mkdir -p $RPM_BUILD_ROOT%{_unitdir}

- for s in httpd.service htcacheclean.service httpd.socket; do

+ for s in httpd.service htcacheclean.service httpd.socket httpd-init.service; do

    install -p -m 644 $RPM_SOURCE_DIR/${s} \

                      $RPM_BUILD_ROOT%{_unitdir}/${s}

  done
@@ -432,6 +435,10 @@ 

  install -m755 $RPM_SOURCE_DIR/httpd-ssl-pass-dialog \

  	$RPM_BUILD_ROOT%{_libexecdir}/httpd-ssl-pass-dialog

  

+ # install http-ssl-gencerts

+ install -m755 $RPM_SOURCE_DIR/httpd-ssl-gencerts \

+ 	$RPM_BUILD_ROOT%{_libexecdir}/httpd-ssl-gencerts

+ 

  # Install action scripts

  mkdir -p $RPM_BUILD_ROOT%{_libexecdir}/initscripts/legacy-actions/httpd

  for f in graceful configtest; do
@@ -511,36 +518,6 @@ 

  test -f /etc/sysconfig/httpd-disable-posttrans || \

    /bin/systemctl try-restart httpd.service htcacheclean.service >/dev/null 2>&1 || :

  

- %define sslcert %{_sysconfdir}/pki/tls/certs/localhost.crt

- %define sslkey %{_sysconfdir}/pki/tls/private/localhost.key

- 

- %post -n mod_ssl

- umask 077

- 

- if [ -f %{sslkey} -o -f %{sslcert} ]; then

-    exit 0

- fi

- 

- %{_bindir}/openssl genrsa -rand /proc/apm:/proc/cpuinfo:/proc/dma:/proc/filesystems:/proc/interrupts:/proc/ioports:/proc/pci:/proc/rtc:/proc/uptime 2048 > %{sslkey} 2> /dev/null

- 

- FQDN=`hostname`

- # A >59 char FQDN means "root@FQDN" exceeds 64-char max length for emailAddress

- if [ "x${FQDN}" = "x" -o ${#FQDN} -gt 59 ]; then

-    FQDN=localhost.localdomain

- fi

- 

- cat << EOF | %{_bindir}/openssl req -new -key %{sslkey} \

-          -x509 -sha256 -days 365 -set_serial $RANDOM -extensions v3_req \

-          -out %{sslcert} 2>/dev/null

- --

- SomeState

- SomeCity

- SomeOrganization

- SomeOrganizationalUnit

- ${FQDN}

- root@${FQDN}

- EOF

- 

  %check

  # Check the built modules are all PIC

  if readelf -d $RPM_BUILD_ROOT%{_libdir}/httpd/modules/*.so | grep TEXTREL; then
@@ -640,7 +617,8 @@ 

  

  %{_mandir}/man8/*

  

- %{_unitdir}/*.service

+ %{_unitdir}/httpd.service

+ %{_unitdir}/htcacheclean.service

  %{_unitdir}/*.socket

  

  %files filesystem
@@ -674,7 +652,9 @@ 

  %config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/00-ssl.conf

  %config(noreplace) %{_sysconfdir}/httpd/conf.d/ssl.conf

  %attr(0700,apache,root) %dir %{_localstatedir}/cache/httpd/ssl

+ %{_unitdir}/httpd-init.service

  %{_libexecdir}/httpd-ssl-pass-dialog

+ %{_libexecdir}/httpd-ssl-gencerts

  %{_unitdir}/httpd.socket.d/10-listen443.conf

  

  %files -n mod_proxy_html
@@ -705,6 +685,9 @@ 

  %{_rpmconfigdir}/macros.d/macros.httpd

  

  %changelog

+ * Wed Sep 20 2017 Stephen Gallagher <sgallagh@redhat.com> - 2.4.27-8.1

+ - Generate SSL certificates on service start, not %posttrans

+ 

  * Tue Sep 19 2017 Joe Orton <jorton@redhat.com> - 2.4.27-8

  - move httpd.service.d, httpd.socket.d dirs to -filesystem

  

file modified
+1 -1
@@ -122,7 +122,7 @@ 

  #   Set the CA certificate verification path where to find CA

  #   certificates for client authentication or alternatively one

  #   huge file containing all of them (file must be PEM encoded)

- #SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt

+ SSLCACertificateFile /etc/pki/tls/certs/localhost-ca.crt

  

  #   Client Authentication (Type):

  #   Client certificate verification type and depth.  Types are

This defers the creation of self-signed SSL certificates to the
first time that httpd starts up. This has several advantages:

  • Waiting until the first boot will help avoid some issues with
    limited entropy in the install process.
  • The certificates can be regenerated automatically whenever they
    are removed, which helps with tools such as virt-sysprep
  • The certificates are now generated by SSCG, which produces a
    limited-trust CA alongside it that can be safely imported by a
    client.

For more information on SSCG, see:
https://sgallagh.wordpress.com/2016/05/02/self-signed-ssltls-certificates-why-they-are-terrible-and-a-better-alternative/

Signed-off-by: Stephen Gallagher sgallagh@redhat.com

Can we omit this and rely on sscg having good defaults? If we have to update 1 rather than N packages as minimum key size defaults evolve over time that's a massive benefit overall IMO.

^ above should apply to hash algorithm too.

This is awesome Stephen, thanks a lot for doing this!

@jorton We can absolutely rely on sscg's defaults (in fact, they happen to be exactly the explicit values specified here). I mostly wrote it explicitly to make sure I wasn't changing anything from the existing approach in case there were specific reasons they had to be exactly that.

Similarly, we have functional defaults for the Subject (though these at least are different from what you were using). If run with no arguments, it produces a Subject like C = US, O = Unspecified, CN = sgallaghp50.sgallagh.rht where the CN is retrieved from the hostname.

So if you wanted me to switch to all defaults, it would basically look like:

sscg -q                                                             \
     --cert-file           /etc/pki/tls/certs/localhost.crt         \
     --cert-key-file       /etc/pki/tls/private/localhost.key       \
     --ca-file             /etc/pki/tls/certs/localhost-ca.crt      \
     --lifetime            365                                      \
     --email               root@$FQDN

Pull-Request has been merged by jorton

6 years ago