123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- #!/usr/bin/env bash
- # Copyright Materialize, Inc. and contributors. All rights reserved.
- #
- # Use of this software is governed by the Business Source License
- # included in the LICENSE file at the root of this repository.
- #
- # As of the Change Date specified in that file, in accordance with
- # the Business Source License, use of this software will be governed
- # by the Apache License, Version 2.0.
- # This code creates TLS certificates for the various TLS-enabled services that
- # appear throughout our mzcompose infrastructure. See test/kafka-auth for a
- # representative example.
- #
- # For each service, we generate:
- #
- # * A PEM-formatted certificate and key, signed by the "ca" CA, in the files
- # SERVICE.crt and SERVICE.key. The certificate is valid for the hostnames
- # `SERVICE` and `*.SERVICE.local`. The latter wildcard is useful when it's
- # necessary to run multiple copies of the service at different hostnames
- # using the same TLS certificate (e.g., `replica1.SERVICE.local` and
- # `replica2.SERVICE.local`). The `.local` suffix is required as TLS wildcard
- # certificates are not valid for top-level domains (e.g., `*.SERVICE`).
- # * A PKCS#12-formatted archive containing the above certificate and key in a
- # file named SERVICE.p12.
- #
- # For Java services like Kafka, we additionally generate:
- #
- # * A Java KeyStore named SERVICE.keystore.jks that contains ca.crt,
- # SERVICE.crt, and SERVICE.key.
- #
- # * A PEM-formatted certificate and key, signed by the "ca-selective" CA, in
- # the files materialized-SERVICE.crt and materialized-SERVICE.key.
- #
- # * A Java TrustStore named SERVICE.truststore.jks that contains ca.crt and
- # materialized-SERVICE.crt.
- #
- # The idea is that you configure services to use SERVICE.key as a client
- # certificate when communicating with other services, and to trust ca.crt
- # (or SERVICE.truststore.jks for Java services) when other services connect to it.
- # The certificates signed by "ca" are then useful when you want a certificate that
- # can connect to any other service.
- #
- # The certificates signed by "ca-selective" are useful when you want to provide
- # Materialize with a certificate that can talk to one service but not another. For
- # example, the materialize-kafka.key file enables communication with Kafka
- # but not the Schema Registry.
- set -euo pipefail
- export SSL_SECRET=mzmzmz
- mkdir secrets
- # Create CA
- openssl req \
- -x509 \
- -days 36500 \
- -newkey rsa:4096 \
- -keyout secrets/ca.key \
- -out secrets/ca.crt \
- -sha256 \
- -batch \
- -subj "/CN=MZ RSA CA" \
- -passin pass:$SSL_SECRET \
- -passout pass:$SSL_SECRET
- # Create an alternative CA, used for certain tests
- openssl req \
- -x509 \
- -days 36500 \
- -newkey rsa:4096 \
- -keyout secrets/ca-selective.key \
- -out secrets/ca-selective.crt \
- -sha256 \
- -batch \
- -subj "/CN=MZ RSA CA" \
- -passin pass:$SSL_SECRET \
- -passout pass:$SSL_SECRET
- # create_cert CLIENT-NAME CA-NAME COMMON-NAME
- create_cert() {
- local client_name=$1
- local ca_name=$2
- local common_name=$3
- # Create key & CSR.
- openssl req -nodes \
- -newkey rsa:2048 \
- -keyout secrets/"$client_name".key \
- -out tmp/"$client_name".csr \
- -sha256 \
- -batch \
- -subj "/CN=$common_name" \
- -addext "subjectAltName = DNS:$common_name, DNS:*.$common_name.local" \
- -passin pass:$SSL_SECRET \
- -passout pass:$SSL_SECRET \
- # Sign the CSR.
- openssl x509 -req \
- -CA secrets/"$ca_name".crt \
- -CAkey secrets/"$ca_name".key \
- -in tmp/"$client_name".csr \
- -out secrets/"$client_name".crt \
- -sha256 \
- -days 36500 \
- -CAcreateserial \
- -copy_extensions copy \
- -passin pass:$SSL_SECRET \
- # Export key and certificate as a PKCS#12 archive for import into JKSs.
- openssl pkcs12 \
- -export \
- -in secrets/"$client_name".crt \
- -name "$client_name" \
- -inkey secrets/"$client_name".key \
- -passin pass:$SSL_SECRET \
- -certfile secrets/"$ca_name".crt \
- -out tmp/"$client_name".p12 \
- -passout pass:$SSL_SECRET
- # Export key and certificate as a PKCS#12 archive with newer cipher
- # suites for use by OpenSSL v3+.
- openssl pkcs12 \
- -export \
- -keypbe AES-256-CBC \
- -certpbe AES-256-CBC \
- -in secrets/"$client_name".crt \
- -name "$client_name" \
- -inkey secrets/"$client_name".key \
- -passin pass:$SSL_SECRET \
- -certfile secrets/"$ca_name".crt \
- -out secrets/"$client_name".p12 \
- -passout pass:$SSL_SECRET
- }
- for i in materialized producer postgres certuser balancerd frontegg-mock sql-server
- do
- create_cert $i "ca" $i
- done
- for i in kafka kafka1 kafka2 schema-registry
- do
- create_cert $i "ca" $i
- create_cert "materialized-$i" "ca-selective" "materialized"
- # Create JKS
- keytool -importkeystore \
- -deststorepass $SSL_SECRET \
- -destkeypass $SSL_SECRET \
- -srcstorepass $SSL_SECRET \
- -destkeystore secrets/$i.keystore.jks \
- -srckeystore tmp/$i.p12 \
- -srcstoretype PKCS12
- # Import CA
- keytool \
- -alias CARoot \
- -import \
- -file secrets/ca.crt \
- -keystore secrets/$i.keystore.jks \
- -noprompt -storepass $SSL_SECRET -keypass $SSL_SECRET
- # Create truststore and import CA cert
- keytool \
- -keystore secrets/$i.truststore.jks \
- -alias CARoot \
- -import \
- -file secrets/ca.crt \
- -noprompt -storepass $SSL_SECRET -keypass $SSL_SECRET
- # Create truststore and import a cert using the alternative CA
- keytool \
- -keystore secrets/$i.truststore.jks \
- -alias Selective \
- -import \
- -file secrets/materialized-$i.crt \
- -noprompt -storepass $SSL_SECRET -keypass $SSL_SECRET
- done
- # Ensure files are readable for any user.
- chmod -R a+r secrets/
- # The PostgreSQL key must be only user accessible to satisfy PostgreSQL's
- # security checks.
- cp secrets/postgres.key secrets/postgres-world-readable.key
- chmod -R og-rwx secrets/postgres.key
|