Skip to content
This repository has been archived by the owner on Feb 22, 2022. It is now read-only.

Commit

Permalink
Add support for intermediate CA creation, Move to file based Cert inc…
Browse files Browse the repository at this point in the history
…ludes

* Bump chart version to 0.2.0
* Make intermediate key readonly after creation
* Separete ca/intermediate ssl configs, align notes with new upsdate, fix scripts
* intermediate CA and CA should have slightly different policies so
separate them
* Ignore yaml files in root of directory that are not values.yaml
* Update notes for new file based setup
* Fix ca/intermediate cert creation scripts
* Move to files for Cert Secrets
* Add secret-cert-password secret. Add env to values.yaml and deployment
* Update readme to match values, add intermediate domain for pulling correct files. Add docs for adding key for sec
* Ignore values that are not values.yaml in the root folder of the mtls
chart

Signed-off-by: Danny Grove <danny@drgrovellc.com>
  • Loading branch information
drGrove committed Apr 10, 2019
1 parent fa83be8 commit 05002ea
Show file tree
Hide file tree
Showing 12 changed files with 437 additions and 23 deletions.
2 changes: 2 additions & 0 deletions stable/mtls/.gitignore
@@ -1,2 +1,4 @@
output/
charts/
/*.yaml
/values.yaml
5 changes: 3 additions & 2 deletions stable/mtls/Chart.yaml
@@ -1,7 +1,6 @@
apiVersion: v1
description: A Helm chart for MTLS, a service for generating SSL Client Certificates based on Google Beyond Corp Zero Trust Framework
name: mtls
version: 0.1.0
version: 0.2.0
appVersion: 0.12.0
home: https://www.github.com/drGrove/mtls-server/
sources:
Expand All @@ -10,3 +9,5 @@ sources:
maintainers:
- name: drGrove
email: danny@drgrovellc.com
keywords:
- mtls
20 changes: 10 additions & 10 deletions stable/mtls/README.md
Expand Up @@ -25,9 +25,13 @@ $ helm repo add incuabor https://storage.googleapis.com/kubernetes-charts-incuba
# If you do not already have a CA or Intermediate Certificate run the following
# commands to generate the Root CA and Key which will be used as secrets when
installing.
$ ./scripts/setup.sh
$ ./scripts/create-ca.sh
$ helm install stable/mtls -f values.yaml
# If not using an intermediate certificate as recommended
$ echo "<Root Key Password>" > output/ca/private/key.password
# If using an intermediate certificate as recommended
$ ./scripts/create-intermediate.sh
$ echo "<Intermediate Key Password>" > output/ca/intermediate/private/key.password
$ helm install --namespace kube-system stable/mtls -f values.yaml
```

## Securing your Ingress
Expand All @@ -36,11 +40,6 @@ To add client certificate authentication to your resource you will need to add
a few annotations to your ingress. These annotations will add the appropriate
secrets and hide enable client certificate authentication.

NOTE: cert-manager will not work with services that integrate with client-cert
authentication unless you create mutliple ingresses and specifically open the
`.well-known`. It is advised that you either add the CA certificate to your
trust store or specifically add a wildcard or other certificate.

On a service that should integrate with mtls you will need to add the following
annotations to your ingress:

Expand Down Expand Up @@ -68,9 +67,10 @@ their defaults.
| `image.repository` | `mtls` image repository | `drgrove/mtls` |
| `image.tag` | `mtls` image tag. | `v0.12.0` |
| `image.pullPolicy` | Image pull policy | `IfNotPresent` |
| `secrets.ca_key` | RSA key for CA | |
| `secrets.ca_crt` | PEM format CA Certificate | |
| `configMaps['config.ini']` | Base configuration for `mtls` | [see values.yaml](values.yaml) |
| `secrets.enabled` | Enable secrets | `true` |
| `secrets.intermidateDomain` | The name of the intermediate domain | |
| `secrets.keyPassword` | The password of the certificate key | |
| `config` | Base configuration for `mtls` | [see values.yaml](values.yaml) |
| `admin_seeds` | ASCII Armored PGP Keys for Seeding Admin Trust Database | `{}` |
| `user_seeds` | ASCII Armored PGP Keys for Seeding User Trust Database | `{}` |
| `persistence.enabled` | Create a volume to store data | `true` |
Expand Down
133 changes: 133 additions & 0 deletions stable/mtls/scripts/ca.cnf
@@ -0,0 +1,133 @@
# OpenSSL root CA configuration file.

[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
# DIR should be changed to the current directory for this to work
dir = /root/ca
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
RANDFILE = $dir/private/.rand

# The root key and root certificate.
private_key = $dir/private/ca.key.pem
certificate = $dir/certs/ca.cert.pem

# For certificate revocation lists.
crlnumber = $dir/crlnumber
crl = $dir/crl/ca.crl.pem
crl_extensions = crl_ext
default_crl_days = 30

# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256

name_opt = ca_default
cert_opt = ca_default
default_days = 375
preserve = no
policy = policy_strict

[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ req ]
# Options for the `req` tool (`man req`).
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only

# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256

# Extension to add when the -x509 option is used.
x509_extensions = v3_ca

[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
commonName = Common Name
emailAddress = Email Address

# Optionally, specify some defaults.
countryName_default = US
stateOrProvinceName_default = California
localityName_default =
0.organizationName_default = MTLS CA
organizationalUnitName_default = IT
emailAddress_default = example@mtls.network

[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection

[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always

[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning

14 changes: 13 additions & 1 deletion stable/mtls/scripts/create-ca.sh
Expand Up @@ -5,6 +5,18 @@ if [[ "$PWD" == "$DIR" ]]; then
exit 1
fi

echo "Creating Root Certificate Output Folders..."
mkdir -p output/ca/certs \
output/ca/crl \
output/ca/newcerts \
output/ca/private \
output/ca/csr
chmod 700 output/ca/private
touch output/ca/index.txt
echo 1000 > output/ca/serial
cp ${DIR}/ca.cnf output/ca/openssl.cnf
sed -i "s|^dir = /root/ca|dir = ${PWD}/output/ca|g" output/ca/openssl.cnf

echo "Generating 4096 RSA Key..."
EXTRA=""
if [[ -z $NOPASSWORD ]]; then
Expand All @@ -14,7 +26,7 @@ openssl \
genrsa \
$EXTRA \
-out output/ca/private/ca.key.pem 4096
chmod 400 output/ca/private/ca.key.pem
# chmod 400 output/ca/private/ca.key.pem

if [[ -z "$SUBJ" ]]; then
if [[ -z "$C" ]]; then
Expand Down
93 changes: 93 additions & 0 deletions stable/mtls/scripts/create-intermediate.sh
@@ -0,0 +1,93 @@
#!/bin/bash
set -e
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null 2>&1 && pwd )"
if [[ "$PWD" == "$DIR" ]]; then
echo "This script should not be run from scripts. It should be run in the base of the mtls chart"
exit 1
fi

prompt_continue() {
read -p 'Create an intermediate certificate? (y/N) ' CREATE

if [[ "${CREATE}" == "y" ]]; then
query
fi
}

query() {
if [[ -z "${CN}" ]]; then
read -p 'What is the common name for this? (ie. My Intermediate CA): ' CN
fi
echo "Creating Intermediate Certificate Output Folders For ${CN}..."
NORMALIZED_CN=$(echo "${CN}" | tr -d '[:space:][:punct:]')
mkdir -p output/ca/intermediate/${NORMALIZED_CN}/certs \
output/ca/intermediate/${NORMALIZED_CN}/crl \
output/ca/intermediate/${NORMALIZED_CN}/newcerts \
output/ca/intermediate/${NORMALIZED_CN}/private \
output/ca/intermediate/${NORMALIZED_CN}/csr
chmod 700 output/ca/intermediate/${NORMALIZED_CN}/private
touch output/ca/intermediate/${NORMALIZED_CN}/index.txt
echo 1000 > output/ca/intermediate/${NORMALIZED_CN}/serial
cp ${DIR}/intermediate.cnf output/ca/intermediate/${NORMALIZED_CN}/openssl.cnf
sed -i "s|^dir = /root/ca|dir = ${PWD}/output/intermediate/${NORMALIZED_CN}|g" \
output/ca/intermediate/${NORMALIZED_CN}/openssl.cnf
gen_key $NORMALIZED_CN
if [[ -z "$SUBJ" ]]; then
if [[ -z "$C" ]]; then
read -p 'COUNTRY: ' C
fi
if [[ -z "$ST" ]]; then
read -p 'State/Province: ' ST
fi
if [[ -z "$L" ]]; then
read -p 'Locality: ' L
fi
if [[ -z "$O" ]]; then
read -p 'Organization Name: ' O
fi
if [[ -z "$OU" ]]; then
read -p 'Organizational Unit: ' OU
fi
if [[ -z "$CN" ]]; then
read -p 'Common Name: ' CN
fi
SUBJ="/CN=$CN/O=$O/OU=$OU/C=$C/ST=$ST/L=$L"
fi
echo "Generating Intermediate CA Certificate CSR for ${CN}..."
openssl req -config output/ca/intermediate/${NORMALIZED_CN}/openssl.cnf \
-new -sha256 \
-subj "$SUBJ" \
-key output/ca/intermediate/${NORMALIZED_CN}/private/${NORMALIZED_CN}.key.pem \
-out output/ca/intermediate/${NORMALIZED_CN}/csr/${NORMALIZED_CN}.csr.pem

echo "Generating Intermediate CA Certificate for ${NORMALIZED_CN}..."
openssl ca -config output/ca/openssl.cnf -extensions v3_intermediate_ca \
-days 3650 -notext -md sha256 \
-in output/ca/intermediate/${NORMALIZED_CN}/csr/${NORMALIZED_CN}.csr.pem \
-out output/ca/intermediate/${NORMALIZED_CN}/certs/${NORMALIZED_CN}.cert.pem
chmod 444 output/ca/intermediate/${NORMALIZED_CN}/certs/${NORMALIZED_CN}.cert.pem

echo "Creating ca-chain..."
cat output/ca/intermediate/${NORMALIZED_CN}/certs/${NORMALIZED_CN}.cert.pem \
output/ca/certs/ca.cert.pem > \
output/ca/intermediate/${NORMALIZED_CN}/certs/ca-chain.cert.pem

unset $NORMALIZED_CN
prompt_continue
}

gen_key() {
local NORMALIZED_CN=$1
echo "Generating 4096 RSA Key..."
EXTRA=""
if [[ -z $NOPASSWORD ]]; then
EXTRA="-aes256"
fi
openssl \
genrsa \
$EXTRA \
-out output/ca/intermediate/${NORMALIZED_CN}/private/${NORMALIZED_CN}.key.pem 4096
chmod 400 output/ca/intermediate/${CN}/private/${CN}.key.pem
}

query

0 comments on commit 05002ea

Please sign in to comment.