From f87608d151827dac1b032fd675b77d721bc6e7a0 Mon Sep 17 00:00:00 2001 From: Paul Belanger Date: Wed, 14 Jun 2017 11:51:56 -0400 Subject: [PATCH] Add CA service to puppetmaster.o.o for zuul We want to start encrypting our gearman traffic for zuulv3, as such we'll need to bring online a CA service. The idea here, is we create a new CA for each interconnecting service we want SSL certs for. As an example /etc/zuul-ca will be used to generate SSL certs for our gearman service. Change-Id: I8c341559292c78d5428fe16837f28494a76e65db Signed-off-by: Paul Belanger Co-Authored-By: Jeremy Stanley --- doc/source/certificate_authority.rst | 258 ++++++++++++++++++ doc/source/systems.rst | 1 + .../files/puppetmaster/zuul_ca.cnf | 80 ++++++ .../manifests/puppetmaster.pp | 48 ++++ 4 files changed, 387 insertions(+) create mode 100644 doc/source/certificate_authority.rst create mode 100644 modules/openstack_project/files/puppetmaster/zuul_ca.cnf diff --git a/doc/source/certificate_authority.rst b/doc/source/certificate_authority.rst new file mode 100644 index 0000000000..e9b298d16d --- /dev/null +++ b/doc/source/certificate_authority.rst @@ -0,0 +1,258 @@ +:title: Certificate Authority + +.. _certificate_authority: + +Certificate Authority +##################### + +The certificate authority services used for signing SSL certs in +openstack-infra. + +At a Glance +=========== + +:Hosts: + * puppetmaster.openstack.org +:Projects: + * https://www.openssl.org/ +:Documentation: + * https://debian-administration.org/article/618/Certificate_Authority_CA_with_OpenSSL + +Overview +======== + +Today we have a single CA service setup on puppetmaster.o.o: + + /etc/zuul-ca + +This is used for generating SSL certificates needed by our CI systems. As we +need to create more SSL certificates for new services, we'll create additional +directories on puppetmaster.openstack.org, having multiple CA services. + +Generating a CA certificate +--------------------------- + +Below are the steps for create a new certificicate authority. Today we do this +on puppetmaster.openstack.org. Some important things to note, our pass phrase +for our cakey.pem file is stored in our GPG password.txt file. Additionally, by +default our cacert.pem file will only be valid for 3 years. + +*NOTE* In the example below we'll be using the /etc/zuul-ca folder on +puppetmaster.openstack.org. + +.. code-block:: bash + + root@puppetmaster:~# cd /etc/zuul-ca + root@puppetmaster:/etc/zuul-ca# env CN=zuulv3.openstack.org CATOP=. SSLEAY_CONFIG="-config ./openssl.cnf" /usr/lib/ssl/misc/CA.sh -newca + CA certificate filename (or enter to create) + + Making CA certificate ... + Generating a 2048 bit RSA private key + ...............................................................+++ + .......+++ + writing new private key to './private/./cakey.pem' + Enter PEM pass phrase:******************************** + Verifying - Enter PEM pass phrase:******************************** + ----- + Using configuration from ./openssl.cnf + Enter pass phrase for ./private/./cakey.pem:******************************** + Check that the request matches the signature + Signature ok + Certificate Details: + Serial Number: 15153659883634025817 (0xd24c9d606b17e559) + Validity + Not Before: Jun 14 15:22:14 2017 GMT + Not After : Jun 13 15:22:14 2020 GMT + Subject: + countryName = US + stateOrProvinceName = Texas + organizationName = OpenStack Foundation + organizationalUnitName = Infrastructure + commonName = zuulv3.openstack.org + emailAddress = openstack-infra@lists.openstack.org + X509v3 extensions: + X509v3 Subject Key Identifier: + 9B:FB:A2:07:32:9D:AE:D8:A5:95:FA:7A:D2:2E:14:CD:9E:66:4A:CF + X509v3 Authority Key Identifier: + keyid:9B:FB:A2:07:32:9D:AE:D8:A5:95:FA:7A:D2:2E:14:CD:9E:66:4A:CF + + X509v3 Basic Constraints: + CA:TRUE + Certificate is to be certified until Jun 13 15:22:14 2020 GMT (1095 days) + + Write out database with 1 new entries + Data Base Updated + +Generate a Cerfificate Request +------------------------------ + +Each service that requires a SSL certificate will need to first request a +certificate. Below we'll be create the private key for a gearman server. + +.. code-block:: bash + + root@puppetmaster:~# umask 077 + root@puppetmaster:~# cd /etc/zuul-ca + root@puppetmaster:/etc/zuul-ca# env CN=gearman.server CATOP=. SSLEAY_CONFIG="-config ./openssl.cnf" /usr/lib/ssl/misc/CA.sh -newreq-nodes + Generating a 2048 bit RSA private key + .......+++ + ....+++ + writing new private key to 'newreq.pem' + ----- + Request (and private key) is in newreq.pem + +Signing a Certificate Request +----------------------------- + +Next we need to sign the request from above, which creates the public +certificate for our service to run. By default SSL certificates are valid for 1 +year. + +.. code-block:: bash + + root@puppetmaster:~# cd /etc/zuul-ca + root@puppetmaster:/etc/zuul-ca# env CN=gearman.server CATOP=. SSLEAY_CONFIG="-config ./openssl.cnf" /usr/lib/ssl/misc/CA.sh -sign + Using configuration from ./openssl.cnf + Enter pass phrase for ./private/cakey.pem:******************************** + Check that the request matches the signature + Signature ok + Certificate Details: + Serial Number: 12264554420616840337 (0xaa347343e1504491) + Validity + Not Before: Jun 14 17:03:41 2017 GMT + Not After : Jun 14 17:03:41 2018 GMT + Subject: + countryName = US + stateOrProvinceName = Texas + localityName = Austin + organizationName = OpenStack Foundation + organizationalUnitName = Infrastructure + commonName = gearman.server + emailAddress = openstack-infra@lists.openstack.org + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 97:4B:C1:CA:32:35:6E:79:25:E3:5E:E7:11:9C:29:3F:14:01:EB:5E + X509v3 Authority Key Identifier: + keyid:BE:45:50:BB:4F:F5:94:80:E2:12:03:95:80:9E:14:19:ED:E5:C6:4E + + Certificate is to be certified until Jun 14 17:03:41 2018 GMT (365 days) + Sign the certificate? [y/n]:y + + + 1 out of 1 certificate requests certified, commit? [y/n]y + Write out database with 1 new entries + Data Base Updated + Certificate: + Data: + Version: 3 (0x2) + Serial Number: 12264554420616840337 (0xaa347343e1504491) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=CA, ST=Texas, O=OpenStack Foundation, OU=Infrastructure, CN=zuulv3.openstack.org/emailAddress=openstack-infra@lists.openstack.org + Validity + Not Before: Jun 14 17:03:41 2017 GMT + Not After : Jun 14 17:03:41 2018 GMT + Subject: C=US, ST=Texas, L=Austin, O=OpenStack Foundation, OU=Infrastructure, CN=gearman server/emailAddress=openstack-infra@lists.openstack.org + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:ce:60:21:c1:c8:89:db:e6:13:fb:51:77:0f:4c: + 3b:e3:35:5e:06:cf:57:5f:87:4a:61:df:61:1d:b9: + 44:75:d4:0b:9d:47:de:8b:b1:28:d6:fb:54:34:43: + 9a:96:09:28:aa:9d:c5:aa:80:cb:27:5a:11:4c:f8: + 14:8a:08:8a:aa:a8:7c:e5:e8:ab:0a:17:29:9c:15: + d7:2b:0b:46:f5:7a:2f:d1:75:68:30:fd:d4:10:18: + ef:86:76:04:6a:54:62:27:cd:c4:73:bb:7c:6a:fa: + 19:9c:31:09:f0:71:5e:af:32:35:df:03:96:5a:55: + b3:43:c7:de:f9:9f:85:e2:d5:fa:d2:08:b9:53:13: + 9f:b4:5f:e5:f6:2a:b5:40:f0:d8:f2:7a:60:d8:b1: + 65:0c:0c:18:1c:f6:bc:bd:64:d6:44:98:74:93:19: + 75:05:ef:5c:a8:94:e9:e5:9a:e7:c7:c4:8d:67:22: + 7a:9d:f0:17:df:74:27:72:cf:c1:81:71:73:fe:aa: + 5b:6c:74:4e:47:ef:29:11:52:b4:c8:8e:92:54:b4: + 53:db:9d:29:6b:ad:3a:40:a4:87:7c:ec:fd:d5:f2: + 39:5e:a4:26:2d:12:88:cd:62:56:11:bf:17:08:cb: + 76:93:6b:fd:7b:64:41:41:0c:f8:58:2a:fa:9f:25: + cc:0f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 97:4B:C1:CA:32:35:6E:79:25:E3:5E:E7:11:9C:29:3F:14:01:EB:5E + X509v3 Authority Key Identifier: + keyid:BE:45:50:BB:4F:F5:94:80:E2:12:03:95:80:9E:14:19:ED:E5:C6:4E + + Signature Algorithm: sha256WithRSAEncryption + 39:59:b2:db:a1:6d:b5:28:37:c6:9f:74:9a:3f:80:e1:4c:ac: + 9d:cd:26:06:86:7e:10:0c:0e:b2:96:94:57:37:0e:03:0f:f1: + 55:d5:13:f3:dd:8a:4f:3f:fa:fc:d3:d5:96:d3:cc:79:a9:a7: + 80:7f:a0:69:55:43:3f:d7:ab:b3:e9:c8:18:92:93:4c:75:cb: + d8:74:5a:70:7a:dc:79:9e:7f:70:b5:c1:39:c9:c7:a8:38:98: + 2f:5c:df:40:df:3f:69:8d:17:6e:2f:01:d0:ec:dc:3a:55:1d: + 9b:b3:0f:b5:5f:00:d2:8d:cf:d7:dc:5c:76:97:62:b3:ed:7e: + e4:51:59:a0:a0:a1:d7:d6:ec:93:ba:37:84:00:22:15:37:6c: + 3b:94:7e:b4:e1:7f:ef:eb:a7:37:99:19:ec:0f:cc:b2:2a:21: + 3f:44:37:bb:c1:36:4f:26:11:37:4f:0d:af:7f:84:4c:2f:6a: + bc:1f:49:d5:bf:da:c8:34:4e:aa:c1:d8:c9:9a:20:77:db:7e: + 33:ff:e9:f9:28:97:e8:47:92:13:f7:86:0d:65:eb:f4:a8:0b: + 4d:a1:ac:a4:43:68:84:4c:5c:46:61:6a:a2:32:b6:5b:d8:d6: + fe:f0:55:ee:08:8a:20:d0:c1:d5:40:7f:e5:ec:fb:c8:7b:13: + 01:83:c8:da + -----BEGIN CERTIFICATE----- + MIIEWzCCA0OgAwIBAgIJAKo0c0PhUESRMA0GCSqGSIb3DQEBCwUAMIGoMQswCQYD + VQQGEwJDQTEOMAwGA1UECAwFVGV4YXMxHTAbBgNVBAoMFE9wZW5TdGFjayBGb3Vu + ZGF0aW9uMRcwFQYDVQQLDA5JbmZyYXN0cnVjdHVyZTEdMBsGA1UEAwwUenV1bHYz + Lm9wZW5zdGFjay5vcmcxMjAwBgkqhkiG9w0BCQEWI29wZW5zdGFjay1pbmZyYUBs + aXN0cy5vcGVuc3RhY2sub3JnMB4XDTE3MDYxNDE3MDM0MVoXDTE4MDYxNDE3MDM0 + MVowgbMxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGQXVz + dGluMR0wGwYDVQQKDBRPcGVuU3RhY2sgRm91bmRhdGlvbjEXMBUGA1UECwwOSW5m + cmFzdHJ1Y3R1cmUxFzAVBgNVBAMMDmdlYXJtYW4gc2VydmVyMTIwMAYJKoZIhvcN + AQkBFiNvcGVuc3RhY2staW5mcmFAbGlzdHMub3BlbnN0YWNrLm9yZzCCASIwDQYJ + KoZIhvcNAQEBBQADggEPADCCAQoCggEBAM5gIcHIidvmE/tRdw9MO+M1XgbPV1+H + SmHfYR25RHXUC51H3ouxKNb7VDRDmpYJKKqdxaqAyydaEUz4FIoIiqqofOXoqwoX + KZwV1ysLRvV6L9F1aDD91BAY74Z2BGpUYifNxHO7fGr6GZwxCfBxXq8yNd8DllpV + s0PH3vmfheLV+tIIuVMTn7Rf5fYqtUDw2PJ6YNixZQwMGBz2vL1k1kSYdJMZdQXv + XKiU6eWa58fEjWciep3wF990J3LPwYFxc/6qW2x0TkfvKRFStMiOklS0U9udKWut + OkCkh3zs/dXyOV6kJi0SiM1iVhG/FwjLdpNr/XtkQUEM+Fgq+p8lzA8CAwEAAaN7 + MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQg + Q2VydGlmaWNhdGUwHQYDVR0OBBYEFJdLwcoyNW55JeNe5xGcKT8UAeteMB8GA1Ud + IwQYMBaAFL5FULtP9ZSA4hIDlYCeFBnt5cZOMA0GCSqGSIb3DQEBCwUAA4IBAQA5 + WbLboW21KDfGn3SaP4DhTKydzSYGhn4QDA6ylpRXNw4DD/FV1RPz3YpPP/r809WW + 08x5qaeAf6BpVUM/16uz6cgYkpNMdcvYdFpwetx5nn9wtcE5yceoOJgvXN9A3z9p + jRduLwHQ7Nw6VR2bsw+1XwDSjc/X3Fx2l2Kz7X7kUVmgoKHX1uyTujeEACIVN2w7 + lH604X/v66c3mRnsD8yyKiE/RDe7wTZPJhE3Tw2vf4RML2q8H0nVv9rINE6qwdjJ + miB3234z/+n5KJfoR5IT94YNZev0qAtNoaykQ2iETFxGYWqiMrZb2Nb+8FXuCIog + 0MHVQH/l7PvIexMBg8ja + -----END CERTIFICATE----- + Signed certificate is in newcert.pem + +Installing the Certificates +--------------------------- + +2 files will have been created, newcert.pem (public key) and newreq.pem (private +key). Be sure to use caution while transporting these files, specifcially +newreq.pem should be added into private hieradata for the specific server and +then deleted from disk. + +.. code-block:: bash + + root@puppetmaster:~# cd /etc/zuul-ca + root@puppetmaster:/etc/zuul-ca# /opt/system-config/production/tools/hieraedit.py \ + > --yaml /etc/puppet/hieradata/production/group/gearman.yaml \ + > -f newreq.pem gearman_ssl_key + root@puppetmaster:/etc/zuul-ca# /opt/system-config/production/tools/hieraedit.py \ + > --yaml /etc/puppet/hieradata/production/group/gearman.yaml \ + > -f newcert.pem gearman_ssl_cert + root@puppetmaster:/etc/zuul-ca# shred newreq.pem + root@puppetmaster:/etc/zuul-ca# rm newcert.pem newreq.pem + +**NOTE** Be sure to delete newcert.pem and newreq.pem from the top-level +directory once complete. This helps avoid leaking our private keys. + diff --git a/doc/source/systems.rst b/doc/source/systems.rst index 87b7167efb..1c4c669a40 100644 --- a/doc/source/systems.rst +++ b/doc/source/systems.rst @@ -7,6 +7,7 @@ Major Systems :maxdepth: 2 cacti + certificate_authority gerrit grafana grafyaml diff --git a/modules/openstack_project/files/puppetmaster/zuul_ca.cnf b/modules/openstack_project/files/puppetmaster/zuul_ca.cnf new file mode 100644 index 0000000000..87290fdbdd --- /dev/null +++ b/modules/openstack_project/files/puppetmaster/zuul_ca.cnf @@ -0,0 +1,80 @@ +# This file is managed by puppet. +# https://git.openstack.org/cgit/openstack-infra/system-config + +[ca] +default_ca = CA_default + +[CA_default] +dir = . +certs = $dir/certs +crl_dir = $dir/crl +database = $dir/index.txt +new_certs_dir = $dir/newcerts +certificate = $dir/cacert.pem +serial = $dir/serial +private_key = $dir/private/cakey.pem +RANDFILE = $dir/private/.rand +x509_extensions = usr_cert +name_opt = ca_default +cert_opt = ca_default +default_days = 3650 +default_md = default +preserve = no +policy = ca_policy + +[ca_policy] +countryName = supplied +stateOrProvinceName = supplied +localityName = supplied +organizationName = supplied +organizationalUnitName = supplied +commonName = supplied +emailAddress = supplied + +[policy_anything] +countryName = supplied +stateOrProvinceName = supplied +localityName = supplied +organizationName = supplied +organizationalUnitName = supplied +commonName = supplied +emailAddress = supplied + +[req] +default_bits = 2048 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +x509_extensions = v3_ca +string_mask = utf8only +prompt = no + +[req_distinguished_name] +C = US +ST = Texas +L = Austin +O = OpenStack Foundation +OU = Infrastructure +CN = $ENV::CN +emailAddress = openstack-infra@lists.openstack.org + +[usr_cert] +basicConstraints = CA:FALSE +nsComment = "client certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer + +[server] +basicConstraints = CA:FALSE +nsCertType = server +nsComment = "server certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer + +[v3_req] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[v3_ca] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = CA:true diff --git a/modules/openstack_project/manifests/puppetmaster.pp b/modules/openstack_project/manifests/puppetmaster.pp index b096bda8a1..86b39f2549 100644 --- a/modules/openstack_project/manifests/puppetmaster.pp +++ b/modules/openstack_project/manifests/puppetmaster.pp @@ -393,4 +393,52 @@ class openstack_project::puppetmaster ( refreshonly => true, } + # Certificate Authority for zuul services. + file { '/etc/zuul-ca': + ensure => directory, + owner => 'root', + group => 'puppet', + mode => '0640', + } + + file { '/etc/zuul-ca/openssl.cnf': + ensure => present, + owner => 'root', + group => 'puppet', + mode => '0640', + source => 'puppet:///modules/openstack_project/puppetmaster/zuul_ca.cnf', + require => File['/etc/zuul-ca'], + } + + file { '/etc/zuul-ca/certs': + ensure => directory, + owner => 'root', + group => 'puppet', + mode => '0640', + require => File['/etc/zuul-ca'], + } + + file { '/etc/zuul-ca/crl': + ensure => directory, + owner => 'root', + group => 'puppet', + mode => '0640', + require => File['/etc/zuul-ca'], + } + + file { '/etc/zuul-ca/newcerts': + ensure => directory, + owner => 'root', + group => 'puppet', + mode => '0640', + require => File['/etc/zuul-ca'], + } + + file { '/etc/zuul-ca/private': + ensure => directory, + owner => 'root', + group => 'puppet', + mode => '0640', + require => File['/etc/zuul-ca'], + } }